79 lines
1.9 KiB
TypeScript
79 lines
1.9 KiB
TypeScript
|
|
import { describe, expect, it } from "vitest";
|
||
|
|
|
||
|
|
import { ConvoyTransitionError, validateConvoyTransition } from "./state-machine";
|
||
|
|
|
||
|
|
describe("validateConvoyTransition", () => {
|
||
|
|
it("rejects draft → released", () => {
|
||
|
|
expect(() =>
|
||
|
|
validateConvoyTransition({
|
||
|
|
from: "draft",
|
||
|
|
to: "released",
|
||
|
|
actor: "human-gate-1",
|
||
|
|
}),
|
||
|
|
).toThrow(ConvoyTransitionError);
|
||
|
|
|
||
|
|
try {
|
||
|
|
validateConvoyTransition({
|
||
|
|
from: "draft",
|
||
|
|
to: "released",
|
||
|
|
actor: "human-gate-1",
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
expect(error).toBeInstanceOf(ConvoyTransitionError);
|
||
|
|
expect((error as ConvoyTransitionError).code).toBe("INVALID_TRANSITION");
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
it("rejects role-architect on human-gate-1 transition", () => {
|
||
|
|
expect(() =>
|
||
|
|
validateConvoyTransition({
|
||
|
|
from: "convoy_review",
|
||
|
|
to: "ready",
|
||
|
|
actor: "role-architect",
|
||
|
|
}),
|
||
|
|
).toThrow(ConvoyTransitionError);
|
||
|
|
|
||
|
|
try {
|
||
|
|
validateConvoyTransition({
|
||
|
|
from: "convoy_review",
|
||
|
|
to: "ready",
|
||
|
|
actor: "role-architect",
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
expect((error as ConvoyTransitionError).code).toBe("FORBIDDEN_ACTOR");
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
it("allows human-gate-1 to approve plan", () => {
|
||
|
|
expect(() =>
|
||
|
|
validateConvoyTransition({
|
||
|
|
from: "convoy_review",
|
||
|
|
to: "ready",
|
||
|
|
actor: "human-gate-1",
|
||
|
|
}),
|
||
|
|
).not.toThrow();
|
||
|
|
});
|
||
|
|
|
||
|
|
it("allows role-architect to submit plan for review", () => {
|
||
|
|
expect(() =>
|
||
|
|
validateConvoyTransition({
|
||
|
|
from: "draft",
|
||
|
|
to: "convoy_review",
|
||
|
|
actor: "role-architect",
|
||
|
|
}),
|
||
|
|
).not.toThrow();
|
||
|
|
});
|
||
|
|
|
||
|
|
it("requires reason for blocked transitions", () => {
|
||
|
|
try {
|
||
|
|
validateConvoyTransition({
|
||
|
|
from: "ready",
|
||
|
|
to: "blocked",
|
||
|
|
actor: "role-implementer",
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
expect((error as ConvoyTransitionError).code).toBe("REASON_REQUIRED");
|
||
|
|
}
|
||
|
|
});
|
||
|
|
});
|