new Approval Updates
Deploy / deploy (push) Failing after 3m34s

This commit is contained in:
twotalesanimation
2026-06-11 12:30:28 +02:00
parent b9610454d9
commit 3f0c5d1dbe
19 changed files with 2015 additions and 70 deletions
+144
View File
@@ -0,0 +1,144 @@
import { describe, it, expect, vi } from "vitest";
// Mock Prisma db so the pure deriveShotStatus function can be tested in isolation
vi.mock("@/lib/db", () => ({ db: {} }));
import { deriveShotStatus } from "./shot-status";
import type { TaskStatus } from "@prisma/client";
// Helper to build task arrays quickly
const tasks = (...statuses: TaskStatus[]) => statuses.map((status) => ({ status }));
describe("deriveShotStatus", () => {
// ── WAITING ───────────────────────────────────────────────────────────────
it("returns WAITING when there are no tasks", () => {
expect(deriveShotStatus([], "PENDING", false)).toBe("WAITING");
});
it("returns WAITING when no tasks and internally approved (edge case: no tasks)", () => {
// With INTERNALLY_APPROVED + no tasks the approval fields take precedence
expect(deriveShotStatus([], "INTERNALLY_APPROVED", false)).toBe("READY_FOR_CLIENT");
});
// ── IN_PROGRESS ───────────────────────────────────────────────────────────
it("returns IN_PROGRESS when a task is TODO", () => {
expect(deriveShotStatus(tasks("TODO"), "PENDING", false)).toBe("IN_PROGRESS");
});
it("returns IN_PROGRESS when a task is IN_PROGRESS", () => {
expect(deriveShotStatus(tasks("IN_PROGRESS"), "PENDING", false)).toBe("IN_PROGRESS");
});
it("returns IN_PROGRESS when tasks are mixed TODO and DONE", () => {
expect(deriveShotStatus(tasks("TODO", "DONE"), "PENDING", false)).toBe("IN_PROGRESS");
});
it("returns IN_PROGRESS for INTERNAL_REVIEW task status (task in internal review)", () => {
// Task is in INTERNAL_REVIEW — not TODO/IN_PROGRESS/CHANGES → falls through to INTERNAL_REVIEW shot status
expect(deriveShotStatus(tasks("INTERNAL_REVIEW"), "PENDING", false)).toBe("INTERNAL_REVIEW");
});
// ── REVISIONS (highest priority) ─────────────────────────────────────────
it("returns REVISIONS when any task is CHANGES", () => {
expect(deriveShotStatus(tasks("CHANGES"), "PENDING", false)).toBe("REVISIONS");
});
it("returns REVISIONS even when some tasks are DONE", () => {
expect(deriveShotStatus(tasks("DONE", "CHANGES"), "PENDING", false)).toBe("REVISIONS");
});
it("returns REVISIONS even when shot is INTERNALLY_APPROVED", () => {
// If somehow a task is in CHANGES after approval, REVISIONS wins
expect(deriveShotStatus(tasks("CHANGES"), "INTERNALLY_APPROVED", false)).toBe("REVISIONS");
});
it("returns REVISIONS even when shot is CLIENT_APPROVED", () => {
expect(deriveShotStatus(tasks("CHANGES"), "CLIENT_APPROVED", false)).toBe("REVISIONS");
});
// ── INTERNAL_REVIEW ───────────────────────────────────────────────────────
it("returns INTERNAL_REVIEW when all tasks are DONE and approval is PENDING", () => {
expect(deriveShotStatus(tasks("DONE", "DONE"), "PENDING", false)).toBe("INTERNAL_REVIEW");
});
it("returns INTERNAL_REVIEW when tasks are INTERNAL_REVIEW/CLIENT_REVIEW and approval is PENDING", () => {
expect(deriveShotStatus(tasks("INTERNAL_REVIEW", "CLIENT_REVIEW"), "PENDING", false)).toBe("INTERNAL_REVIEW");
});
it("returns INTERNAL_REVIEW when all tasks are DONE, regardless of sharedWithClient", () => {
// sharedWithClient has no effect when approval is still PENDING
expect(deriveShotStatus(tasks("DONE"), "PENDING", true)).toBe("INTERNAL_REVIEW");
});
// ── READY_FOR_CLIENT ──────────────────────────────────────────────────────
it("returns READY_FOR_CLIENT when internally approved and not shared", () => {
expect(deriveShotStatus(tasks("DONE"), "INTERNALLY_APPROVED", false)).toBe("READY_FOR_CLIENT");
});
it("returns READY_FOR_CLIENT when internally approved and not shared (no tasks)", () => {
expect(deriveShotStatus([], "INTERNALLY_APPROVED", false)).toBe("READY_FOR_CLIENT");
});
// ── CLIENT_REVIEW ─────────────────────────────────────────────────────────
it("returns CLIENT_REVIEW when internally approved and shared", () => {
expect(deriveShotStatus(tasks("DONE"), "INTERNALLY_APPROVED", true)).toBe("CLIENT_REVIEW");
});
it("returns CLIENT_REVIEW when internally approved, shared, and tasks still in progress", () => {
// Approval field takes precedence over task statuses (except CHANGES)
expect(deriveShotStatus(tasks("TODO"), "INTERNALLY_APPROVED", true)).toBe("CLIENT_REVIEW");
});
// ── COMPLETE ──────────────────────────────────────────────────────────────
it("returns COMPLETE when client approved", () => {
expect(deriveShotStatus(tasks("DONE"), "CLIENT_APPROVED", true)).toBe("COMPLETE");
});
it("returns COMPLETE when client approved even if not shared anymore", () => {
expect(deriveShotStatus(tasks("DONE"), "CLIENT_APPROVED", false)).toBe("COMPLETE");
});
// ── State transition scenarios ────────────────────────────────────────────
describe("full workflow transitions", () => {
it("Artist work → tasks TODO → IN_PROGRESS", () => {
expect(deriveShotStatus(tasks("TODO"), "PENDING", false)).toBe("IN_PROGRESS");
});
it("Tasks in internal review → INTERNAL_REVIEW shot status", () => {
expect(deriveShotStatus(tasks("INTERNAL_REVIEW"), "PENDING", false)).toBe("INTERNAL_REVIEW");
});
it("All tasks done → INTERNAL_REVIEW (awaiting supervisor)", () => {
expect(deriveShotStatus(tasks("DONE", "DONE", "DONE"), "PENDING", false)).toBe("INTERNAL_REVIEW");
});
it("Supervisor approves → READY_FOR_CLIENT", () => {
expect(deriveShotStatus(tasks("DONE"), "INTERNALLY_APPROVED", false)).toBe("READY_FOR_CLIENT");
});
it("Producer shares → CLIENT_REVIEW", () => {
expect(deriveShotStatus(tasks("DONE"), "INTERNALLY_APPROVED", true)).toBe("CLIENT_REVIEW");
});
it("Producer unshares → READY_FOR_CLIENT", () => {
expect(deriveShotStatus(tasks("DONE"), "INTERNALLY_APPROVED", false)).toBe("READY_FOR_CLIENT");
});
it("Client approves → COMPLETE", () => {
expect(deriveShotStatus(tasks("DONE"), "CLIENT_APPROVED", false)).toBe("COMPLETE");
});
it("Client requests changes → approval reset to PENDING + task CHANGES → REVISIONS", () => {
// When changes are requested: shotApprovalStatus → PENDING, sharedWithClient → false, task → CHANGES
expect(deriveShotStatus(tasks("CHANGES"), "PENDING", false)).toBe("REVISIONS");
});
});
});