mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-07 16:19:01 +00:00
205 lines
6.8 KiB
TypeScript
205 lines
6.8 KiB
TypeScript
import { screen } from "@testing-library/react";
|
|
import userEvent from "@testing-library/user-event";
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
import { useForm, useWatch, type FieldErrors } from "react-hook-form";
|
|
import { describe, expect, it } from "vitest";
|
|
import { VendorFormFields } from "@/app/(protected)/vendors/_components/vendor-form-fields";
|
|
import { vendorSchema, type VendorFormValues } from "@/domain/vendors/schemas/vendor-schema";
|
|
import type { VendorFacetCompany } from "@/domain/vendors/types/vendor";
|
|
import { renderWithProviders } from "@/test/test-utils";
|
|
|
|
const companies: VendorFacetCompany[] = [
|
|
{
|
|
companyId: "co-1",
|
|
name: "Gateway Plumbing",
|
|
companyPhone: "(314) 555-0198",
|
|
email: "dispatch@gatewayplumbing.com",
|
|
address: "1 Main St",
|
|
city: "St. Louis",
|
|
state: "MO",
|
|
zip: "63101",
|
|
googleMapsUrl: "https://maps.google.com/gateway",
|
|
},
|
|
];
|
|
|
|
const emptyForm: VendorFormValues = {
|
|
companyName: "",
|
|
contactName: "Tech Person",
|
|
email: "",
|
|
phone: "",
|
|
companyPhone: "",
|
|
googleMapsUrl: "",
|
|
notes: "",
|
|
totalJobs: 0,
|
|
address: "",
|
|
city: "",
|
|
state: "",
|
|
zip: "",
|
|
tradeSpecialties: "",
|
|
isActive: true,
|
|
companyId: null,
|
|
preferredContact: "Phone",
|
|
};
|
|
|
|
function Harness({
|
|
defaultValues,
|
|
resetTarget,
|
|
}: {
|
|
defaultValues: VendorFormValues;
|
|
resetTarget: VendorFormValues;
|
|
}) {
|
|
const { control, reset, setValue } = useForm<VendorFormValues>({
|
|
resolver: zodResolver(vendorSchema),
|
|
defaultValues,
|
|
});
|
|
|
|
const onCompanySelected = (company: VendorFacetCompany | null) => {
|
|
if (!company) return;
|
|
setValue("companyId", company.companyId);
|
|
setValue("companyPhone", company.companyPhone);
|
|
setValue("email", company.email);
|
|
setValue("address", company.address);
|
|
setValue("city", company.city);
|
|
setValue("state", company.state);
|
|
setValue("zip", company.zip);
|
|
setValue("googleMapsUrl", company.googleMapsUrl);
|
|
};
|
|
|
|
const companyId = useWatch({ control, name: "companyId" });
|
|
|
|
return (
|
|
<>
|
|
<VendorFormFields
|
|
control={control}
|
|
errors={{} as FieldErrors<VendorFormValues>}
|
|
companies={companies}
|
|
tradeOptions={[]}
|
|
onCompanySelected={onCompanySelected}
|
|
/>
|
|
<output data-testid="company-id">{String(companyId ?? "")}</output>
|
|
<button type="button" onClick={() => reset(resetTarget)}>
|
|
reset-form
|
|
</button>
|
|
</>
|
|
);
|
|
}
|
|
|
|
const companyField = () => screen.getByRole("combobox", { name: "Company" }) as HTMLInputElement;
|
|
const companyIdOutput = () => screen.getByTestId("company-id");
|
|
|
|
describe("VendorFormFields company autocomplete state", () => {
|
|
it("clears a previously typed company when the form is reset (create-form reopen)", async () => {
|
|
renderWithProviders(<Harness defaultValues={emptyForm} resetTarget={emptyForm} />, {
|
|
withAuth: false,
|
|
});
|
|
|
|
await userEvent.type(companyField(), "Leftover Co");
|
|
expect(companyField()).toHaveValue("Leftover Co");
|
|
|
|
await userEvent.click(screen.getByRole("button", { name: "reset-form" }));
|
|
|
|
expect(companyField()).toHaveValue("");
|
|
});
|
|
|
|
it("shows the switched company value instead of previously typed text when the form is reset", async () => {
|
|
renderWithProviders(
|
|
<Harness
|
|
defaultValues={emptyForm}
|
|
resetTarget={{ ...emptyForm, companyName: "Beta LLC", contactName: "Other Tech" }}
|
|
/>,
|
|
{ withAuth: false },
|
|
);
|
|
|
|
await userEvent.type(companyField(), "Acme");
|
|
expect(companyField()).toHaveValue("Acme");
|
|
|
|
await userEvent.click(screen.getByRole("button", { name: "reset-form" }));
|
|
|
|
expect(companyField()).toHaveValue("Beta LLC");
|
|
});
|
|
|
|
it("reflects the company provided by an external reset even when nothing was typed", async () => {
|
|
renderWithProviders(
|
|
<Harness
|
|
defaultValues={{ ...emptyForm, companyName: "Acme Corp" }}
|
|
resetTarget={{ ...emptyForm, companyName: "Beta LLC" }}
|
|
/>,
|
|
{ withAuth: false },
|
|
);
|
|
|
|
expect(companyField()).toHaveValue("Acme Corp");
|
|
|
|
await userEvent.click(screen.getByRole("button", { name: "reset-form" }));
|
|
|
|
expect(companyField()).toHaveValue("Beta LLC");
|
|
});
|
|
|
|
it("updates the displayed company as the user types (freeSolo)", async () => {
|
|
renderWithProviders(<Harness defaultValues={emptyForm} resetTarget={emptyForm} />, {
|
|
withAuth: false,
|
|
});
|
|
|
|
await userEvent.type(companyField(), "Acme");
|
|
|
|
expect(companyField()).toHaveValue("Acme");
|
|
});
|
|
|
|
it("selects a company option, autofills company details, and shows the company name", async () => {
|
|
renderWithProviders(<Harness defaultValues={emptyForm} resetTarget={emptyForm} />, {
|
|
withAuth: false,
|
|
});
|
|
|
|
await userEvent.type(companyField(), "Gate");
|
|
const option = await screen.findByRole("option", { name: "Gateway Plumbing" });
|
|
await userEvent.click(option);
|
|
|
|
expect(companyField()).toHaveValue("Gateway Plumbing");
|
|
expect(screen.getByRole("textbox", { name: "Company Phone" })).toHaveValue("(314) 555-0198");
|
|
});
|
|
|
|
it("sets companyId when a known company is selected and clears it when the text changes", async () => {
|
|
renderWithProviders(<Harness defaultValues={emptyForm} resetTarget={emptyForm} />, {
|
|
withAuth: false,
|
|
});
|
|
|
|
await userEvent.type(companyField(), "Gate");
|
|
await userEvent.click(await screen.findByRole("option", { name: "Gateway Plumbing" }));
|
|
expect(companyIdOutput()).toHaveTextContent("co-1");
|
|
|
|
await userEvent.type(companyField(), "!");
|
|
expect(companyIdOutput()).toHaveTextContent("");
|
|
});
|
|
|
|
it("keeps companyId null for free-typed company text that matches no option", async () => {
|
|
renderWithProviders(<Harness defaultValues={emptyForm} resetTarget={emptyForm} />, {
|
|
withAuth: false,
|
|
});
|
|
|
|
await userEvent.type(companyField(), "Independent Vendor LLC");
|
|
expect(companyIdOutput()).toHaveTextContent("");
|
|
});
|
|
|
|
it("formats technician and company phones into the (XXX) XXX-XXXX mask", async () => {
|
|
renderWithProviders(<Harness defaultValues={emptyForm} resetTarget={emptyForm} />, {
|
|
withAuth: false,
|
|
});
|
|
|
|
const phone = screen.getByRole("textbox", { name: "Technician Phone" });
|
|
await userEvent.type(phone, "3145550198");
|
|
expect(phone).toHaveValue("(314) 555-0198");
|
|
|
|
const companyPhone = screen.getByRole("textbox", { name: "Company Phone" });
|
|
await userEvent.type(companyPhone, "3145550100");
|
|
expect(companyPhone).toHaveValue("(314) 555-0100");
|
|
});
|
|
|
|
it("exposes a preferred contact selector with Phone, Email, and Text options", () => {
|
|
renderWithProviders(<Harness defaultValues={emptyForm} resetTarget={emptyForm} />, {
|
|
withAuth: false,
|
|
});
|
|
|
|
expect(screen.getByRole("button", { name: "Phone" })).toHaveAttribute("aria-pressed", "true");
|
|
expect(screen.getByRole("button", { name: "Email" })).toBeInTheDocument();
|
|
expect(screen.getByRole("button", { name: "Text" })).toBeInTheDocument();
|
|
});
|
|
});
|