shoc-frontend-new/src/test/app/(protected)/locations/state-select.test.tsx

137 lines
4.6 KiB
TypeScript
Raw Normal View History

import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { fireEvent, screen, waitFor } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import { StateSelect } from "@/app/(protected)/locations/_components/state-select";
import {
locationDefaultValues,
locationSchema,
type LocationFormValues,
} from "@/domain/locations/schemas/location-schema";
import { renderWithProviders } from "@/test/test-utils";
function StateSelectHarness({
onSubmit = vi.fn(),
}: {
onSubmit?: (values: LocationFormValues) => void;
}) {
const {
control,
handleSubmit,
formState: { errors },
} = useForm<LocationFormValues>({
resolver: zodResolver(locationSchema),
defaultValues: {
...locationDefaultValues,
name: "Dallas DC",
address: "3811 Distribution Dr",
city: "Dallas",
zipCode: "70068",
contacts: [{ name: "Jane", phone: "(421) 433-0032" }],
contactEmail: "jane@example.com",
accountId: "7",
},
});
return (
<form onSubmit={handleSubmit(onSubmit)} noValidate>
<StateSelect control={control} error={errors.state} />
<button type="submit">Save</button>
</form>
);
}
function openOptions() {
const input = screen.getByRole("combobox");
input.focus();
fireEvent.mouseDown(input);
return input;
}
describe("StateSelect", () => {
it("starts empty with no implicit default state", () => {
renderWithProviders(<StateSelectHarness />, { withAuth: false });
expect(screen.getByRole("combobox")).toHaveValue("");
expect(screen.queryByText("Area: ")).not.toBeInTheDocument();
});
it("shows searchable Name (CODE) options and no free-text entries", async () => {
renderWithProviders(<StateSelectHarness />, { withAuth: false });
const input = openOptions();
const options = await screen.findAllByRole("option");
expect(options).toHaveLength(50);
expect(screen.getByRole("option", { name: "Texas (TX)" })).toBeInTheDocument();
expect(screen.getByRole("option", { name: "California (CA)" })).toBeInTheDocument();
fireEvent.change(input, { target: { value: "mass" } });
await screen.findAllByRole("option");
expect(screen.getByRole("option", { name: "Massachusetts (MA)" })).toBeInTheDocument();
expect(screen.getAllByRole("option")).toHaveLength(1);
fireEvent.change(input, { target: { value: "Republic of Texas" } });
expect(screen.queryByRole("option")).not.toBeInTheDocument();
});
it("selects by search and shows the Area helper immediately", async () => {
const onSubmit = vi.fn();
renderWithProviders(<StateSelectHarness onSubmit={onSubmit} />, { withAuth: false });
const input = openOptions();
fireEvent.change(input, { target: { value: "texas" } });
fireEvent.click(await screen.findByRole("option", { name: "Texas (TX)" }));
expect(input).toHaveValue("Texas (TX)");
expect(screen.getByText("Area: West")).toBeInTheDocument();
fireEvent.click(screen.getByRole("button", { name: "Save" }));
await waitFor(() => {
expect(onSubmit).toHaveBeenCalledWith(
expect.objectContaining({ state: "TX" }),
expect.anything(),
);
});
});
it("is keyboard accessible (arrow + enter selection)", async () => {
const onSubmit = vi.fn();
renderWithProviders(<StateSelectHarness onSubmit={onSubmit} />, { withAuth: false });
const input = screen.getByRole("combobox");
input.focus();
fireEvent.change(input, { target: { value: "ohio" } });
fireEvent.keyDown(input, { key: "ArrowDown" });
fireEvent.keyDown(input, { key: "Enter" });
expect(input).toHaveValue("Ohio (OH)");
expect(screen.getByText("Area: Central")).toBeInTheDocument();
fireEvent.click(screen.getByRole("button", { name: "Save" }));
await waitFor(() => {
expect(onSubmit).toHaveBeenCalledWith(
expect.objectContaining({ state: "OH" }),
expect.anything(),
);
});
});
it("requires a state and rejects free text on submit", async () => {
const onSubmit = vi.fn();
renderWithProviders(<StateSelectHarness onSubmit={onSubmit} />, { withAuth: false });
fireEvent.click(screen.getByRole("button", { name: "Save" }));
expect(await screen.findByText("State is required")).toBeInTheDocument();
expect(onSubmit).not.toHaveBeenCalled();
const input = screen.getByRole("combobox");
input.focus();
fireEvent.change(input, { target: { value: "NotAState" } });
fireEvent.keyDown(input, { key: "Enter" });
fireEvent.click(screen.getByRole("button", { name: "Save" }));
await screen.findByText("State is required");
expect(onSubmit).not.toHaveBeenCalled();
});
});