WFDASH-WEBAPP/src/lib/quote-status.test.ts
SJCoetz 7f924ccc45 refactor: switch hardcoded UI colors to semantic theme tokens
Overhaul the app's color system by replacing all hardcoded Tailwind color classes with semantic theme variables to ensure consistent theming across all components, pages, and tests.

Additional changes:
- Add assigned date support for order item status updates: add `assignedDate` field to the order item status PATCH API, implement server-side normalization/validation, and add corresponding tests
- Refactor purchase order PDF workflows to use the consolidated `purchase_orders.documents` field instead of the legacy separate `purchase_order_pdfs` collection
- Fix quote number parsing and formatting to support both dashed (Q-YYYY-MM-NNN) and dashless (QYYYYMMNNN) formats
- Rename `driver_pool` item status to `collection_pool` across the codebase
- Add null handling for order item quantities and pricing to display "—" for missing values
- Improve filter tab styling: make mobile tabs scrollable, prevent text wrapping, hide scrollbar
- Add new utility scripts, API routes, migrations, and polish small UI/UX fixes including tsconfig updates and theme hook improvements
2026-07-07 17:22:03 +02:00

75 lines
2.5 KiB
TypeScript

import { describe, it, expect } from "vitest";
import { quoteStatusClassName, formatQuoteStatus } from "./quote-status";
describe("quoteStatusClassName", () => {
it("returns a styled class string for known statuses", () => {
const cls = quoteStatusClassName("new");
expect(cls).toContain("border-info");
expect(cls).toContain("bg-info");
});
it("returns a fallback class for unknown statuses", () => {
const cls = quoteStatusClassName("not_a_real_status");
expect(cls).toContain("border-muted");
expect(cls).toContain("bg-muted");
});
it("supports every documented quote status", () => {
const statuses = [
"new",
"claimed",
"processed",
"emailed",
"approval_pending",
"approved",
"rejected",
"problem",
"complete",
"cancelled",
"follow_up",
"email_failed",
"unmatched_bounce",
"template",
"sending",
"mail_failed",
];
for (const s of statuses) {
const cls = quoteStatusClassName(s);
// Every known status must produce a border-using class so the
// pill has visual weight. The neutral `cancelled` shares the
// muted fallback on purpose (it's terminal — no semantic
// colour needed); everything else must produce its own map
// entry.
expect(cls, `class for ${s}`).toMatch(/border-/);
if (s !== "cancelled") {
expect(
cls,
`class for ${s}`,
).not.toContain("border-muted bg-muted text-muted-foreground");
}
}
});
});
describe("formatQuoteStatus", () => {
it("uses workflow-friendly labels for email-status enums", () => {
expect(formatQuoteStatus("email_failed")).toBe("Email failed");
expect(formatQuoteStatus("mail_failed")).toBe("Mail failed");
expect(formatQuoteStatus("unmatched_bounce")).toBe("Unmatched bounce");
});
it("renders workflow-friendly labels for the merged tabs", () => {
expect(formatQuoteStatus("approval_pending")).toBe("Pending approval");
expect(formatQuoteStatus("emailed")).toBe("Awaiting reply");
expect(formatQuoteStatus("sending")).toBe("Sending…");
expect(formatQuoteStatus("follow_up")).toBe("Follow up");
});
it("leaves single-word and terminal statuses unchanged", () => {
expect(formatQuoteStatus("new")).toBe("new");
expect(formatQuoteStatus("complete")).toBe("complete");
expect(formatQuoteStatus("cancelled")).toBe("cancelled");
expect(formatQuoteStatus("rejected")).toBe("rejected");
expect(formatQuoteStatus("claimed")).toBe("claimed");
});
});