Files
citation-evidence/src/app/forms/capture-persistence.test.ts
tegwick dd2f2115bd Implement CE-WP-0009: wire umbrella to @citation-evidence/engine
Add link: dependency on citation-engine, retarget @shared/@engine aliases,
remove in-repo shared/engine copies. ADR-0002 accepted (option B).
172 tests, typecheck, and lint pass.
2026-06-22 19:45:11 +02:00

96 lines
2.8 KiB
TypeScript

/**
* 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<string, string>();
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();
});
});