import { beforeEach, describe, expect, it, vi } from "vitest"; const mocks = vi.hoisted(() => ({ reads: [] as unknown[], rows: new Map() })); vi.mock("server-only", () => ({})); vi.mock("@/lib/media/storage", () => ({ publicMediaUrl: (key: string) => `/media/${key}` })); vi.mock("@/db", () => ({ getDb: () => ({ select: () => { let table: unknown; const query = { from(value: unknown) { table = value; return query; }, innerJoin() { return query; }, leftJoin() { return query; }, where() { return query; }, orderBy() { return query; }, limit() { return query; }, then(resolve: (rows: unknown[]) => unknown) { mocks.reads.push(table); return Promise.resolve(mocks.rows.get(table) ?? []).then(resolve); }, }; return query; }, }), })); import { artifactConditions, artifactProfiles, constellationConditions, extraSectionRows, guides, guideSections, teamCompositions, teamConditions, teamMembers, weaponConditions, catalogMaterials, guidePosterBleeding, media, } from "@/db/schema"; import { getAdminGuideContent, listAdminTeamImportsForCharacter } from "./queries"; beforeEach(() => { mocks.reads.length = 0; mocks.rows.clear(); mocks.rows.set(guides, [{ guide: { id: "guide", slug: "test", posterArtMediaId: null }, cover: { objectKey: "cover", status: "ready" }, character: { key: "test", imageKey: "character", constellations: [], talents: [], ascension: [], leveling: [] }, }]); mocks.rows.set(guideSections, [ { id: "extra-a", slug: "extra-a", kind: "extra" }, { id: "extra-b", slug: "extra-b", kind: "extra" }, ]); }); describe("admin section reads", () => { it.each([ ["weapon", weaponConditions], ["artifact", artifactConditions], ["constellations", constellationConditions], ["team", teamConditions], ])("loads only the %s section's conditions", async (section, expectedTable) => { const result = await getAdminGuideContent("test", section); expect(result).not.toBeNull(); expect(mocks.reads).toContain(expectedTable); for (const table of [weaponConditions, artifactConditions, constellationConditions, teamConditions]) { if (table !== expectedTable) expect(mocks.reads).not.toContain(table); } expect(mocks.reads).not.toContain(extraSectionRows); expect(mocks.reads).not.toContain(catalogMaterials); expect(mocks.reads).not.toContain(guidePosterBleeding); }); it("loads just the selected extra section", async () => { const result = await getAdminGuideContent("test", "extra-b"); expect(result?.extras.map((extra) => extra.id)).toEqual(["extra-b"]); expect(mocks.reads).toContain(extraSectionRows); expect(mocks.reads).not.toContain(weaponConditions); expect(mocks.reads).not.toContain(teamConditions); }); it("preserves full-guide reads for existing preview and validation callers", async () => { const result = await getAdminGuideContent("test"); for (const table of [weaponConditions, artifactConditions, constellationConditions, teamConditions, extraSectionRows]) { expect(mocks.reads).toContain(table); } expect(result?.extras).toHaveLength(2); }); it("resolves condition icons from one batched media read", async () => { const iconMediaId = "550e8400-e29b-41d4-a716-446655440000"; mocks.rows.set(weaponConditions, [{ id: "weapon-condition", iconMediaId }]); mocks.rows.set(artifactConditions, [{ id: "artifact-condition", iconMediaId }]); mocks.rows.set(constellationConditions, [{ id: "constellation-condition", iconMediaId }]); mocks.rows.set(teamConditions, [{ id: "team-condition", iconMediaId }]); mocks.rows.set(artifactProfiles, [{ sands: [], goblet: [], circlet: [], substats: [], targets: [], recommendedConditions: [{ name: "Recommended", note: null, iconMediaId, sands: [], goblet: [], circlet: [], substats: [] }], targetConditions: [{ name: "Target", note: null, iconMediaId, rows: [] }], }]); mocks.rows.set(media, [{ id: iconMediaId, objectKey: "condition-icon.png" }]); const result = await getAdminGuideContent("test"); expect(result?.weaponGroups[0].iconUrl).toBe("/media/condition-icon.png"); expect(result?.artifactGroups[0].iconUrl).toBe("/media/condition-icon.png"); expect(result?.constellationGroups[0].iconUrl).toBe("/media/condition-icon.png"); expect(result?.teamGroups[0].iconUrl).toBe("/media/condition-icon.png"); expect(result?.artifactProfile?.recommendedConditions[0].iconUrl).toBe("/media/condition-icon.png"); expect(result?.artifactProfile?.targetConditions[0].iconUrl).toBe("/media/condition-icon.png"); expect(mocks.reads.filter((table) => table === media)).toHaveLength(1); }); }); describe("team import lookup", () => { it("hydrates matching teams and source labels with one member read", async () => { mocks.rows.set(teamCompositions, [{ id: "team-1", title: "Example", rotationSeconds: "20", combo: "E > Q", guideName: "Other Guide", conditionName: "Boss", }]); mocks.rows.set(teamMembers, [{ member: { teamId: "team-1", characterKey: "character-1", weaponKey: "weapon-1", artifactKey: "artifact-1", secondArtifactKey: null, constellation: "2", refinement: "1", damage: "100", }, characterName: "Character One", }]); const result = await listAdminTeamImportsForCharacter("current-guide", "character-1"); expect(result).toEqual([{ id: "team-1", title: "Example", rotationSeconds: "20", combo: "E > Q", guideName: "Other Guide", conditionName: "Boss", members: [{ characterKey: "character-1", characterName: "Character One", weaponKey: "weapon-1", artifactKey: "artifact-1", secondArtifactKey: null, constellation: "2", refinement: "1", damage: "100", }], }]); expect(mocks.reads).toEqual([teamCompositions, teamMembers]); }); });