import type { PdfPreflightResult } from "@reactive-resume/pdf/server"; import type { CompileStylesheetResult } from "@reactive-resume/resume/stylesheet"; import type { ResumeData } from "@reactive-resume/schema/resume/data"; import type { SemanticStylesheet, StylesheetSource } from "@reactive-resume/schema/resume/stylesheet"; import type { SemanticCssEventInput } from "./stylesheet-observability"; import type { StylesheetSnapshot } from "./stylesheet-service"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { defaultResumeData } from "@reactive-resume/schema/resume/default"; import { createStylesheetService } from "./stylesheet-service"; vi.mock("@reactive-resume/db/client", () => ({ db: {}, getPool: vi.fn() })); const validSource = { languageVersion: 1, text: "@version 1;\nsection { color: #112233; }\n", } satisfies StylesheetSource; const invalidSource = { languageVersion: 1, text: "@version 1;\nsection {", } satisfies StylesheetSource; const previousSource = { languageVersion: 1, text: "@version 1;\nsection { color: #445566; }\n", } satisfies StylesheetSource; const previousApplied = { languageVersion: 1, text: "@version 1;\nsection { color: #778899; }\n", } satisfies StylesheetSource; const previousStylesheet = { mode: "semantic", source: previousSource, applied: previousApplied, } satisfies SemanticStylesheet; const diagnostic = { code: "PARSE_ERROR", severity: "error" as const, message: "Invalid stylesheet.", range: { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 }, }, }; const successfulCompile = { program: { languageVersion: 1, rules: [] }, diagnostics: [], } satisfies CompileStylesheetResult; const failedCompile = { program: null, diagnostics: [diagnostic] } satisfies CompileStylesheetResult; const successfulPreflight = { ok: true, pageCount: 1, byteCount: 256, diagnostics: [], } satisfies PdfPreflightResult; const commonMutationInput = { id: "resume-1", userId: "user-1", expectedRevision: 3, expectedRenderDataVersion: 8, editGeneration: 11, } as const; const snapshot = (stylesheet: SemanticStylesheet = previousStylesheet): StylesheetSnapshot => { const data: ResumeData = structuredClone(defaultResumeData); data.metadata.stylesheet = stylesheet; data.metadata.styleRules = [ { id: "legacy-rule", label: "Legacy", enabled: true, target: { scope: "global" }, slots: { heading: { color: "#123456" } }, }, ]; return { id: "resume-1", userId: "user-1", data, isLocked: false, stylesheetRevision: 3, renderDataVersion: 8, updatedAt: new Date("2026-07-28T12:00:00.000Z"), }; }; type HarnessOptions = { initial?: StylesheetSnapshot; compile?: (source: StylesheetSource) => CompileStylesheetResult; preflight?: ((input: { data: ResumeData; stylesheet: StylesheetSource }) => Promise) | undefined; locked?: StylesheetSnapshot; useDefaultObserver?: boolean; }; const createHarness = (options: HarnessOptions = {}) => { const callOrder: string[] = []; const events: SemanticCssEventInput[] = []; let persisted = structuredClone(options.initial ?? snapshot()); const compile = vi.fn((source: StylesheetSource) => { callOrder.push("compile"); return options.compile?.(source) ?? successfulCompile; }); const preflight = options.preflight ? vi.fn(options.preflight) : vi.fn(() => { callOrder.push("preflight"); return Promise.resolve(successfulPreflight); }); const publish = vi.fn(() => { callOrder.push("publish"); return Promise.resolve(); }); const service = createStylesheetService({ readSnapshot: () => { callOrder.push("readSnapshot"); return Promise.resolve(structuredClone(persisted)); }, convertLegacy: () => { callOrder.push("convertLegacy"); return { languageVersion: 1, text: "@version 1;\n" }; }, compile, preflight: options.preflight === undefined ? preflight : (input) => { callOrder.push("preflight"); return preflight(input); }, transaction: async (run) => { callOrder.push("begin"); try { const result = await run({ lock: () => { callOrder.push("lock"); return Promise.resolve(structuredClone(options.locked ?? persisted)); }, update: ({ data }) => { callOrder.push("update"); persisted = { ...persisted, data, stylesheetRevision: persisted.stylesheetRevision + 1, }; return Promise.resolve(structuredClone(persisted)); }, }); callOrder.push("commit"); return result; } catch (error) { callOrder.push("rollback"); throw error; } }, compare: (locked, input) => { callOrder.push("compare"); return ( locked.stylesheetRevision === input.expectedRevision && locked.renderDataVersion === input.expectedRenderDataVersion ); }, publish, ...(options.useDefaultObserver ? {} : { observe: (event: SemanticCssEventInput) => events.push(event) }), }); return { callOrder, compile, events, persisted: () => persisted, preflight, publish, service }; }; describe("stylesheet service", () => { beforeEach(() => { vi.restoreAllMocks(); }); it("stores invalid editable source while preserving the last-valid applied source and render version", async () => { const harness = createHarness({ compile: () => failedCompile }); const result = await harness.service.mutate({ ...commonMutationInput, transition: "edit_source", source: invalidSource, }); expect(result.stylesheet.source).toEqual(invalidSource); expect(result.stylesheet.applied).toEqual(previousApplied); expect(result.revision).toBe(4); expect(result.renderDataVersion).toBe(8); expect(result.editGeneration).toBe(11); expect(result.diagnostics).toEqual([diagnostic]); expect(harness.preflight).not.toHaveBeenCalled(); }); it("promotes a valid edit only in semantic mode after preflight outside the short transaction", async () => { const harness = createHarness(); const result = await harness.service.mutate({ ...commonMutationInput, transition: "edit_source", source: validSource, }); expect(result.stylesheet.source).toEqual(validSource); expect(result.stylesheet.applied).toEqual(validSource); expect(harness.callOrder).toEqual([ "readSnapshot", "compile", "preflight", "begin", "lock", "compare", "update", "commit", "publish", ]); }); it("keeps a valid legacy-mode edit dormant without preflight", async () => { const initial = snapshot({ ...previousStylesheet, mode: "legacy" }); const harness = createHarness({ initial }); const result = await harness.service.mutate({ ...commonMutationInput, transition: "edit_source", source: validSource, }); expect(result.stylesheet).toEqual({ mode: "legacy", source: validSource, applied: previousApplied, }); expect(harness.preflight).not.toHaveBeenCalled(); }); it("preserves editable source but not applied source when semantic render preflight fails", async () => { const harness = createHarness({ preflight: async () => ({ ok: false, code: "STYLESHEET_PREFLIGHT_RENDER_FAILED", message: "PDF rendering failed.", diagnostics: [], }), }); const result = await harness.service.mutate({ ...commonMutationInput, transition: "edit_source", source: validSource, }); expect(result.stylesheet.source).toEqual(validSource); expect(result.stylesheet.applied).toEqual(previousApplied); expect(result.diagnostics).toEqual([ expect.objectContaining({ code: "STYLESHEET_PREFLIGHT_RENDER_FAILED", severity: "error" }), ]); }); it("activates an explicitly requested mode transition without checking legacy parity", async () => { const initial = snapshot({ ...previousStylesheet, mode: "legacy" }); const harness = createHarness({ initial }); const result = await harness.service.mutate({ ...commonMutationInput, transition: "activate", source: validSource, }); expect(result.stylesheet).toEqual({ mode: "semantic", source: validSource, applied: validSource }); expect(harness.preflight).toHaveBeenCalledOnce(); expect(result.revision).toBe(4); expect(result.renderDataVersion).toBe(8); expect(harness.events).toContainEqual( expect.objectContaining({ name: "semantic_css.activate", durationMs: expect.any(Number), pageCount: 1, revision: 4, success: true, }), ); }); it("records a sanitized compile failure metric when the compiler throws", async () => { const privateText = "private compiler failure john.doe@example.com"; const log = vi.spyOn(console, "info").mockImplementation(() => undefined); const harness = createHarness({ compile: () => { throw new Error(privateText); }, useDefaultObserver: true, }); await expect( harness.service.mutate({ ...commonMutationInput, transition: "edit_source", source: validSource }), ).rejects.toThrow(privateText); expect(log.mock.calls.map(([event]) => event)).toContainEqual( expect.objectContaining({ name: "semantic_css.compile", durationMs: expect.any(Number), diagnosticCodes: [], success: false, }), ); const serialized = JSON.stringify(log.mock.calls); expect(serialized).not.toContain(privateText); expect(serialized).not.toContain(validSource.text); expect(serialized).not.toContain("resume-1"); }); it("records a sanitized preflight failure metric when the runner throws", async () => { const privateText = "private preflight failure john.doe@example.com"; const log = vi.spyOn(console, "info").mockImplementation(() => undefined); const harness = createHarness({ preflight: () => Promise.reject(new Error(privateText)), useDefaultObserver: true, }); await expect( harness.service.mutate({ ...commonMutationInput, transition: "edit_source", source: validSource }), ).rejects.toThrow(privateText); expect(log.mock.calls.map(([event]) => event)).toContainEqual( expect.objectContaining({ name: "semantic_css.preflight", durationMs: expect.any(Number), diagnosticCodes: [], success: false, }), ); const serialized = JSON.stringify(log.mock.calls); expect(serialized).not.toContain(privateText); expect(serialized).not.toContain(validSource.text); expect(serialized).not.toContain("resume-1"); }); it("deactivates without compiling or deleting either source", async () => { const harness = createHarness(); const result = await harness.service.mutate({ ...commonMutationInput, transition: "deactivate" }); expect(result.stylesheet).toEqual({ ...previousStylesheet, mode: "legacy" }); expect(harness.compile).not.toHaveBeenCalled(); expect(harness.preflight).not.toHaveBeenCalled(); }); it("does not rewrite invalid stored resume data during deactivation", async () => { const initial = snapshot(); initial.data.customSections = [ { id: "custom-experience", type: "experience", title: "Experience", icon: "", columns: 1, hidden: false, keepTogether: false, startOnNewPage: false, items: [{ id: "summary-item", hidden: false, content: "

Missing company

" }], } as never, ]; const harness = createHarness({ initial }); const error = await harness.service .mutate({ ...commonMutationInput, transition: "deactivate" }) .catch((caught: unknown) => caught); expect(error).toMatchObject({ code: "INTERNAL_SERVER_ERROR", status: 500 }); expect(error).toHaveProperty("cause.issues.0.path", ["customSections", 0, "items", 0, "company"]); expect(harness.callOrder).not.toContain("update"); expect(harness.publish).not.toHaveBeenCalled(); }); it("normalizes valid stored resume data during deactivation", async () => { const initial = snapshot(); initial.data.customSections = [ { id: "custom-experience", type: "experience", title: "Experience", icon: "", columns: 1, hidden: false, keepTogether: false, startOnNewPage: false, items: [ { id: "experience-item", hidden: false, company: "Analytical Engines", position: "Programmer", location: "London", period: "1842–1843", description: "

Wrote the first algorithm.

", content: "

Compatible overlap

", }, ], } as never, ]; const harness = createHarness({ initial }); await harness.service.mutate({ ...commonMutationInput, transition: "deactivate" }); expect(harness.persisted().data.customSections[0]?.items[0]).toMatchObject({ content: "

Compatible overlap

", roles: [], website: { url: "", label: "", inlineLink: false }, }); }); it("validates and preflights restored applied source independently from invalid editable source", async () => { const restoredApplied = { ...validSource, text: "@version 1;\nresume { color: #abcdef; }\n" }; const compile = vi.fn((source: StylesheetSource) => source === restoredApplied ? successfulCompile : failedCompile, ); const harness = createHarness({ compile }); const result = await harness.service.mutate({ ...commonMutationInput, transition: "restore_history", restore: { mode: "semantic", source: invalidSource, applied: restoredApplied, }, }); expect(compile).toHaveBeenCalledTimes(1); expect(compile).toHaveBeenCalledWith(restoredApplied); expect(harness.preflight).toHaveBeenCalledWith({ data: expect.any(Object), stylesheet: restoredApplied, }); expect(result.stylesheet).toEqual({ mode: "semantic", source: invalidSource, applied: restoredApplied, }); }); it("rejects locked resumes before compiler or preflight work", async () => { const initial = { ...snapshot(), isLocked: true }; const harness = createHarness({ initial }); await expect( harness.service.mutate({ ...commonMutationInput, transition: "edit_source", source: validSource }), ).rejects.toMatchObject({ code: "RESUME_LOCKED" }); expect(harness.compile).not.toHaveBeenCalled(); expect(harness.preflight).not.toHaveBeenCalled(); }); it("returns the locked canonical snapshot on a two-version conflict without writing", async () => { const locked = { ...snapshot(), stylesheetRevision: 4, renderDataVersion: 9, }; delete locked.data.metadata.stylesheet; const harness = createHarness({ locked }); const error = await harness.service .mutate({ ...commonMutationInput, transition: "edit_source", source: validSource }) .catch((caught: unknown) => caught); expect(error).toMatchObject({ code: "STYLESHEET_REVISION_CONFLICT", data: { state: expect.objectContaining({ revision: 4, renderDataVersion: 9, stylesheet: expect.objectContaining({ mode: "legacy", source: { languageVersion: 1, text: "@version 1;\n" }, }), }), }, }); expect(harness.callOrder).not.toContain("update"); expect(harness.publish).not.toHaveBeenCalled(); expect(harness.callOrder.indexOf("rollback")).toBeLessThan(harness.callOrder.indexOf("convertLegacy")); }); it("reloads the exact invalid source, last-valid applied source, and untouched legacy rules", async () => { const harness = createHarness({ compile: () => failedCompile }); await harness.service.mutate({ ...commonMutationInput, transition: "edit_source", source: invalidSource, }); const reloaded = await harness.service.getState({ id: "resume-1", userId: "user-1" }); expect(reloaded.stylesheet.source).toEqual(invalidSource); expect(reloaded.stylesheet.applied).toEqual(previousApplied); expect(harness.persisted().data.metadata.styleRules).toEqual(snapshot().data.metadata.styleRules); }); });