import { beforeEach, describe, expect, it, vi } from "vitest"; const mocks = vi.hoisted(() => ({ tag: vi.fn(), guide: vi.fn(), summary: vi.fn() })); vi.mock("server-only", () => ({})); vi.mock("next/cache", () => ({ cacheTag: mocks.tag, cacheLife: vi.fn() })); vi.mock("@/lib/guides/queries", () => ({ getPublicGuide: mocks.guide, getPublicGuideSummary: mocks.summary, listPublicGuideCards: vi.fn(), })); import { getCachedPublicGuide, getCachedPublicGuideSummary } from "./public"; beforeEach(() => vi.resetAllMocks()); describe("public cache dependency boundaries", () => { it.each([getCachedPublicGuide, getCachedPublicGuideSummary])("keeps existing guides independent of directory invalidations", async (read) => { mocks.guide.mockResolvedValue({ id: "first" }); mocks.summary.mockResolvedValue({ id: "first" }); await read("first"); expect(mocks.tag).toHaveBeenCalledWith("buzz:page:first"); expect(mocks.tag).toHaveBeenCalledWith("buzz:catalog"); expect(mocks.tag).not.toHaveBeenCalledWith("buzz:directory"); }); it.each([getCachedPublicGuide, getCachedPublicGuideSummary])("refreshes missing guides when the directory changes", async (read) => { mocks.guide.mockResolvedValue(null); mocks.summary.mockResolvedValue(null); expect(await read("missing")).toBeNull(); expect(mocks.tag).toHaveBeenCalledWith("buzz:directory"); }); });