test(repairs): pin the status labels, variants and next steps

This commit is contained in:
Dave 2026-11-06 05:57:17 +02:00
parent 2ad066045a
commit 4c0256baf4

View file

@ -28,6 +28,37 @@ describe("repair status vocabulary", () => {
}
});
// The label is the operator-facing wording on EVERY repairs surface
// (office list, office detail, the phone app, the agent's tools).
// Truthiness above only proves a label EXISTS - a typo or a swapped
// word would still pass. Pin the exact wording.
it("pins the operator-facing label of every status", () => {
expect(REPAIR_STATUS_LABEL).toEqual({
new: "Booked in",
assessing: "With supplier",
quoted: "Quote in",
approved: "Approved",
in_progress: "On the bench",
completed: "Done",
cancelled: "Cancelled",
});
});
// Same for the badge variant. "secondary" is a legal variant on the
// WRONG status, and no type check can catch that - only the exact
// assignment can.
it("pins the badge variant of every status", () => {
expect(REPAIR_STATUS_VARIANT).toEqual({
new: "outline",
assessing: "secondary",
quoted: "secondary",
approved: "default",
in_progress: "secondary",
completed: "default",
cancelled: "destructive",
});
});
it("allows exactly the transitions the service allowed before", () => {
expect(REPAIR_TRANSITIONS.new).toEqual(["assessing", "quoted", "cancelled"]);
expect(REPAIR_TRANSITIONS.assessing).toEqual(["quoted", "cancelled"]);
@ -59,6 +90,40 @@ describe("repair status vocabulary", () => {
expect(nextStepFor("cancelled")).toBeNull();
});
// The whole next step, pinned - label AND action AND target. The
// target matters most: "quoted" must point at "approved", never at
// "in_progress". Both are legal transitions, but in_progress would
// let a job skip the customer's approval.
it("pins the exact next step of every status", () => {
expect(nextStepFor("new")).toEqual({
label: "Send to supplier",
action: "generate_repair_request",
to: "assessing",
});
expect(nextStepFor("assessing")).toEqual({
label: "Upload supplier quote",
action: "upload_supplier_quote",
to: "quoted",
});
expect(nextStepFor("quoted")).toEqual({
label: "Make customer quote",
action: "create_customer_quote",
to: "approved",
});
expect(nextStepFor("approved")).toEqual({
label: "Start work",
action: "start_work",
to: "in_progress",
});
expect(nextStepFor("in_progress")).toEqual({
label: "Mark completed",
action: "mark_completed",
to: "completed",
});
expect(nextStepFor("completed")).toBeNull();
expect(nextStepFor("cancelled")).toBeNull();
});
it("never offers a next step that is not a legal transition", () => {
for (const status of REPAIR_STATUS) {
const step = nextStepFor(status);
@ -74,6 +139,11 @@ describe("repair status vocabulary", () => {
expect(() => assertRepairTransition("new", "completed")).toThrow(
/allowed: assessing, quoted, cancelled/,
);
// A status with NO legal targets names "none" - the terminal
// wording the caller shows the operator.
expect(() => assertRepairTransition("completed", "completed")).toThrow(
/Cannot transition repair from "completed" to "completed" \(allowed: none\)\./,
);
expect(() => assertRepairTransition("new", "assessing")).not.toThrow();
});
});