feat: refine widget interactions
This commit is contained in:
1 parent
a8a7545f40
commit
842e86012d
107 files changed
+3144
-1233
No files matched your search
@@ -14,7 +14,8 @@ vi.mock("@homarr/core/infrastructure/http", () => ({
|
||||
const mockFetch = vi.mocked(fetchWithTrustedCertificatesAsync);
|
||||
const mockCreateCertificateAgent = vi.mocked(createCertificateAgentAsync);
|
||||
const mockCloseDispatcher = vi.fn();
|
||||
const mockDispatcher = { close: mockCloseDispatcher };
|
||||
const mockDestroyDispatcher = vi.fn().mockResolvedValue(undefined);
|
||||
const mockDispatcher = { close: mockCloseDispatcher, destroy: mockDestroyDispatcher };
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
@@ -156,6 +157,41 @@ describe("timetable response bounds", () => {
|
||||
expect(mockCloseDispatcher).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("destroys the pinned station dispatcher when response handling fails", async () => {
|
||||
mockFetch.mockResolvedValue(new Response("not json"));
|
||||
|
||||
await expect(
|
||||
timetableSearchStationsRequestHandler
|
||||
.handler({
|
||||
baseUrl: "https://timetable.example.com",
|
||||
query: "invalid-stations",
|
||||
pinnedAddresses: [{ address: "93.184.216.34", family: 4 }],
|
||||
})
|
||||
.getDataAsync(),
|
||||
).rejects.toThrow();
|
||||
|
||||
expect(mockDestroyDispatcher).toHaveBeenCalledOnce();
|
||||
expect(mockCloseDispatcher).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("destroys the pinned timetable dispatcher when response handling fails", async () => {
|
||||
mockFetch.mockResolvedValue(new Response("not json"));
|
||||
|
||||
await expect(
|
||||
timetableGetTimetableRequestHandler
|
||||
.handler({
|
||||
baseUrl: "https://timetable.example.com",
|
||||
stationId: "invalid-departures",
|
||||
limit: 1,
|
||||
pinnedAddresses: [{ address: "93.184.216.34", family: 4 }],
|
||||
})
|
||||
.getDataAsync(),
|
||||
).rejects.toThrow();
|
||||
|
||||
expect(mockDestroyDispatcher).toHaveBeenCalledOnce();
|
||||
expect(mockCloseDispatcher).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("never caches more departures than requested", async () => {
|
||||
mockFetch.mockResolvedValue(
|
||||
new Response(
|
||||
|
||||
@@ -124,9 +124,10 @@ const searchStationsAsync = async (
|
||||
query: string,
|
||||
pinnedAddresses?: TimetableResolvedAddress[],
|
||||
): Promise<Station[]> => {
|
||||
const dispatcher = pinnedAddresses ? await createPinnedTimetableDispatcherAsync(baseUrl, pinnedAddresses) : undefined;
|
||||
let dispatcher = pinnedAddresses ? await createPinnedTimetableDispatcherAsync(baseUrl, pinnedAddresses) : undefined;
|
||||
let response: Awaited<ReturnType<typeof fetchWithTrustedCertificatesAsync>> | undefined;
|
||||
try {
|
||||
const response = await fetchWithTrustedCertificatesAsync(
|
||||
response = await fetchWithTrustedCertificatesAsync(
|
||||
buildUrl(baseUrl, "/timetable/api/completion.json", { term: query, show_ids: 1, nofavorites: 1 }),
|
||||
{ ...timetableFetchOptions, dispatcher },
|
||||
);
|
||||
@@ -138,6 +139,11 @@ const searchStationsAsync = async (
|
||||
.filter((item) => supportedStationTypes.some((type) => item.iconclass.endsWith(type)))
|
||||
.map((item) => (item.id !== undefined ? { id: item.id, name: item.label } : null))
|
||||
.filter((item) => item !== null);
|
||||
} catch (error) {
|
||||
if (response?.body) await response.body.cancel().catch(() => {});
|
||||
await dispatcher?.destroy().catch(() => {});
|
||||
dispatcher = undefined;
|
||||
throw error;
|
||||
} finally {
|
||||
await dispatcher?.close();
|
||||
}
|
||||
@@ -161,9 +167,10 @@ const getTimetableAsync = async (
|
||||
minute: "2-digit",
|
||||
hour12: false,
|
||||
}).format(now);
|
||||
const dispatcher = pinnedAddresses ? await createPinnedTimetableDispatcherAsync(baseUrl, pinnedAddresses) : undefined;
|
||||
let dispatcher = pinnedAddresses ? await createPinnedTimetableDispatcherAsync(baseUrl, pinnedAddresses) : undefined;
|
||||
let response: Awaited<ReturnType<typeof fetchWithTrustedCertificatesAsync>> | undefined;
|
||||
try {
|
||||
const response = await fetchWithTrustedCertificatesAsync(
|
||||
response = await fetchWithTrustedCertificatesAsync(
|
||||
buildUrl(baseUrl, "/timetable/api/stationboard.json", {
|
||||
stop: options.stationId,
|
||||
limit: options.limit,
|
||||
@@ -205,6 +212,11 @@ const getTimetableAsync = async (
|
||||
};
|
||||
}),
|
||||
};
|
||||
} catch (error) {
|
||||
if (response?.body) await response.body.cancel().catch(() => {});
|
||||
await dispatcher?.destroy().catch(() => {});
|
||||
dispatcher = undefined;
|
||||
throw error;
|
||||
} finally {
|
||||
await dispatcher?.close();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user