/** * TASK-0102 DoD: "Status machine enforced; only valid transitions possible * (test)." The full transition table — valid and invalid — is pinned here. */ import { describe, expect, it } from "vitest"; import { ALLOWED_TRANSITIONS, assertTransition, isValidTransition, InvalidTransitionError } from "../status.js"; import type { FileStatus } from "@prisma/client"; const ALL: FileStatus[] = ["UPLOADING", "SCANNING", "READY", "VIRUS_DETECTED", "FAILED"]; describe("files status machine (TASK-0102 §2)", () => { it("allows exactly the spec transitions", () => { expect(ALLOWED_TRANSITIONS.UPLOADING).toEqual(["SCANNING"]); expect(ALLOWED_TRANSITIONS.SCANNING).toEqual(["READY", "VIRUS_DETECTED", "FAILED"]); expect(ALLOWED_TRANSITIONS.READY).toEqual(["FAILED"]); // re-scan only expect(ALLOWED_TRANSITIONS.VIRUS_DETECTED).toEqual([]); expect(ALLOWED_TRANSITIONS.FAILED).toEqual([]); }); it("isValidTransition matches the table for every (from,to) pair", () => { for (const from of ALL) { for (const to of ALL) { expect(isValidTransition(from, to)).toBe(ALLOWED_TRANSITIONS[from].includes(to)); } } }); it("assertTransition passes on legal transitions", () => { expect(() => assertTransition("UPLOADING", "SCANNING")).not.toThrow(); expect(() => assertTransition("SCANNING", "READY")).not.toThrow(); expect(() => assertTransition("SCANNING", "VIRUS_DETECTED")).not.toThrow(); expect(() => assertTransition("SCANNING", "FAILED")).not.toThrow(); expect(() => assertTransition("READY", "FAILED")).not.toThrow(); }); it("assertTransition throws InvalidTransitionError on every illegal transition", () => { for (const from of ALL) { for (const to of ALL) { if (ALLOWED_TRANSITIONS[from].includes(to)) continue; expect(() => assertTransition(from, to), `${from} → ${to}`).toThrow( InvalidTransitionError ); expect(() => assertTransition(from, to), `${from} → ${to}`).toThrow( new RegExp(`${from} → ${to}`) ); } } }); it("terminal states have no outgoing transitions", () => { for (const t of ["VIRUS_DETECTED", "FAILED"] as FileStatus[]) { for (const to of ALL) { expect(isValidTransition(t, to)).toBe(false); } } }); it("READY is terminal for the pipeline (only a later re-scan → FAILED)", () => { expect(isValidTransition("READY", "READY")).toBe(false); expect(isValidTransition("READY", "SCANNING")).toBe(false); expect(isValidTransition("READY", "VIRUS_DETECTED")).toBe(false); expect(isValidTransition("READY", "FAILED")).toBe(true); }); });