import { fireEvent, screen, waitFor } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; import { VendorDialog } from "@/app/(protected)/workorders/_components/list/table/cells/vendor-dialog"; import type { VendorDropdownItem } from "@/domain/work-orders/types/work-order"; import { renderWithProviders } from "@/test/test-utils"; vi.mock("@/domain/vendors/use-cases/use-create-vendor", () => ({ useCreateVendor: () => ({ mutateAsync: vi.fn(), isPending: false, }), })); const jordan: VendorDropdownItem = { id: 10, companyName: "Gateway Plumbing", contactName: "Jordan Lee", tradeSpecialties: "Plumbing", address: "1 Main St", distanceMiles: 4.2, email: "dispatch@gateway.test", }; const casey: VendorDropdownItem = { ...jordan, id: 11, contactName: "Casey New", }; const avery: VendorDropdownItem = { ...jordan, id: 12, companyName: "Coastal HVAC", contactName: "Avery Chen", tradeSpecialties: "HVAC", }; function renderAssigned(onSave = vi.fn()) { renderWithProviders( , ); return onSave; } describe("VendorDialog save gate", () => { it("does not persist when the empty modal is saved unchanged", () => { const onSave = vi.fn(); renderWithProviders( , ); expect(screen.getByRole("button", { name: /pick a company first/i })).toBeDisabled(); const save = screen.getByRole("button", { name: /^save$/i }); expect(save).not.toBeDisabled(); expect(save).toHaveAttribute("aria-disabled", "true"); expect(save).toHaveStyle({ opacity: "0.5", cursor: "not-allowed" }); fireEvent.click(save); expect(onSave).not.toHaveBeenCalled(); }); it("does not persist when an existing assignment is saved unchanged", () => { const onSave = renderAssigned(); fireEvent.click(screen.getByRole("button", { name: /^save$/i })); expect(onSave).not.toHaveBeenCalled(); }); it("persists after the selected technician changes", async () => { const onSave = renderAssigned(); fireEvent.click(screen.getByRole("button", { name: /jordan lee/i })); fireEvent.click(await screen.findByRole("button", { name: /casey new/i })); fireEvent.click(screen.getByRole("button", { name: /^save$/i })); await waitFor(() => { expect(onSave).toHaveBeenCalledWith( expect.objectContaining({ vendorId: "11", tech: "Casey New", company: "Gateway Plumbing", }), ); }); }); it("persists a company-only assignment without selecting a technician", async () => { const onSave = vi.fn(); renderWithProviders( , ); fireEvent.click(screen.getByRole("button", { name: /select company/i })); fireEvent.click(await screen.findByRole("button", { name: "Gateway Plumbing" })); fireEvent.click(screen.getByRole("button", { name: /^save$/i })); expect(onSave).toHaveBeenCalledWith( expect.objectContaining({ vendorId: "10", company: "Gateway Plumbing", tech: "", techPhone: "", }), ); }); it("only offers technicians from the selected company", async () => { renderWithProviders( , ); fireEvent.click(screen.getByRole("button", { name: /select company/i })); fireEvent.click(await screen.findByRole("button", { name: "Coastal HVAC" })); fireEvent.click(screen.getByRole("button", { name: /select technician/i })); expect(await screen.findByRole("button", { name: "Avery Chen" })).toBeInTheDocument(); expect(screen.queryByRole("button", { name: "Jordan Lee" })).not.toBeInTheDocument(); expect(screen.queryByRole("button", { name: "Casey New" })).not.toBeInTheDocument(); }); it("does not persist after a notes-only change", () => { const onSave = renderAssigned(); fireEvent.change(screen.getByPlaceholderText("Contact preferences, availability, etc."), { target: { value: "Gate code 12" }, }); fireEvent.click(screen.getByRole("button", { name: /^save$/i })); expect(onSave).not.toHaveBeenCalled(); }); });