shoc-frontend-new/src/test/domain/work-orders/mappers/wizard-draft-mapper.test.ts
Arthur Bassi b4cb9d0288
Some checks failed
CI / ci (push) Has been cancelled
CI / governance (push) Has been cancelled
CI / vendor-visual-regression (push) Has been cancelled
Deploy / deploy (push) Has been cancelled
feat(work-orders): severity gates and wizard type/WO# parity (SH-192) (#106)
* fix(work-orders): allow blank WO number in wizard create path

[recover] remove malicious eslint payload (was d0d08508)

* fix(work-orders): emit severity before type in board scalar PATCH ops

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore(work-orders): drop vendor collateral from SH-192 lane

* fix(work-orders): add severity to unscheduled highlight fixture after dev merge

* refactor(work-orders): extract inline type/severity cell under function line cap

* fix(work-orders): add severity to comp-doc and media fixtures after dev merge

PR #45 introduced completion-doc, media and table-mutation fixtures that predate the required severity field, so the integrated head failed tsc. Fill severity on those row builders (null for PM, SEV 1 for the Emergency fixture) and type the mutation BASE_ROW instead of asserting it.

* test(work-orders): align merge fixes with severity field and WO# placeholder

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Arthur Bassi <bassi-arthurr@users.noreply.github.com>
Co-authored-by: Alexandre Brandizzi <alex_brandizzi@hotmail.com>
2026-08-14 11:59:52 -03:00

201 lines
6 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { mapWizardDraftToFormValues } from "@/domain/work-orders/mappers/wizard-draft-mapper";
import {
EMPTY_WIZARD_DRAFT,
canContinueWizardStep1,
canContinueWizardStep2,
canCreateWorkOrderFromWizard,
isWizardStepValid,
isWizardWoNumberValid,
} from "@/domain/work-orders/types/work-order-wizard";
describe("mapWizardDraftToFormValues", () => {
it("maps minimal draft with type and site to valid form values", () => {
const draft = {
...EMPTY_WIZARD_DRAFT,
type: "PM" as const,
locationId: "42",
locationName: "DFW8 · Dallas, TX",
woNumber: "24818",
assigneeName: "Sarah Chen",
status: "Incomplete" as const,
};
const values = mapWizardDraftToFormValues(draft);
expect(values.title).toBe("PM — #24818");
expect(values.workOrderNumber).toBe("24818");
expect(values.locationId).toBe("42");
expect(values.assignedTo).toBe("Sarah Chen");
expect(values.status).toBe("Open");
expect(values.priority).toBe("Sev 3");
expect(values.source).toBe("PM");
expect(values.createdDate).toMatch(/^\d{4}-\d{2}-\d{2}$/);
});
it("maps emergency type to Sev 1 priority", () => {
const values = mapWizardDraftToFormValues({
...EMPTY_WIZARD_DRAFT,
type: "Emergency",
locationId: "1",
locationName: "Site A",
});
expect(values.priority).toBe("Sev 1");
expect(values.title).toBe("Emergency — Site A");
});
it("includes appointment and notes in description", () => {
const values = mapWizardDraftToFormValues({
...EMPTY_WIZARD_DRAFT,
type: "Reactive",
locationId: "1",
locationName: "Site A",
apptStart: "09:00",
apptEnd: "11:00",
pocNotes: "Call ahead",
vendorName: "Roto-Rooter",
vendorNotes: "Prefers morning",
});
expect(values.description).toContain("Appt:");
expect(values.description).toContain("POC notes: Call ahead");
expect(values.description).toContain("Vendor: Roto-Rooter");
});
});
describe("wizard step validation", () => {
it("allows step 1 continue without a woNumber for backend SH generation", () => {
expect(canContinueWizardStep1(EMPTY_WIZARD_DRAFT)).toBe(true);
expect(isWizardStepValid(1, EMPTY_WIZARD_DRAFT)).toBe(true);
});
it("allows step 1 without type when woNumber is set (type defaults to PM)", () => {
const draft = { ...EMPTY_WIZARD_DRAFT, woNumber: "12345" };
expect(canContinueWizardStep1(draft)).toBe(true);
expect(isWizardStepValid(1, draft)).toBe(true);
});
it("allows step 1 when woNumber is missing even with type", () => {
const draft = { ...EMPTY_WIZARD_DRAFT, type: "PM" as const };
expect(canContinueWizardStep1(draft)).toBe(true);
expect(isWizardStepValid(1, draft)).toBe(true);
});
it("allows step 1 when type and woNumber are set (schedule optional)", () => {
const draft = {
...EMPTY_WIZARD_DRAFT,
type: "PM" as const,
woNumber: "12345",
};
expect(canContinueWizardStep1(draft)).toBe(true);
expect(isWizardStepValid(1, draft)).toBe(true);
});
it("blocks step 1 for Emergency without severity", () => {
const draft = {
...EMPTY_WIZARD_DRAFT,
type: "Emergency" as const,
woNumber: "12345",
};
expect(canContinueWizardStep1(draft)).toBe(false);
});
it("allows step 1 for Emergency with severity", () => {
const draft = {
...EMPTY_WIZARD_DRAFT,
type: "Emergency" as const,
woNumber: "12345",
severity: 2 as const,
};
expect(canContinueWizardStep1(draft)).toBe(true);
});
it("blocks step 2 without POC name/phone", () => {
const draft = {
...EMPTY_WIZARD_DRAFT,
type: "PM" as const,
woNumber: "12345",
locationId: "99",
siteCode: "BK5",
};
expect(canContinueWizardStep2(draft)).toBe(false);
expect(isWizardStepValid(2, draft)).toBe(false);
});
it("allows step 2 when site and POC are set", () => {
const draft = {
...EMPTY_WIZARD_DRAFT,
type: "PM" as const,
woNumber: "12345",
locationId: "99",
siteCode: "BK5",
pocName: "Jordan",
pocPhone: "555-0100",
};
expect(canContinueWizardStep2(draft)).toBe(true);
expect(isWizardStepValid(2, draft)).toBe(true);
});
it("blocks create without siteCode", () => {
const draft = {
...EMPTY_WIZARD_DRAFT,
type: "PM" as const,
woNumber: "12345",
locationId: "99",
};
expect(canCreateWorkOrderFromWizard(draft)).toBe(false);
expect(isWizardStepValid(2, draft)).toBe(false);
});
it("allows create when type, woNumber, site, and POC are set", () => {
const draft = {
...EMPTY_WIZARD_DRAFT,
type: "PM" as const,
woNumber: "12345678901234567890",
locationId: "99",
siteCode: "BK5",
pocName: "Jordan",
pocPhone: "555-0100",
};
expect(canCreateWorkOrderFromWizard(draft)).toBe(true);
expect(isWizardStepValid(2, draft)).toBe(true);
});
it("allows provisional SH-prefixed woNumber", () => {
const draft = {
...EMPTY_WIZARD_DRAFT,
woNumber: "SH12345",
};
expect(canContinueWizardStep1(draft)).toBe(true);
});
it("accepts blank woNumber for backend SH generation", () => {
const draft = {
...EMPTY_WIZARD_DRAFT,
type: "PM" as const,
woNumber: "",
};
expect(isWizardWoNumberValid(draft.woNumber)).toBe(true);
expect(canContinueWizardStep1(draft)).toBe(true);
});
it("accepts whitespace-only woNumber for backend SH generation", () => {
const draft = {
...EMPTY_WIZARD_DRAFT,
type: "PM" as const,
woNumber: " ",
};
expect(isWizardWoNumberValid(draft.woNumber)).toBe(true);
expect(canContinueWizardStep1(draft)).toBe(true);
});
it("rejects non-alphanumeric woNumber", () => {
expect(isWizardWoNumberValid("!!!")).toBe(false);
expect(canContinueWizardStep1({ ...EMPTY_WIZARD_DRAFT, woNumber: "!!!" })).toBe(false);
});
it("accepts alphanumeric woNumber", () => {
expect(isWizardWoNumberValid("ABC123")).toBe(true);
});
});