/** * CE-WP-0008 — per-session capture state round-trip. */ import { describe, expect, it } from "vitest"; import type { EvidenceLink } from "@shared/evidence-link"; import type { EvidenceItemId, EvidenceLinkId, SessionId } from "@shared/ids"; import { CAPTURE_STATE_VERSION, captureStateKey, defaultCaptureState, loadCaptureState, persistCapturePatch, removeCaptureState, saveCaptureState, } from "./capture-persistence"; function memoryStorage(): Storage { const map = new Map(); return { get length() { return map.size; }, clear: () => map.clear(), getItem: (k) => map.get(k) ?? null, key: (i) => [...map.keys()][i] ?? null, removeItem: (k) => void map.delete(k), setItem: (k, v) => void map.set(k, v), }; } const SESSION = "sess_capture" as SessionId; describe("capture-persistence", () => { it("uses a per-session storage key", () => { expect(captureStateKey(SESSION)).toBe( "citation-evidence:session:sess_capture:capture-state:v1", ); }); it("round-trips schema, field values, and links", () => { const storage = memoryStorage(); const state = defaultCaptureState(); const withData = { ...state, fieldValues: { summary: "Tenant owes arrears", deadline: "2026-12-15" }, evidenceLinks: [ { id: "evlink_1" as EvidenceLinkId, evidenceItemId: "evi_1" as EvidenceItemId, targetType: "form-field", targetId: "summary", relation: "supports", status: "candidate", createdAt: "2026-06-08T00:00:00.000Z", updatedAt: "2026-06-08T00:00:00.000Z", } satisfies EvidenceLink, ], }; saveCaptureState(SESSION, withData, storage); const loaded = loadCaptureState(SESSION, storage); expect(loaded?.version).toBe(CAPTURE_STATE_VERSION); expect(loaded?.fieldValues).toEqual(withData.fieldValues); expect(loaded?.evidenceLinks).toHaveLength(1); expect(loaded?.formSchema.id).toBe("demo-form"); }); it("persistCapturePatch merges without dropping other fields", () => { const storage = memoryStorage(); saveCaptureState( SESSION, { ...defaultCaptureState(), fieldValues: { amount: "1200" }, evidenceLinks: [], }, storage, ); persistCapturePatch(SESSION, { fieldValues: { amount: "1500", summary: "Updated" } }, storage); const loaded = loadCaptureState(SESSION, storage); expect(loaded?.fieldValues).toEqual({ amount: "1500", summary: "Updated" }); }); it("removeCaptureState clears the key", () => { const storage = memoryStorage(); saveCaptureState(SESSION, defaultCaptureState(), storage); removeCaptureState(SESSION, storage); expect(loadCaptureState(SESSION, storage)).toBeNull(); }); });