// @vitest-environment jsdom // // A Takeout import is watched to its end whether or not its section is still on screen, and what it // changed is read afresh then: the feed and its counts, Watch later, and the playlists' sizes. import { afterEach, describe, expect, it, vi } from "vitest"; import { QueryClient } from "@tanstack/react-query"; import { api, type TakeoutStatus } from "../../lib/api"; import { qk } from "../../lib/queryKeys"; import { importBusy, watchTakeout } from "./takeoutWatch"; afterEach(() => { vi.restoreAllMocks(); vi.useRealTimers(); }); const st = (s: Partial): TakeoutStatus => ({ queued: false, max_bytes: 1, run: null, ...s, }); const running = { status: "running", started_at: "S", finished_at: null, result: null, failure: null, }; describe("the Takeout import's watch", () => { it("a queued import is busy as much as a running one", () => { expect(importBusy(st({ queued: true }))).toBe(true); expect(importBusy(st({ run: { ...running, status: "running" } as TakeoutStatus["run"] }))).toBe( true, ); expect(importBusy(st({ run: { ...running, status: "ok" } as TakeoutStatus["run"] }))).toBe( false, ); expect(importBusy(undefined)).toBe(false); }); it("asks until the import is done, then reads again everything it changed", async () => { vi.useFakeTimers(); const qc = new QueryClient(); qc.setQueryData(qk.takeout(), st({ queued: true })); const answers = [st({ run: running as TakeoutStatus["run"] }), st({})]; const read = vi.spyOn(api, "takeoutStatus").mockImplementation(async () => answers.shift()!); const stale = vi.spyOn(qc, "invalidateQueries"); const done = watchTakeout(qc); void watchTakeout(qc); // a second call while it watches is the same watch await vi.advanceTimersByTimeAsync(1500); expect(read).toHaveBeenCalledTimes(1); expect(stale).not.toHaveBeenCalled(); await vi.advanceTimersByTimeAsync(1500); await done; expect(read).toHaveBeenCalledTimes(2); expect(stale.mock.calls.map(([f]) => f?.queryKey)).toEqual([ qk.feed(), qk.feedSummary(), qk.feedYears(), qk.playlist(), qk.playlists(), ]); }); });