/** * The engine's labels and board columns: every stage lands in exactly one column, a legacy * task lands by its status, and grouping keeps the order the tasks came in. */ import { describe, expect, it } from "vitest"; import { BOARD_COLUMNS, columnFor, groupByColumn, ROLE_LABELS, STAGE_LABELS, stageTone, TIER_LABELS, } from "@/lib/engine-labels"; const STAGES = [ "pending_manager_review", "pending_analysis", "pending_implementation", "pending_review", "pending_test", "pending_final_review", "merge_request", "completed", "pending_user_decision", "error_review", "paused", "cancelled", "failed", ]; describe("the board", () => { it("places every one of the thirteen stages in exactly one column", () => { for (const stage of STAGES) { const homes = BOARD_COLUMNS.filter((column) => column.stages.includes(stage as never)); expect(homes, stage).toHaveLength(1); expect(STAGE_LABELS[stage], stage).toBeTruthy(); } const placed = BOARD_COLUMNS.flatMap((column) => column.stages as readonly string[]); expect([...placed].sort()).toEqual([...STAGES].sort()); }); it("uses the stage column whenever the engine owns the task", () => { expect(columnFor("pending_test", "running")).toBe("test"); expect(columnFor("pending_final_review", "running")).toBe("review"); expect(columnFor("paused", "waiting_approval")).toBe("decision"); expect(columnFor("completed", "done")).toBe("done"); }); it("places a legacy task by its coarse status", () => { expect(columnFor(null, "new")).toBe("manager_review"); expect(columnFor(null, "triaged")).toBe("implementation"); expect(columnFor(null, "running")).toBe("implementation"); expect(columnFor(null, "waiting_approval")).toBe("decision"); for (const status of ["done", "failed", "cancelled"]) { expect(columnFor(null, status)).toBe("done"); } }); it("sends an unknown stage or status to the decision column", () => { expect(columnFor("some_new_stage", "running")).toBe("decision"); expect(columnFor(null, "some_new_status")).toBe("decision"); }); it("groups tasks by column, keeps every column, and keeps the order inside each", () => { const tasks = [ { id: "a", stage: "pending_test", status: "running" }, { id: "b", stage: null, status: "new" }, { id: "c", stage: "pending_test", status: "running" }, { id: "d", stage: "pending_final_review", status: "running" }, ]; const groups = groupByColumn(tasks); expect(groups.test.map((task) => task.id)).toEqual(["a", "c"]); expect(groups.review.map((task) => task.id)).toEqual(["d"]); expect(groups.manager_review.map((task) => task.id)).toEqual(["b"]); expect(groups.merge).toEqual([]); expect(Object.keys(groups)).toHaveLength(BOARD_COLUMNS.length); }); }); describe("labels and tones", () => { it("tones a stage by how it ended or whether a person must act", () => { expect(stageTone("completed")).toBe("success"); expect(stageTone("failed")).toBe("danger"); expect(stageTone("cancelled")).toBe("danger"); expect(stageTone("paused")).toBe("warning"); expect(stageTone("pending_user_decision")).toBe("warning"); expect(stageTone("error_review")).toBe("warning"); expect(stageTone("pending_test")).toBe("info"); }); it("labels the four tiers in Persian", () => { expect(TIER_LABELS).toEqual({ fast: "سریع", balanced: "متعادل", strong: "قوی", unknown: "نامشخص", }); }); it("labels the five hirable roles in Persian", () => { expect(Object.keys(ROLE_LABELS).sort()).toEqual( ["developer", "manager", "planner", "reviewer", "tester"].sort(), ); expect(ROLE_LABELS.manager).toBe("مدیر"); expect(ROLE_LABELS.reviewer).toBe("بازبین"); expect(ROLE_LABELS.tester).toBe("آزمونگر"); }); });