Files
NODEDC_MISSION_CORE/apps/control-station/test/e30HumanReview.test.mjs
T

208 lines
5.7 KiB
JavaScript

import assert from "node:assert/strict";
import { after, before, test } from "node:test";
import { createServer } from "vite";
let server;
let parseE30HumanReviewDraft;
let parseE30HumanReviewFinalized;
let createOrResumeE30HumanReview;
let saveE30HumanReviewDecision;
let finalizeE30HumanReview;
let E30ReviewContractError;
const resultId = `e30-materialization-${"a".repeat(64)}`;
const engineeringGenerationId =
`e30-engineering-generation-${"b".repeat(64)}`;
const draftId = `e30-human-draft-${"c".repeat(64)}`;
const reviewGenerationId = `e30-review-generation-${"d".repeat(64)}`;
const firstItemId = `e30-review-item-${"e".repeat(64)}`;
const secondItemId = `e30-review-item-${"f".repeat(64)}`;
const firstEventId = `e30-review-event-${"1".repeat(64)}`;
const secondEventId = `e30-review-event-${"2".repeat(64)}`;
function decision(overrides = {}) {
return {
item_id: firstItemId,
source_stratum: "conflict",
disposition: "object-present",
notes: null,
event_id: firstEventId,
decided_at_utc: "2026-07-27T06:00:00Z",
...overrides,
};
}
function draft(overrides = {}) {
return {
schema_version: "missioncore.e30-human-review-draft/v2",
draft_id: draftId,
materialization_id: resultId,
engineering_generation_id: engineeringGenerationId,
reviewer_id: "DC",
created_at_utc: "2026-07-27T06:00:00Z",
state: "active",
revision: 1,
item_count: 2,
reviewed_item_count: 1,
remaining_item_count: 1,
disposition_distribution: { "object-present": 1 },
generation_id: null,
decisions: [decision()],
lab_published: false,
access: "review-write",
...overrides,
};
}
function finalized() {
return {
schema_version: "missioncore.laboratory-e30-human-review-finalized/v2",
draft: draft({
state: "finalized",
revision: 2,
reviewed_item_count: 2,
remaining_item_count: 0,
disposition_distribution: {
"object-present": 1,
"background-or-noise": 1,
},
generation_id: reviewGenerationId,
decisions: [
decision(),
decision({
item_id: secondItemId,
source_stratum: "unknown",
disposition: "background-or-noise",
event_id: secondEventId,
}),
],
access: "read-only",
}),
generation: {
schema_version: "missioncore.e30-human-review-generation/v2",
generation_id: reviewGenerationId,
materialization_id: resultId,
engineering_generation_id: engineeringGenerationId,
reviewer_id: "DC",
created_at_utc: "2026-07-27T06:05:00Z",
item_count: 2,
disposition_distribution: {
"object-present": 1,
"background-or-noise": 1,
},
coverage: {
expected_item_count: 2,
reviewed_item_count: 2,
complete: true,
},
human_review_complete: true,
lab_published: false,
access: "read-only",
},
};
}
before(async () => {
server = await createServer({
appType: "custom",
logLevel: "silent",
server: { middlewareMode: true },
});
({
parseE30HumanReviewDraft,
parseE30HumanReviewFinalized,
createOrResumeE30HumanReview,
saveE30HumanReviewDecision,
finalizeE30HumanReview,
} = await server.ssrLoadModule(
"/src/core/laboratory/e30HumanReview.ts",
));
({ E30ReviewContractError } = await server.ssrLoadModule(
"/src/core/laboratory/e30Review.ts",
));
});
after(async () => {
await server?.close();
});
test("decodes an exception-only draft and immutable final generation", () => {
const active = parseE30HumanReviewDraft(draft());
const complete = parseE30HumanReviewFinalized(finalized());
assert.equal(active.engineeringGenerationId, engineeringGenerationId);
assert.equal(active.reviewedItemCount, 1);
assert.equal(active.decisions[0].disposition, "object-present");
assert.equal(complete.draft.state, "finalized");
assert.equal(complete.generation.humanReviewComplete, true);
assert.equal(complete.generation.labPublished, false);
});
test("rejects unknown dispositions and finalized writable access", () => {
assert.throws(
() => parseE30HumanReviewDraft(draft({
decisions: [decision({ disposition: "invented" })],
})),
E30ReviewContractError,
);
assert.throws(
() => parseE30HumanReviewDraft(draft({
state: "finalized",
access: "review-write",
})),
E30ReviewContractError,
);
});
test("uses generation-bound write endpoints and explicit finalization", async () => {
const requests = [];
const fetcher = async (input, init) => {
const body = init?.body ? JSON.parse(String(init.body)) : null;
requests.push({ input: String(input), method: init?.method, body });
const payload = String(input).includes("/finalize?")
? finalized()
: draft();
return new Response(JSON.stringify(payload), {
status: 200,
headers: { "Content-Type": "application/json" },
});
};
await createOrResumeE30HumanReview(
resultId,
engineeringGenerationId,
"DC",
{ fetcher },
);
await saveE30HumanReviewDecision(
resultId,
engineeringGenerationId,
draftId,
firstItemId,
{
expectedRevision: 1,
idempotencyKey: "ui-decision-001",
disposition: "insufficient-evidence",
notes: null,
},
{ fetcher },
);
await finalizeE30HumanReview(
resultId,
engineeringGenerationId,
draftId,
2,
{ fetcher },
);
assert.equal(requests[0].method, "POST");
assert.deepEqual(requests[0].body, {
reviewer_id: "DC",
engineering_generation_id: engineeringGenerationId,
});
assert.match(requests[1].input, /engineering_generation_id=/);
assert.equal(requests[1].body.disposition, "insufficient-evidence");
assert.equal(requests[2].body.confirm_generation, true);
});