shoc-frontend-new/src/test/app/(protected)/workorders/wizard-step-vendor-time-closability.test.tsx
Arthur Bassi 9cc9bc4dfb feat(work-orders): align inline lifecycle transitions with AAP
Use the prototype status list and gates on the board and wizard.
Auto-derive Scheduled or Pending from a concrete schedule date.
2026-09-02 15:11:31 -03:00

79 lines
2.9 KiB
TypeScript

import { fireEvent, render, screen, within } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import { WizardStepVendorTime } from "@/app/(protected)/workorders/_components/wizard/wizard-step-vendor-time";
import { EMPTY_WIZARD_DRAFT } from "@/domain/work-orders/types/work-order-wizard";
describe("WizardStepVendorTime Appt Time", () => {
it("marks Appt Time as optional", () => {
render(
<WizardStepVendorTime
draft={{ ...EMPTY_WIZARD_DRAFT, type: "PM", status: "Incomplete" }}
vendors={[]}
onUpdate={vi.fn()}
onPatch={vi.fn()}
/>,
);
expect(screen.getByText("Appt Time")).toBeInTheDocument();
expect(screen.getAllByText("optional").length).toBeGreaterThan(0);
});
});
describe("WizardStepVendorTime creation statuses (AAP)", () => {
it("offers only Incomplete, Pending, and Scheduled", () => {
render(
<WizardStepVendorTime
draft={{ ...EMPTY_WIZARD_DRAFT, type: "PM", status: "Incomplete" }}
vendors={[]}
onUpdate={vi.fn()}
onPatch={vi.fn()}
/>,
);
fireEvent.click(screen.getByRole("button", { name: /incomplete/i }));
expect(screen.getByRole("button", { name: /^pending$/i })).toBeInTheDocument();
expect(screen.getByRole("button", { name: /^scheduled$/i })).toBeInTheDocument();
expect(screen.queryByRole("button", { name: /^completed$/i })).not.toBeInTheDocument();
expect(screen.queryByRole("button", { name: /^en route$/i })).not.toBeInTheDocument();
});
it("disables Scheduled without a concrete date", () => {
const onUpdate = vi.fn();
render(
<WizardStepVendorTime
draft={{ ...EMPTY_WIZARD_DRAFT, type: "PM", status: "Incomplete" }}
vendors={[]}
onUpdate={onUpdate}
onPatch={vi.fn()}
/>,
);
fireEvent.click(screen.getByRole("button", { name: /incomplete/i }));
const scheduled = screen.getByRole("button", { name: /^scheduled$/i });
expect(scheduled).toBeDisabled();
expect(scheduled).toHaveAttribute(
"title",
"Set a Schedule On date before marking this work order as Scheduled.",
);
fireEvent.click(scheduled);
expect(onUpdate).not.toHaveBeenCalledWith("status", "Scheduled");
});
it("allows selecting a non-Completed status", () => {
const onUpdate = vi.fn();
render(
<WizardStepVendorTime
draft={{ ...EMPTY_WIZARD_DRAFT, type: "PM", status: "Incomplete" }}
vendors={[]}
onUpdate={onUpdate}
onPatch={vi.fn()}
/>,
);
fireEvent.click(screen.getByRole("button", { name: /incomplete/i }));
const menu = screen.getByRole("button", { name: /^pending$/i }).closest("div");
expect(menu).not.toBeNull();
fireEvent.click(within(menu!.parentElement!).getByRole("button", { name: /^pending$/i }));
expect(onUpdate).toHaveBeenCalledWith("status", "Pending");
});
});