doatlas-2 / artifacts /api-server /src /lib /capability /__tests__ /lifecycle-transitions.test.ts
Iostream-Li's picture
Add files using upload-large-folder tool
ff78003 verified
Raw
History Blame Contribute Delete
3.24 kB
/**
* Task #242 (B1) — lifecycle transition tests.
*
* Unit-half: pure isLegalTransition matrix.
* DB-half: transitionTo persists row when DATABASE_URL is set.
*/
import { test } from "node:test";
import assert from "node:assert/strict";
import {
isLegalTransition,
assertLegalTransition,
IllegalLifecycleTransitionError,
ALL_LIFECYCLE_STATES,
type CapabilityLifecycleState,
} from "../lifecycle.ts";
const LEGAL: ReadonlyArray<[CapabilityLifecycleState, CapabilityLifecycleState]> = [
["created", "cold_start"],
["cold_start", "graduated"],
["cold_start", "degraded"],
["graduated", "live"],
["graduated", "degraded"],
["live", "degraded"],
["degraded", "cold_start"],
["degraded", "live"],
];
test("lifecycle: isLegalTransition matches expected matrix", () => {
for (const [from, to] of LEGAL) {
assert.equal(isLegalTransition(from, to), true, `${from}${to} should be legal`);
}
// self-transition is not legal
for (const s of ALL_LIFECYCLE_STATES) {
assert.equal(isLegalTransition(s, s), false, `self ${s}${s} should not be legal`);
}
// a known illegal jump
assert.equal(isLegalTransition("created", "live"), false);
assert.equal(isLegalTransition("created", "degraded"), false);
assert.equal(isLegalTransition("graduated", "cold_start"), false);
assert.equal(isLegalTransition("live", "created"), false);
});
test("lifecycle: assertLegalTransition throws IllegalLifecycleTransitionError on bad jump", () => {
assert.throws(
() => assertLegalTransition("created", "live"),
(err: unknown) => err instanceof IllegalLifecycleTransitionError,
);
});
const SKIP_DB = !process.env["DATABASE_URL"];
test(
"lifecycle: transitionTo persists capability_lifecycle_events row",
{ skip: SKIP_DB && "DATABASE_URL not set" },
async () => {
const { transitionTo } = await import("../lifecycle.ts");
const { db, capabilityLifecycleEvents } = await import("@workspace/db");
const { eq } = await import("drizzle-orm");
const capabilityId = `cap_b1test_${Math.random().toString(16).slice(2, 8)}`;
const r = await transitionTo({
capabilityId,
from: "created",
to: "cold_start",
reason: "b1_test",
payload: { foo: "bar" },
});
assert.ok(r.eventId);
const rows = await db
.select()
.from(capabilityLifecycleEvents)
.where(eq(capabilityLifecycleEvents.id, r.eventId));
assert.equal(rows.length, 1);
assert.equal(rows[0]!.capabilityId, capabilityId);
assert.equal(rows[0]!.toState, "cold_start");
assert.equal(rows[0]!.reason, "b1_test");
// cleanup
await db
.delete(capabilityLifecycleEvents)
.where(eq(capabilityLifecycleEvents.id, r.eventId));
},
);
test(
"lifecycle: transitionTo throws on illegal transition (no row written)",
{ skip: SKIP_DB && "DATABASE_URL not set" },
async () => {
const { transitionTo } = await import("../lifecycle.ts");
await assert.rejects(
() =>
transitionTo({
capabilityId: "cap_b1test_illegal",
from: "created",
to: "live",
reason: "should_fail",
}),
(err: unknown) => err instanceof IllegalLifecycleTransitionError,
);
},
);