2026-07-17 12:02:05 -03:00
|
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
|
import { mapWizardDraftToFormValues } from "@/domain/work-orders/mappers/wizard-draft-mapper";
|
|
|
|
|
import {
|
|
|
|
|
EMPTY_WIZARD_DRAFT,
|
|
|
|
|
canContinueWizardStep1,
|
|
|
|
|
canCreateWorkOrderFromWizard,
|
|
|
|
|
isWizardStepValid,
|
|
|
|
|
} 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("blocks step 1 continue without type", () => {
|
|
|
|
|
expect(canContinueWizardStep1(EMPTY_WIZARD_DRAFT)).toBe(false);
|
|
|
|
|
expect(isWizardStepValid(1, EMPTY_WIZARD_DRAFT)).toBe(false);
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-17 10:45:59 -03:00
|
|
|
it("allows step 1 when type is set without woNumber", () => {
|
2026-07-17 12:02:05 -03:00
|
|
|
const draft = { ...EMPTY_WIZARD_DRAFT, type: "PM" as const };
|
|
|
|
|
expect(canContinueWizardStep1(draft)).toBe(true);
|
|
|
|
|
expect(isWizardStepValid(1, draft)).toBe(true);
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-17 10:45:59 -03:00
|
|
|
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 create without siteCode", () => {
|
|
|
|
|
const draft = {
|
|
|
|
|
...EMPTY_WIZARD_DRAFT,
|
|
|
|
|
type: "PM" as const,
|
|
|
|
|
woNumber: "12345",
|
|
|
|
|
locationId: "99",
|
|
|
|
|
};
|
2026-07-17 12:02:05 -03:00
|
|
|
expect(canCreateWorkOrderFromWizard(draft)).toBe(false);
|
|
|
|
|
expect(isWizardStepValid(2, draft)).toBe(false);
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-17 10:45:59 -03:00
|
|
|
it("allows create when type and siteCode are set (woNumber optional)", () => {
|
|
|
|
|
const draft = {
|
|
|
|
|
...EMPTY_WIZARD_DRAFT,
|
|
|
|
|
type: "PM" as const,
|
|
|
|
|
locationId: "99",
|
|
|
|
|
siteCode: "BK5",
|
|
|
|
|
};
|
|
|
|
|
expect(canCreateWorkOrderFromWizard(draft)).toBe(true);
|
|
|
|
|
expect(isWizardStepValid(2, draft)).toBe(true);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("allows create when type, woNumber, and siteCode are set", () => {
|
2026-07-17 12:02:05 -03:00
|
|
|
const draft = {
|
|
|
|
|
...EMPTY_WIZARD_DRAFT,
|
|
|
|
|
type: "PM" as const,
|
2026-07-17 10:45:59 -03:00
|
|
|
woNumber: "12345678901234567890",
|
2026-07-17 12:02:05 -03:00
|
|
|
locationId: "99",
|
2026-07-17 10:45:59 -03:00
|
|
|
siteCode: "BK5",
|
2026-07-17 12:02:05 -03:00
|
|
|
};
|
|
|
|
|
expect(canCreateWorkOrderFromWizard(draft)).toBe(true);
|
|
|
|
|
expect(isWizardStepValid(2, draft)).toBe(true);
|
|
|
|
|
});
|
2026-07-17 10:45:59 -03:00
|
|
|
|
|
|
|
|
it("allows step 1 when woNumber is empty", () => {
|
|
|
|
|
const draft = {
|
|
|
|
|
...EMPTY_WIZARD_DRAFT,
|
|
|
|
|
type: "PM" as const,
|
|
|
|
|
woNumber: "",
|
|
|
|
|
};
|
|
|
|
|
expect(canContinueWizardStep1(draft)).toBe(true);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("blocks step 1 when woNumber is non-numeric", () => {
|
|
|
|
|
const draft = {
|
|
|
|
|
...EMPTY_WIZARD_DRAFT,
|
|
|
|
|
type: "PM" as const,
|
|
|
|
|
woNumber: "abc",
|
|
|
|
|
};
|
|
|
|
|
expect(canContinueWizardStep1(draft)).toBe(false);
|
|
|
|
|
});
|
2026-07-17 12:02:05 -03:00
|
|
|
});
|