import { readdirSync, readFileSync } from "node:fs"; import { QueryClient } from "@tanstack/react-query"; import { describe, expect, it, vi } from "vitest"; import { qk } from "./queryKeys"; import { invalidateSubscription } from "./subscriptionCache"; // A subscription change touches the same reads wherever it is made, and each site kept // its own list — the channel menu's unsubscribe left the feed showing the channel's videos, the // channel page's left the status counts stale. One set, one function, every site on it. describe("a subscription change", () => { it("refreshes the channel, the lists, the counts and the feed", () => { const qc = new QueryClient(); const spy = vi.spyOn(qc, "invalidateQueries"); invalidateSubscription(qc, "UC1"); expect(spy.mock.calls.map(([f]) => f?.queryKey)).toEqual([ qk.channel("UC1"), qk.channels(), qk.myStatus(), qk.feed(), qk.feedSummary(), qk.discoveredChannels(), qk.watchedChannels(), ]); }); it("is refreshed through that one function wherever it is made", () => { const root = new URL("../", import.meta.url); const sites = readdirSync(root, { recursive: true, encoding: "utf8" }) .map((f) => f.split("\\").join("/")) .filter((f) => f.endsWith(".tsx") && !f.includes(".test.") && !f.startsWith("design-lab/")) .map((f) => [f, readFileSync(new URL(f, root), "utf8")] as const) .filter(([, src]) => /api\.(un)?subscribeChannel\(/.test(src)); expect(sites.length).toBeGreaterThanOrEqual(3); for (const [f, src] of sites) { const calls = src.match(/api\.(un)?subscribeChannel\(/g)!.length; expect(src.match(/invalidateSubscription\(/g)?.length ?? 0, f).toBe(calls); } }); });