mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-04 09:02:05 +00:00
The inline status control no longer offers the automatic Incomplete and Scheduled states or the work order's current status. Inline create keeps its explicit Incomplete/Pending/Scheduled creation list.
119 lines
4 KiB
TypeScript
119 lines
4 KiB
TypeScript
import { fireEvent, render, screen } from "@testing-library/react";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
import { StatusCell } from "@/app/(protected)/workorders/_components/list/table/cells/status-cell";
|
|
import type { WizardWOStatus } from "@/domain/work-orders/types/work-order-wizard";
|
|
import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row";
|
|
|
|
const incompleteRow = {
|
|
id: "wo-1",
|
|
status: "Scheduled",
|
|
dispatcherId: "",
|
|
dispatcherName: "",
|
|
company: "",
|
|
vendorId: "",
|
|
tech: "",
|
|
completedDate: "",
|
|
woNumber: "",
|
|
pm: "",
|
|
docStatus: "",
|
|
mediaCount: 0,
|
|
type: "PM",
|
|
} as WorkOrderTableRow;
|
|
|
|
describe("StatusCell closability gate", () => {
|
|
it("does not submit Completed when required work-order data is missing", () => {
|
|
const onChangeStatus = vi.fn();
|
|
|
|
render(
|
|
<StatusCell wo={incompleteRow} onChangeStatus={onChangeStatus} onOpenSlideOver={vi.fn()} />,
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: /scheduled/i }));
|
|
const completed = screen.getByRole("button", { name: /^completed$/i });
|
|
|
|
expect(completed.hasAttribute("disabled")).toBe(true);
|
|
expect(completed.getAttribute("title") ?? "").toContain("Fill in");
|
|
fireEvent.click(completed);
|
|
expect(onChangeStatus).not.toHaveBeenCalledWith("Completed");
|
|
});
|
|
|
|
it("does not offer Canceled", () => {
|
|
render(<StatusCell wo={incompleteRow} onChangeStatus={vi.fn()} onOpenSlideOver={vi.fn()} />);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: /scheduled/i }));
|
|
expect(screen.queryByRole("button", { name: /^canceled$/i })).toBeNull();
|
|
});
|
|
|
|
it.each<WizardWOStatus>([
|
|
"Pending",
|
|
"En Route",
|
|
"On Site",
|
|
"In Progress",
|
|
"Rescheduled",
|
|
"Pending Quote",
|
|
])("offers only manual transitions away from %s (SH-357, SH-358)", (current) => {
|
|
const onChangeStatus = vi.fn();
|
|
render(
|
|
<StatusCell
|
|
wo={{ ...incompleteRow, status: current, scheduledOn: "2026-06-01" }}
|
|
onChangeStatus={onChangeStatus}
|
|
onOpenSlideOver={vi.fn()}
|
|
/>,
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: new RegExp(current, "i") }));
|
|
const offered = Array.from(document.querySelectorAll(".MuiPopover-paper button")).map(
|
|
(button) => button.textContent?.trim(),
|
|
);
|
|
|
|
expect(offered).not.toContain("Incomplete");
|
|
expect(offered).not.toContain("Scheduled");
|
|
expect(offered).not.toContain("Past Due");
|
|
expect(offered).not.toContain("Canceled");
|
|
expect(offered).not.toContain(current);
|
|
expect(offered).toEqual(
|
|
[
|
|
"Pending",
|
|
"En Route",
|
|
"On Site",
|
|
"In Progress",
|
|
"Completed",
|
|
"Rescheduled",
|
|
"Pending Quote",
|
|
].filter((status) => status !== current),
|
|
);
|
|
});
|
|
|
|
it("offers every manual status, and no automatic one, from Incomplete or Scheduled", () => {
|
|
for (const current of ["Incomplete", "Scheduled"] as const) {
|
|
const { unmount } = render(
|
|
<StatusCell
|
|
wo={{ ...incompleteRow, status: current }}
|
|
onChangeStatus={vi.fn()}
|
|
onOpenSlideOver={vi.fn()}
|
|
/>,
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: new RegExp(current, "i") }));
|
|
expect(screen.getByRole("button", { name: /^pending$/i })).toBeTruthy();
|
|
expect(screen.queryByRole("button", { name: /^incomplete$/i })).toBeNull();
|
|
expect(screen.queryByRole("button", { name: /^scheduled$/i })).toBeNull();
|
|
unmount();
|
|
}
|
|
});
|
|
|
|
it("limits creation options to Incomplete, Pending, and Scheduled", () => {
|
|
render(
|
|
<StatusCell
|
|
wo={{ ...incompleteRow, status: "Incomplete" }}
|
|
statusOptions={["Incomplete", "Pending", "Scheduled"]}
|
|
onChangeStatus={vi.fn()}
|
|
onOpenSlideOver={vi.fn()}
|
|
/>,
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: /incomplete/i }));
|
|
expect(screen.getByRole("button", { name: /^pending$/i })).toBeTruthy();
|
|
expect(screen.queryByRole("button", { name: /^en route$/i })).toBeNull();
|
|
});
|
|
});
|