import { describe, it, expect } from "vitest"; import { cn, displayContactName } from "./utils"; describe("cn", () => { it("merges class names", () => { expect(cn("foo", "bar")).toBe("foo bar"); }); it("filters falsy values", () => { expect(cn("foo", false, null, undefined, "", "bar")).toBe("foo bar"); }); it("dedupes conflicting tailwind classes", () => { // twMerge keeps the last conflicting utility expect(cn("px-2", "px-4")).toBe("px-4"); }); it("handles conditional class objects via clsx", () => { expect(cn("base", { active: true, disabled: false })).toBe("base active"); }); it("returns empty string for no args", () => { expect(cn()).toBe(""); }); }); describe("displayContactName", () => { // The contact_name field is populated by an LLM during email intake; // it historically contains stray whitespace that produces visible // "miss" symptoms on the orders list (a dangling separator dot with // no actual name). These tests pin the sanitiser's contract. it("returns empty string for null / undefined / non-strings", () => { expect(displayContactName(null)).toBe(""); expect(displayContactName(undefined)).toBe(""); expect(displayContactName("")).toBe(""); }); it("trims leading and trailing whitespace", () => { expect(displayContactName(" Neville Benadé ")).toBe("Neville Benadé"); }); it("collapses internal whitespace runs (including newlines) to a single space", () => { expect(displayContactName("Neville Benadé")).toBe("Neville Benadé"); expect(displayContactName("Neville\nBenadé")).toBe("Neville Benadé"); expect(displayContactName("Neville\t\n Benadé")).toBe("Neville Benadé"); }); it("returns empty string for whitespace-only input", () => { expect(displayContactName("\n")).toBe(""); expect(displayContactName(" ")).toBe(""); expect(displayContactName("\n\n \t")).toBe(""); }); it("preserves a non-empty name untouched", () => { expect(displayContactName("Neville Benadé")).toBe("Neville Benadé"); expect(displayContactName("Swanepoel, Ms. Joey")).toBe("Swanepoel, Ms. Joey"); }); it("handles the real-world LLM trim case", () => { // The newlines are exactly what the n8n AI Agent has historically // returned (see docs/audit/order-pipeline-investigation-2026-08-20.md §3). expect(displayContactName("Nbenade\n")).toBe("Nbenade"); expect(displayContactName("N. Benade\n")).toBe("N. Benade"); expect(displayContactName("Drilling Technical Services (PTY) Ltd\n")).toBe( "Drilling Technical Services (PTY) Ltd", ); }); });