82 lines
3.1 KiB
TypeScript
82 lines
3.1 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
|
|
import {
|
|
installerRequestMatchesPlan,
|
|
moduleInstallerQueueBlock,
|
|
moduleInstallerWorkflowStages,
|
|
type ModuleInstallerWorkflowInput
|
|
} from "../src/features/admin/moduleInstallerWorkflow.ts";
|
|
|
|
const ready: ModuleInstallerWorkflowInput = {
|
|
planItemCount: 1,
|
|
planDirty: false,
|
|
planValid: true,
|
|
preflightAllowed: true,
|
|
maintenanceEnabled: true,
|
|
canWrite: true,
|
|
canAccessMaintenance: true
|
|
};
|
|
|
|
test("keeps the operator on the earliest incomplete installer stage", () => {
|
|
assert.equal(moduleInstallerWorkflowStages({ ...ready, planItemCount: 0 })[0].current, true);
|
|
assert.equal(moduleInstallerWorkflowStages({ ...ready, planDirty: true })[0].current, true);
|
|
assert.equal(moduleInstallerWorkflowStages({ ...ready, preflightAllowed: false })[1].state, "blocked");
|
|
assert.equal(moduleInstallerWorkflowStages({ ...ready, maintenanceEnabled: false })[2].state, "blocked");
|
|
assert.equal(moduleInstallerWorkflowStages(ready)[2].state, "current");
|
|
});
|
|
|
|
test("moves queued work through execution to durable evidence", () => {
|
|
const queued = moduleInstallerWorkflowStages({ ...ready, requestStatus: "queued" });
|
|
assert.equal(queued[2].state, "complete");
|
|
assert.equal(queued[3].state, "current");
|
|
|
|
const completed = moduleInstallerWorkflowStages({
|
|
...ready,
|
|
requestStatus: "completed",
|
|
runStatus: "completed"
|
|
});
|
|
assert.deepEqual(completed.map((stage) => stage.state), [
|
|
"complete",
|
|
"complete",
|
|
"complete",
|
|
"complete",
|
|
"current"
|
|
]);
|
|
|
|
const failed = moduleInstallerWorkflowStages({
|
|
...ready,
|
|
requestStatus: "failed",
|
|
runStatus: "rollback_failed"
|
|
});
|
|
assert.equal(failed[4].state, "failed");
|
|
});
|
|
|
|
test("reports one actionable queue blocker in deterministic order", () => {
|
|
assert.equal(moduleInstallerQueueBlock({ ...ready, canWrite: false }), "write_access");
|
|
assert.equal(moduleInstallerQueueBlock({ ...ready, planItemCount: 0 }), "empty_plan");
|
|
assert.equal(moduleInstallerQueueBlock({ ...ready, planValid: false }), "invalid_plan");
|
|
assert.equal(moduleInstallerQueueBlock({ ...ready, planDirty: true }), "unsaved_plan");
|
|
assert.equal(moduleInstallerQueueBlock({ ...ready, preflightAllowed: false }), "preflight");
|
|
assert.equal(moduleInstallerQueueBlock({ ...ready, maintenanceEnabled: false }), "maintenance_mode");
|
|
assert.equal(moduleInstallerQueueBlock({ ...ready, canAccessMaintenance: false }), "maintenance_access");
|
|
assert.equal(
|
|
moduleInstallerQueueBlock({ ...ready, maintenanceEnabled: false, canAccessMaintenance: false }),
|
|
"maintenance_access"
|
|
);
|
|
assert.equal(moduleInstallerQueueBlock(ready), null);
|
|
});
|
|
|
|
test("does not present an older installer request as evidence for a newer plan", () => {
|
|
assert.equal(installerRequestMatchesPlan(null, "2026-08-03T10:00:00Z"), true);
|
|
assert.equal(
|
|
installerRequestMatchesPlan("2026-08-03T10:00:00Z", "2026-08-03T10:00:01Z"),
|
|
true
|
|
);
|
|
assert.equal(
|
|
installerRequestMatchesPlan("2026-08-03T10:00:00Z", "2026-08-03T09:59:59Z"),
|
|
false
|
|
);
|
|
assert.equal(installerRequestMatchesPlan("invalid", "2026-08-03T10:00:00Z"), false);
|
|
});
|