shoc-frontend-new/src/test/app/(protected)/workorders/vendor-dialog-save-gate.test.tsx

159 lines
4.7 KiB
TypeScript

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-add-technicians-to-company", () => ({
useAddTechniciansToCompany: () => ({
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(
<VendorDialog
open
onOpenChange={vi.fn()}
vendorId={10}
company="Gateway Plumbing"
tech="Jordan Lee"
techPhone="(314) 555-0100"
vendors={[jordan, casey]}
onSave={onSave}
/>,
);
return onSave;
}
describe("VendorDialog save gate", () => {
it("does not persist when the empty modal is saved unchanged", () => {
const onSave = vi.fn();
renderWithProviders(
<VendorDialog
open
onOpenChange={vi.fn()}
vendorId=""
company=""
tech=""
vendors={[]}
onSave={onSave}
/>,
);
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(
<VendorDialog
open
onOpenChange={vi.fn()}
vendorId=""
company=""
tech=""
vendors={[jordan, casey]}
onSave={onSave}
/>,
);
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(
<VendorDialog
open
onOpenChange={vi.fn()}
vendorId=""
company=""
tech=""
vendors={[jordan, casey, avery]}
onSave={vi.fn()}
/>,
);
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();
});
});