// app/__tests__/metadata.test.ts import { describe, it, expect, vi, beforeEach } from "vitest" // Mock modules that page renders depend on vi.mock("@/lib/db/index", () => ({ db: { select: vi.fn(() => ({ from: vi.fn(() => ({ where: vi.fn(() => ({ orderBy: vi.fn(() => ({ limit: vi.fn(() => []), })), })), innerJoin: vi.fn(() => ({ where: vi.fn(() => ({ groupBy: vi.fn(() => ({ orderBy: vi.fn(() => []), })), })), })), })), })), }, })) vi.mock("@/lib/db/schema", () => ({ games: { id: "id", title: "title", slug: "slug", updatedAt: "updatedAt", capsuleImage: "capsuleImage", syncStatus: "syncStatus" }, gameVersions: { id: "id", gameId: "gameId", versionString: "versionString", buildId: "buildId" }, performanceEntries: { id: "id", versionId: "versionId", isRemoved: "isRemoved", hardwareSlug: "hardwareSlug", fpsAvg: "fpsAvg", fpsLow: "fpsLow", fpsHigh: "fpsHigh" }, hardware: { slug: "slug", name: "name", deviceType: "deviceType", sortOrder: "sortOrder" }, gameComments: { gameId: "gameId", id: "id" }, gamePlatformSupport: { gameId: "gameId", hardwareSlug: "hardwareSlug", protonStatus: "protonStatus" }, user: { id: "id", name: "name", image: "image", role: "role" }, entryScreenshots: { id: "id", entryId: "entryId", storageKey: "storageKey", orderIndex: "orderIndex" }, steamReviewSentimentEnum: { enumValues: [ "overwhelmingly_positive", "very_positive", "positive", "mostly_positive", "mixed", "mostly_negative", "negative", "very_negative", "overwhelmingly_negative", ], }, })) vi.mock("drizzle-orm", () => ({ eq: vi.fn((col: unknown, val: unknown) => ({ col, val })), and: vi.fn((...args: unknown[]) => args), desc: vi.fn((col: unknown) => col), or: vi.fn((...args: unknown[]) => args), ne: vi.fn((col: unknown) => col), isNull: vi.fn((col: unknown) => col), inArray: vi.fn((col: unknown, vals: unknown) => ({ col, vals })), sql: vi.fn((strings: TemplateStringsArray, ...values: unknown[]) => ({ raw: strings, vals: values })), avg: vi.fn((col: unknown) => col), count: vi.fn((col: unknown) => col), })) vi.mock("@/lib/storage", () => ({ getR2PublicUrl: vi.fn(() => "https://r2.example.com"), })) vi.mock("@/lib/auth", () => ({ auth: { $Infer: { Session: { user: {} } }, api: {}, handler: vi.fn(), }, })) vi.mock("@/lib/auth-client", () => ({})) vi.mock("@/lib/updates", () => ({ getAllUpdates: vi.fn(() => []), getAllUpdateSlugs: vi.fn(() => []), getUpdateBySlug: vi.fn(() => Promise.resolve({ meta: { title: "", date: "", version: "", summary: "" }, html: "", headings: [] })), })) vi.mock("next/font/google", () => ({ Lexend: vi.fn(() => ({ variable: "font-mock" })), })) vi.mock("@/components/navbar", () => ({ default: vi.fn(() => null), })) describe("Page Metadata", () => { describe("Root Layout", () => { it("exports canonical URL", async () => { const { metadata } = await import("@/app/layout") expect(metadata.alternates?.canonical).toBe("https://deckyvault.xyz") }) }) describe("Games page", () => { it("has a unique title without duplicate brand name", async () => { const { metadata } = await import("@/app/games/page") expect(metadata.title).toBe("Games") }) }) describe("Devices page", () => { it("has a unique title without duplicate brand name", async () => { const { metadata } = await import("@/app/devices/page") expect(metadata.title).toBe("Devices") }) }) describe("Compare layout", () => { it("exports unique title and description", async () => { const { metadata } = await import("@/app/compare/layout") expect(metadata.title).toBe("Compare Games") expect(metadata.description).toBeDefined() }) }) describe("Profile layout", () => { it("exports unique title and description", async () => { const { metadata } = await import("@/app/profile/layout") expect(metadata.title).toBe("Profile") expect(metadata.description).toBeDefined() }) }) describe("End-to-end metadata consolidation", () => { it("all public pages have unique titles", async () => { const pages = [ { name: "layout", expected: "DeckyVault - Steam Deck Benchmarks & Settings" }, { name: "games/page", expected: "Games" }, { name: "devices/page", expected: "Devices" }, { name: "compare/layout", expected: "Compare Games" }, ] const titles = new Set() for (const page of pages) { const mod = await import(`@/app/${page.name}`) const actualTitle = mod.metadata.title?.default ?? mod.metadata.title expect(actualTitle).toBe(page.expected) const resolvedTitle = page.name === "layout" ? actualTitle : `${actualTitle} | DeckyVault` titles.add(resolvedTitle) } expect(titles.has("DeckyVault - Steam Deck Benchmarks & Settings")).toBe(true) expect(titles.size).toBe(pages.length) }) }) })