mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-05 07:12:06 +00:00
230 lines
6.4 KiB
TypeScript
230 lines
6.4 KiB
TypeScript
import { fireEvent, screen, waitFor } from "@testing-library/react";
|
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { VendorDialog } from "@/app/(protected)/workorders/_components/list/table/cells/vendor-dialog";
|
|
import type { Vendor } from "@/domain/vendors/types/vendor";
|
|
import type { VendorDropdownItem } from "@/domain/work-orders/types/work-order";
|
|
import { renderWithProviders } from "@/test/test-utils";
|
|
|
|
const mutateAsync = vi.fn();
|
|
|
|
vi.mock("@/domain/vendors/use-cases/use-create-vendor", () => ({
|
|
useCreateVendor: () => ({
|
|
mutateAsync,
|
|
isPending: false,
|
|
}),
|
|
}));
|
|
|
|
const existingVendor: VendorDropdownItem = {
|
|
id: 10,
|
|
companyName: "Gateway Plumbing",
|
|
contactName: "Jordan Lee",
|
|
tradeSpecialties: "Plumbing",
|
|
address: "1 Main St",
|
|
distanceMiles: 4.2,
|
|
email: "dispatch@gateway.test",
|
|
};
|
|
|
|
const createdVendor: Vendor = {
|
|
id: 99,
|
|
companyId: 10,
|
|
companyName: "Gateway Plumbing",
|
|
contactName: "Jordan Lee",
|
|
email: "dispatch@gateway.test",
|
|
phone: "(314) 555-9999",
|
|
companyPhone: "",
|
|
googleMapsUrl: "",
|
|
notes: "",
|
|
totalJobs: 0,
|
|
address: "1 Main St",
|
|
city: "",
|
|
state: "",
|
|
zip: "",
|
|
tradeSpecialties: "Plumbing",
|
|
isActive: true,
|
|
preferredContact: "Phone",
|
|
};
|
|
|
|
describe("VendorDialog stable technician identity", () => {
|
|
beforeEach(() => {
|
|
mutateAsync.mockReset();
|
|
mutateAsync.mockResolvedValue(createdVendor);
|
|
});
|
|
|
|
it("keeps draft identity on same-name collision and posts live phone on save", async () => {
|
|
const onSave = vi.fn();
|
|
const onOpenChange = vi.fn();
|
|
|
|
renderWithProviders(
|
|
<VendorDialog
|
|
open={true}
|
|
onOpenChange={onOpenChange}
|
|
vendorId={10}
|
|
company="Gateway Plumbing"
|
|
tech="Jordan Lee"
|
|
techPhone="(314) 555-0100"
|
|
vendors={[existingVendor]}
|
|
onSave={onSave}
|
|
/>,
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: /\+ add technician/i }));
|
|
fireEvent.change(screen.getByPlaceholderText("Full name"), {
|
|
target: { value: "Jordan Lee" },
|
|
});
|
|
fireEvent.change(screen.getByPlaceholderText("(000) 000-0000"), {
|
|
target: { value: "3145550199" },
|
|
});
|
|
fireEvent.click(screen.getByRole("button", { name: /^add$/i }));
|
|
|
|
// Draft stays staged: add form collapses and select still shows the colliding name.
|
|
expect(screen.getByRole("button", { name: /\+ add technician/i })).toBeTruthy();
|
|
expect(screen.getByRole("button", { name: "Jordan Lee" })).toBeTruthy();
|
|
|
|
fireEvent.change(screen.getByDisplayValue("3145550199"), {
|
|
target: { value: "(314) 555-9999" },
|
|
});
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: /^save$/i }));
|
|
|
|
await waitFor(() => {
|
|
expect(mutateAsync).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
expect(mutateAsync).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
contactName: "Jordan Lee",
|
|
companyName: "Gateway Plumbing",
|
|
phone: "(314) 555-9999",
|
|
}),
|
|
);
|
|
|
|
await waitFor(() => {
|
|
expect(onSave).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
vendorId: "99",
|
|
tech: "Jordan Lee",
|
|
company: "Gateway Plumbing",
|
|
techPhone: "(314) 555-9999",
|
|
}),
|
|
);
|
|
});
|
|
|
|
// Must not persist the pre-existing colliding vendor id.
|
|
expect(onSave.mock.calls[0]?.[0].vendorId).not.toBe("10");
|
|
});
|
|
|
|
it("does not clear staged draft when technicianOptions rebuild after add", async () => {
|
|
const onSave = vi.fn();
|
|
mutateAsync.mockResolvedValue({
|
|
...createdVendor,
|
|
id: 88,
|
|
contactName: "Casey New",
|
|
phone: "3145550188",
|
|
});
|
|
|
|
renderWithProviders(
|
|
<VendorDialog
|
|
open={true}
|
|
onOpenChange={vi.fn()}
|
|
vendorId={11}
|
|
company="Gateway Plumbing"
|
|
tech="Adam Whyte"
|
|
techPhone=""
|
|
vendors={[
|
|
existingVendor,
|
|
{
|
|
...existingVendor,
|
|
id: 11,
|
|
contactName: "Adam Whyte",
|
|
},
|
|
]}
|
|
onSave={onSave}
|
|
/>,
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: /\+ add technician/i }));
|
|
fireEvent.change(screen.getByPlaceholderText("Full name"), {
|
|
target: { value: "Casey New" },
|
|
});
|
|
fireEvent.change(screen.getByPlaceholderText("(000) 000-0000"), {
|
|
target: { value: "3145550188" },
|
|
});
|
|
fireEvent.click(screen.getByRole("button", { name: /^add$/i }));
|
|
|
|
expect(screen.getByRole("button", { name: "Casey New" })).toBeTruthy();
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: /^save$/i }));
|
|
|
|
await waitFor(() => {
|
|
expect(mutateAsync).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
expect(mutateAsync).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
contactName: "Casey New",
|
|
phone: "3145550188",
|
|
}),
|
|
);
|
|
|
|
await waitFor(() => {
|
|
expect(onSave).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
vendorId: "88",
|
|
tech: "Casey New",
|
|
}),
|
|
);
|
|
});
|
|
});
|
|
|
|
it("keeps a staged draft when the same company is picked again", async () => {
|
|
const onSave = vi.fn();
|
|
mutateAsync.mockResolvedValue({
|
|
...createdVendor,
|
|
id: 88,
|
|
contactName: "Casey New",
|
|
phone: "3145550188",
|
|
});
|
|
|
|
renderWithProviders(
|
|
<VendorDialog
|
|
open={true}
|
|
onOpenChange={vi.fn()}
|
|
vendorId={10}
|
|
company="Gateway Plumbing"
|
|
tech="Jordan Lee"
|
|
techPhone="(314) 555-0100"
|
|
vendors={[existingVendor]}
|
|
onSave={onSave}
|
|
/>,
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: /\+ add technician/i }));
|
|
fireEvent.change(screen.getByPlaceholderText("Full name"), {
|
|
target: { value: "Casey New" },
|
|
});
|
|
fireEvent.change(screen.getByPlaceholderText("(000) 000-0000"), {
|
|
target: { value: "3145550188" },
|
|
});
|
|
fireEvent.click(screen.getByRole("button", { name: /^add$/i }));
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: "Gateway Plumbing" }));
|
|
const companyButtons = await screen.findAllByRole("button", { name: "Gateway Plumbing" });
|
|
fireEvent.click(companyButtons[companyButtons.length - 1]!);
|
|
fireEvent.click(screen.getByRole("button", { name: /^save$/i }));
|
|
|
|
await waitFor(() => {
|
|
expect(mutateAsync).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
contactName: "Casey New",
|
|
phone: "3145550188",
|
|
}),
|
|
);
|
|
});
|
|
expect(onSave).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
vendorId: "88",
|
|
tech: "Casey New",
|
|
}),
|
|
);
|
|
});
|
|
});
|