shoc-frontend-new/src/test/app/(protected)/workorders/new-wo-wizard-duplicate.test.tsx

92 lines
2.9 KiB
TypeScript
Raw Normal View History

feat(work-orders): duplicate WO number dialog on table and wizard (SH-189) (#90) * docs(work-orders): add pending BE contract checklist for design parity gaps * feat(work-orders): confirm dialog when duplicate wo number detected * fix(work-orders): show duplicate wo number dialog on wizard create * docs(work-orders): align pr description with jira and qa residuals * style(work-orders): prettier wizard duplicate dialog files * refactor(workorders): extract wizard state hook and list overlays * fix(work-orders): check duplicate numbers globally * fix(work-orders): exhaust fuzzy pages for exact WO number lookup Prevent accepting duplicates that fall outside the first fuzzy search page. * style(work-orders): format editable WO number cell for Prettier gate * fix(work-orders): 0-based WO search page and stale duplicate guard * fix(work-orders): sync draft WO# ref in effect for duplicate guard [SH-189] * fix(work-orders): extract WO number editor under max-lines gate Co-authored-by: Cursor <cursoragent@cursor.com> * fix(work-orders): harden duplicate WO number checks [SH-189] * fix(work-orders): sync wizard refs in effects and exhaust duplicate WO lookup Co-authored-by: Cursor <cursoragent@cursor.com> * fix(work-orders): extract hooks to satisfy max-lines governance gate Co-authored-by: Cursor <cursoragent@cursor.com> * style(work-orders): format wizard state hook for Prettier gate Co-authored-by: Cursor <cursoragent@cursor.com> * fix(work-orders): search one-character WO numbers for duplicates --------- Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-13 11:04:48 -03:00
import { fireEvent, screen, waitFor } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import { NewWoWizard } from "@/app/(protected)/workorders/_components/wizard/new-wo-wizard";
import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row";
import { renderWithProviders } from "@/test/test-utils";
const existingRow = { id: "wo-99", woNumber: "12345678901" } as WorkOrderTableRow;
const findByWoNumber = vi.fn();
vi.mock("@/domain/work-orders/use-cases/use-create-work-order-from-wizard", () => ({
useCreateWorkOrderFromWizard: () => ({
mutate: vi.fn(),
isPending: false,
}),
}));
vi.mock("@/domain/work-orders/use-cases/use-work-order-detail", () => ({
useWorkOrderVendors: () => ({ data: [] }),
}));
vi.mock("@/domain/locations/use-cases/use-location-sites", () => ({
useLocationSites: () => ({ data: [] }),
}));
feat(work-orders): duplicate WO number dialog on table and wizard (SH-189) (#90) * docs(work-orders): add pending BE contract checklist for design parity gaps * feat(work-orders): confirm dialog when duplicate wo number detected * fix(work-orders): show duplicate wo number dialog on wizard create * docs(work-orders): align pr description with jira and qa residuals * style(work-orders): prettier wizard duplicate dialog files * refactor(workorders): extract wizard state hook and list overlays * fix(work-orders): check duplicate numbers globally * fix(work-orders): exhaust fuzzy pages for exact WO number lookup Prevent accepting duplicates that fall outside the first fuzzy search page. * style(work-orders): format editable WO number cell for Prettier gate * fix(work-orders): 0-based WO search page and stale duplicate guard * fix(work-orders): sync draft WO# ref in effect for duplicate guard [SH-189] * fix(work-orders): extract WO number editor under max-lines gate Co-authored-by: Cursor <cursoragent@cursor.com> * fix(work-orders): harden duplicate WO number checks [SH-189] * fix(work-orders): sync wizard refs in effects and exhaust duplicate WO lookup Co-authored-by: Cursor <cursoragent@cursor.com> * fix(work-orders): extract hooks to satisfy max-lines governance gate Co-authored-by: Cursor <cursoragent@cursor.com> * style(work-orders): format wizard state hook for Prettier gate Co-authored-by: Cursor <cursoragent@cursor.com> * fix(work-orders): search one-character WO numbers for duplicates --------- Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-13 11:04:48 -03:00
vi.mock("@/domain/locations/use-cases/use-location-detail", () => ({
useLocationDetail: () => ({ data: undefined }),
}));
vi.mock("@/domain/settings/dropdown-options/use-cases/use-dropdown-options-by-category", () => ({
useDropdownOptionsByCategory: () => ({ data: [] }),
}));
vi.mock("@/domain/work-orders/api/work-orders-api", () => ({
workOrdersApi: {
findByWoNumber: (...args: unknown[]) => findByWoNumber(...args),
},
}));
describe("NewWoWizard duplicate wo number", () => {
it("shows the duplicate dialog when the wizard wo number matches an existing row", async () => {
renderWithProviders(
<NewWoWizard
open
onOpenChange={vi.fn()}
users={[]}
existingRows={[existingRow]}
onViewExistingWo={vi.fn()}
/>,
);
const woNumberInput = screen.getByPlaceholderText("Leave blank for SH provisional number");
feat(work-orders): duplicate WO number dialog on table and wizard (SH-189) (#90) * docs(work-orders): add pending BE contract checklist for design parity gaps * feat(work-orders): confirm dialog when duplicate wo number detected * fix(work-orders): show duplicate wo number dialog on wizard create * docs(work-orders): align pr description with jira and qa residuals * style(work-orders): prettier wizard duplicate dialog files * refactor(workorders): extract wizard state hook and list overlays * fix(work-orders): check duplicate numbers globally * fix(work-orders): exhaust fuzzy pages for exact WO number lookup Prevent accepting duplicates that fall outside the first fuzzy search page. * style(work-orders): format editable WO number cell for Prettier gate * fix(work-orders): 0-based WO search page and stale duplicate guard * fix(work-orders): sync draft WO# ref in effect for duplicate guard [SH-189] * fix(work-orders): extract WO number editor under max-lines gate Co-authored-by: Cursor <cursoragent@cursor.com> * fix(work-orders): harden duplicate WO number checks [SH-189] * fix(work-orders): sync wizard refs in effects and exhaust duplicate WO lookup Co-authored-by: Cursor <cursoragent@cursor.com> * fix(work-orders): extract hooks to satisfy max-lines governance gate Co-authored-by: Cursor <cursoragent@cursor.com> * style(work-orders): format wizard state hook for Prettier gate Co-authored-by: Cursor <cursoragent@cursor.com> * fix(work-orders): search one-character WO numbers for duplicates --------- Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-13 11:04:48 -03:00
fireEvent.change(woNumberInput, {
target: { value: "12345678901" },
});
fireEvent.blur(woNumberInput);
await waitFor(() => {
expect(screen.getByText("Duplicate Work Order Number")).toBeInTheDocument();
});
expect(screen.getByText(/is already assigned to another work order/i)).toBeInTheDocument();
});
it("finds a duplicate outside the loaded board rows", async () => {
const offPageRow = {
id: "wo-off-page",
woNumber: "98765432109",
} as WorkOrderTableRow;
findByWoNumber.mockResolvedValueOnce(offPageRow);
renderWithProviders(
<NewWoWizard
open
onOpenChange={vi.fn()}
users={[]}
existingRows={[]}
onViewExistingWo={vi.fn()}
/>,
);
const woNumberInput = screen.getByPlaceholderText("Leave blank for SH provisional number");
feat(work-orders): duplicate WO number dialog on table and wizard (SH-189) (#90) * docs(work-orders): add pending BE contract checklist for design parity gaps * feat(work-orders): confirm dialog when duplicate wo number detected * fix(work-orders): show duplicate wo number dialog on wizard create * docs(work-orders): align pr description with jira and qa residuals * style(work-orders): prettier wizard duplicate dialog files * refactor(workorders): extract wizard state hook and list overlays * fix(work-orders): check duplicate numbers globally * fix(work-orders): exhaust fuzzy pages for exact WO number lookup Prevent accepting duplicates that fall outside the first fuzzy search page. * style(work-orders): format editable WO number cell for Prettier gate * fix(work-orders): 0-based WO search page and stale duplicate guard * fix(work-orders): sync draft WO# ref in effect for duplicate guard [SH-189] * fix(work-orders): extract WO number editor under max-lines gate Co-authored-by: Cursor <cursoragent@cursor.com> * fix(work-orders): harden duplicate WO number checks [SH-189] * fix(work-orders): sync wizard refs in effects and exhaust duplicate WO lookup Co-authored-by: Cursor <cursoragent@cursor.com> * fix(work-orders): extract hooks to satisfy max-lines governance gate Co-authored-by: Cursor <cursoragent@cursor.com> * style(work-orders): format wizard state hook for Prettier gate Co-authored-by: Cursor <cursoragent@cursor.com> * fix(work-orders): search one-character WO numbers for duplicates --------- Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-13 11:04:48 -03:00
fireEvent.change(woNumberInput, {
target: { value: "98765432109" },
});
fireEvent.blur(woNumberInput);
await waitFor(() => {
expect(screen.getByText("Duplicate Work Order Number")).toBeInTheDocument();
});
expect(findByWoNumber).toHaveBeenCalledWith("98765432109");
});
});