175 lines
5.0 KiB
JavaScript
175 lines
5.0 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { after, before, test } from "node:test";
|
|
|
|
import { createServer } from "vite";
|
|
|
|
let server;
|
|
let parseE40CaseCatalog;
|
|
let parseE40OperatorReview;
|
|
let fetchE40CaseCatalog;
|
|
let saveE40OperatorVerdict;
|
|
let E40CaseReviewContractError;
|
|
|
|
const resultId = `e40-perception-product-gate-${"a".repeat(64)}`;
|
|
const materializationId = `e30-materialization-${"b".repeat(64)}`;
|
|
const itemId = `e30-review-item-${"c".repeat(64)}`;
|
|
|
|
function payload(overrides = {}) {
|
|
return {
|
|
schema_version: "missioncore.laboratory-e40-case-catalog/v1",
|
|
result_id: resultId,
|
|
materialization_id: materializationId,
|
|
items: [{
|
|
item_id: itemId,
|
|
sequence: 3,
|
|
source_frame_index: 1080,
|
|
source_stratum: "geometry-only",
|
|
severity: "high",
|
|
presence_confidence: 1,
|
|
prediction_basis: "fixed-stratum-policy",
|
|
reference: {
|
|
presence: "object-present",
|
|
geometry_association: "object-associated",
|
|
freshness: "current",
|
|
},
|
|
prediction: {
|
|
presence: "occupied-environment",
|
|
geometry_association: "independent-occupied",
|
|
freshness: "current",
|
|
},
|
|
mismatched_dimensions: ["presence", "geometry_association"],
|
|
access: "read-only",
|
|
}],
|
|
total: 23,
|
|
truncated: false,
|
|
access: "read-only",
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
function reviewPayload(overrides = {}) {
|
|
return {
|
|
schema_version: "missioncore.e40-operator-review/v1",
|
|
review_id: `e40-operator-review-${"f".repeat(64)}`,
|
|
protocol: "sealed-error-adjudication/v1",
|
|
source: {
|
|
result_id: resultId,
|
|
materialization_id: materializationId,
|
|
case_catalog_sha256: "1".repeat(64),
|
|
item_count: 1,
|
|
item_set_sha256: "2".repeat(64),
|
|
},
|
|
reviewer_id: "DC",
|
|
revision: 1,
|
|
decisions: [{
|
|
item_id: itemId,
|
|
verdict: "confirmed-error",
|
|
revision: 1,
|
|
idempotency_key: "ui-test",
|
|
decided_at_utc: "2026-07-30T17:00:00.000Z",
|
|
event_id: `e40-operator-verdict-${"3".repeat(64)}`,
|
|
}],
|
|
reviewed_item_count: 1,
|
|
remaining_item_count: 0,
|
|
updated_at_utc: "2026-07-30T17:00:00.000Z",
|
|
access: "review-write",
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
before(async () => {
|
|
server = await createServer({
|
|
configFile: false,
|
|
appType: "custom",
|
|
optimizeDeps: { noDiscovery: true },
|
|
server: { middlewareMode: true, hmr: false },
|
|
});
|
|
({
|
|
parseE40CaseCatalog,
|
|
parseE40OperatorReview,
|
|
fetchE40CaseCatalog,
|
|
saveE40OperatorVerdict,
|
|
E40CaseReviewContractError,
|
|
} = await server.ssrLoadModule("/src/core/laboratory/e40CaseReview.ts"));
|
|
});
|
|
|
|
test("E40 operator review preserves the sealed source and verdict", () => {
|
|
const review = parseE40OperatorReview(reviewPayload());
|
|
|
|
assert.equal(review.resultId, resultId);
|
|
assert.equal(review.materializationId, materializationId);
|
|
assert.equal(review.caseCatalogSha256, "1".repeat(64));
|
|
assert.equal(review.reviewedItemCount, 1);
|
|
assert.equal(review.decisions[0].verdict, "confirmed-error");
|
|
});
|
|
|
|
after(async () => {
|
|
await server.close();
|
|
});
|
|
|
|
test("E40 case catalog preserves the sealed error binding", () => {
|
|
const catalog = parseE40CaseCatalog(payload());
|
|
|
|
assert.equal(catalog.resultId, resultId);
|
|
assert.equal(catalog.materializationId, materializationId);
|
|
assert.equal(catalog.items[0].sourceFrameIndex, 1080);
|
|
assert.equal(catalog.items[0].predictionBasis, "fixed-stratum-policy");
|
|
assert.deepEqual(
|
|
catalog.items[0].mismatchedDimensions,
|
|
["presence", "geometry_association"],
|
|
);
|
|
assert.equal(
|
|
catalog.items[0].prediction.geometryAssociation,
|
|
"independent-occupied",
|
|
);
|
|
});
|
|
|
|
test("E40 case fetch is bounded and rejects a foreign result", async () => {
|
|
let requestUrl = "";
|
|
const fetcher = async (input) => {
|
|
requestUrl = String(input);
|
|
return new Response(JSON.stringify(payload({
|
|
result_id: `e40-perception-product-gate-${"d".repeat(64)}`,
|
|
})), {
|
|
status: 200,
|
|
headers: { "Content-Type": "application/json" },
|
|
});
|
|
};
|
|
|
|
await assert.rejects(
|
|
fetchE40CaseCatalog(resultId, { fetcher }),
|
|
E40CaseReviewContractError,
|
|
);
|
|
assert.match(requestUrl, /cases\?limit=48$/);
|
|
});
|
|
|
|
test("E40 operator verdict is committed with revision and idempotency", async () => {
|
|
let requestUrl = "";
|
|
let requestInit;
|
|
const fetcher = async (input, init) => {
|
|
requestUrl = String(input);
|
|
requestInit = init;
|
|
return new Response(JSON.stringify(reviewPayload()), {
|
|
status: 200,
|
|
headers: { "Content-Type": "application/json" },
|
|
});
|
|
};
|
|
|
|
const review = await saveE40OperatorVerdict(resultId, itemId, {
|
|
expectedRevision: 0,
|
|
idempotencyKey: "ui-test",
|
|
verdict: "confirmed-error",
|
|
fetcher,
|
|
});
|
|
|
|
assert.match(requestUrl, /operator-review\/decisions\/e30-review-item-/);
|
|
assert.equal(requestInit.method, "PUT");
|
|
assert.deepEqual(JSON.parse(requestInit.body), {
|
|
reviewer_id: "DC",
|
|
expected_revision: 0,
|
|
idempotency_key: "ui-test",
|
|
verdict: "confirmed-error",
|
|
});
|
|
assert.equal(review.revision, 1);
|
|
});
|