src/features/reviews/command-draft.test.ts
Linked repository file from this build.
import { expect, test } from "bun:test";
import { CommandDraft } from "./command-draft";
import { execute, finalCurrent } from "./commands";
import { createSeed } from "@/programs/snap-negative/seed";
import type { PendingCommand } from "./persistence";
import { demoActor } from "@/lib/auth/roster";
const actor = { ...demoActor("examiner"), name: "Test Examiner" };
function entry(command: PendingCommand["command"]): PendingCommand {
return { command, actor, id: crypto.randomUUID(), at: new Date().toISOString() };
}
test("typing a narrative previews and commits one revision and activity event", () => {
const buffer = new CommandDraft();
const base = createSeed();
let preview = base;
const text = "A meaningful synthetic narrative.";
for (let i = 1; i <= text.length; i++)
preview = buffer.stage(
preview,
entry({ type: "answers", value: { ...preview.facts.answers, narrative: text.slice(0, i) } }),
);
expect(preview.revision).toBe(base.revision + 1);
expect(preview.activity).toHaveLength(base.activity.length + 1);
const committed = buffer.take()!;
expect(buffer.take()).toBeUndefined();
expect(execute(base, committed.command, actor, { id: committed.id, at: committed.at })).toEqual(
preview,
);
});
test("identity drafts merge patches and immediately invalidate affected results", () => {
const buffer = new CommandDraft();
const seed = createSeed();
const base = execute(seed, { type: "apply_final" }, actor, {
id: "final",
at: new Date().toISOString(),
});
let preview = buffer.stage(
base,
entry({ type: "identity", value: { clientName: "Draft client" } }),
);
preview = buffer.stage(preview, entry({ type: "identity", value: { sampleMonth: "2026-05" } }));
expect(preview.clientName).toBe("Draft client");
expect(preview.sampleMonth).toBe("2026-05");
expect(finalCurrent(preview)).toBe(false);
expect(preview.facts.inputsRevision).toBe(base.facts.inputsRevision + 1);
expect(buffer.accepts(entry({ type: "answers", value: base.facts.answers }))).toBe(false);
expect(
buffer.accepts({
...entry({ type: "identity", value: { address: "Elsewhere" } }),
actor: { ...demoActor("supervisor"), name: "Other" },
}),
).toBe(false);
});
test("draft previews match committed execution without mutating their base", () => {
const seed = createSeed();
const noteBase = {
...seed,
notes: [{ id: "note-1", body: "Old", actor, createdAt: "2026-01-01T00:00:00.000Z" }],
};
const conditionalBase = {
...seed,
state: "awaiting_pec_approval" as const,
pecDecision: {
decision: "conditional" as const,
policyNote: "Original",
actor,
createdAt: "2026-01-01T00:00:00.000Z",
},
};
const cases: [typeof seed, PendingCommand["command"]][] = [
[seed, { type: "identity", value: { clientName: "Draft name" } }],
[seed, { type: "negative_action", value: { noticeDate: "2026-03-21" } }],
[seed, { type: "answers", value: { ...seed.facts.answers, narrative: "Draft" } }],
[seed, { type: "household", value: seed.facts.members.map((member) => ({ ...member })) }],
[seed, { type: "scenario", scenario: "compI", value: seed.facts.scenarios.compI }],
[noteBase, { type: "update_note", noteId: "note-1", body: "Changed" }],
[conditionalBase, { type: "conditional_notes", body: "Changed conditions" }],
];
for (const [base, command] of cases) {
const before = structuredClone(base);
const pending = entry(command);
const preview = new CommandDraft().stage(base, pending);
expect(base).toEqual(before);
expect(preview).toEqual(
execute(base, command, pending.actor, { id: pending.id, at: pending.at }),
);
}
});