import { basename, join, resolve } from "node:path"; import { beforeAll, describe, expect, it } from "vitest"; import { checkNote, checkVault } from "@gk/schema"; import { build, loadProducts, type BuildResult } from "../src/build.ts"; const legacy = resolve(import.meta.dirname, "../../../legacy"); let result: BuildResult; beforeAll(async () => { await loadProducts(legacy); result = build(legacy); }); const find = (type: string, title: string) => result.notes.find((n) => n.data.type === type && n.data.title === title); describe("migration", () => { it("produces only valid notes and a consistent vault", () => { const vault = result.notes.map((n) => { const r = checkNote(n.text); expect(r.ok, n.path).toBe(true); return { path: n.path, type: String(n.data.type), data: n.data, body: n.body }; }); expect(checkVault(vault, result.attachments.map((a) => basename(a.to)))).toEqual([]); }); it("carries every legacy list item over", () => { const count = (t: string) => result.notes.filter((n) => n.data.type === t).length; expect(count("board-game")).toBe(50); // 24 reading + 108 anime + 103 TV + 152 movies + 11 hall of fame + 5 now playing expect(count("library-item")).toBe(403); expect(count("experience")).toBe(3); }); it("merges a favorite listed twice into one note", () => { const demonSlayer = result.notes.filter((n) => n.data.title === "Demon Slayer"); expect(demonSlayer).toHaveLength(1); expect(demonSlayer[0]!.data).toMatchObject({ favorite: true, group: "Major Modern Hits", state: "finished" }); }); it("splits author from series", () => { expect(find("library-item", "Cosmere")?.data).toMatchObject({ creator: "Brandon Sanderson", medium: "book" }); }); it("keeps the store's real prices, with no slot open until Greg opens orders", () => { const proxies = find("product-line", "Proxy MTG Cards")!.data as any; expect(proxies.slots).toEqual({ open: 0, total: 3 }); expect(proxies.priceTiers).toContainEqual({ band: "100 card deck", price: "$40.00", note: "per set of cards" }); }); it("takes the resume from Greg's interview answers", () => { const implico = find("experience", "Team Lead, BTP Cloud & Mobile Apps and US Managed Services at Implico Inc.")!.data as any; expect(implico.bullets.join(" ")).toContain("500+ active users across 50+ companies"); expect(result.notes.filter((n) => n.data.type === "experience" && (n.data as any).earlier)).toHaveLength(2); expect(find("page", "Resume")?.data).toMatchObject({ page: "/resume", stats: expect.any(Array), projects: expect.any(Array) }); }); it("logs status for everything in progress", () => { const kinds = result.notes.filter((n) => n.data.type === "status").map((n) => `${n.data.kind}: ${n.data.title}`); expect(kinds).toContain("Playing: Slay the Spire 2"); expect(kinds).toContain("Watching: House of the Dragon"); expect(kinds).toContain("Listening: The Lord of the Rings"); }); it("never publishes anything still waiting on Greg", () => { for (const title of ["D&D campaign", "Daggerheart campaign", "Carrier Connect", "Book-bound journals"]) { expect(result.notes.find((n) => n.data.title === title)?.data.publish, title).toBe(false); } }); });