import React from "react"; import { SearchBlock } from "./index"; import { SearchBlockProps } from "./types"; import { fireEvent, render, screen } from "@testing-library/react"; // Mock dependencies jest.mock("@shared/components/button", () => ({ Button: ({ children, onClick, type, className, ...rest }: any) => ( ), })); jest.mock("@shared/components/input", () => ({ Input: ({ value, onChange, placeholder, className, // eslint-disable-next-line @typescript-eslint/no-unused-vars containerClassName, ...rest }: any) => ( ), })); jest.mock("@shared/components/material-icon", () => ({ MaterialIcon: ({ name, className }: any) => ( {name} ), })); jest.mock("@shared/components/text", () => ({ Text: ({ as: Tag = "span", children, className }: any) => ( {children} ), })); jest.mock("@shared/utils", () => ({ cx: (...args: any[]) => args.filter(Boolean).join(" "), })); const defaultProps: SearchBlockProps = { title: "Search Our Plans", backgroundColor: "white", color: "dark", }; describe("SearchBlock", () => { describe("Rendering", () => { it("renders with data-testid", () => { render(); expect(screen.getByTestId("search-block")).toBeInTheDocument(); }); it("renders title", () => { render(); expect(screen.getByText("Search Our Plans")).toBeInTheDocument(); }); it("renders with default anchorId", () => { render(); expect(screen.getByTestId("search-block")).toHaveAttribute( "id", "SearchBlock" ); }); it("renders with custom anchorId", () => { render(); expect(screen.getByTestId("search-block")).toHaveAttribute( "id", "custom-search" ); }); it("renders search input with placeholder", () => { render( ); expect(screen.getByTestId("search-input")).toHaveAttribute( "placeholder", "Enter your address" ); }); it("renders search icon button", () => { render(); expect(screen.getByTestId("icon-search")).toBeInTheDocument(); }); it("renders submit button with type submit", () => { render(); const submitBtn = screen.getByTestId("icon-search").closest("button"); expect(submitBtn).toHaveAttribute("type", "submit"); }); }); describe("Optional content", () => { it("renders subtitle when provided", () => { render(); expect(screen.getByText("Find the best plan")).toBeInTheDocument(); }); it("does not render subtitle when not provided", () => { render(); expect(screen.queryByText("Find the best plan")).not.toBeInTheDocument(); }); it("renders searchDescription when provided", () => { render( ); expect(screen.getByText("Enter your ZIP code")).toBeInTheDocument(); }); it("does not render searchDescription when not provided", () => { render(); expect(screen.queryByText("Enter your ZIP code")).not.toBeInTheDocument(); }); it("renders caption ReactNode when provided", () => { render( Caption content} /> ); expect(screen.getByTestId("caption")).toBeInTheDocument(); }); it("does not render caption when not provided", () => { render(); expect(screen.queryByTestId("caption")).not.toBeInTheDocument(); }); it("renders basicCaption ReactNode when provided", () => { render( Basic caption

} /> ); expect(screen.getByTestId("basic-caption")).toBeInTheDocument(); }); }); describe("Heading levels", () => { it("renders title as h2 when enableHeading is false/undefined", () => { render(); const el = screen.getByText("Search Our Plans"); expect(el.tagName).toBe("H2"); }); it("renders title as h1 when enableHeading is true", () => { render(); const el = screen.getByText("Search Our Plans"); expect(el.tagName).toBe("H1"); }); }); describe("Background and color themes", () => { it("applies supporting background class", () => { render(); expect(screen.getByTestId("search-block")).toHaveClass( "bg-bg-fill-brand-supporting" ); }); it("applies white background class", () => { render(); expect(screen.getByTestId("search-block")).toHaveClass("bg-bg"); }); it("applies brand background class", () => { render(); expect(screen.getByTestId("search-block")).toHaveClass( "bg-bg-fill-brand" ); }); it("applies dark text color", () => { render(); expect(screen.getByTestId("search-block")).toHaveClass("text-text"); }); it("applies light (white) text color", () => { render(); expect(screen.getByTestId("search-block")).toHaveClass("text-white"); }); }); describe("Form submission", () => { it("calls onSubmit with searchText on form submit", () => { const mockSubmit = jest.fn(); render(); const input = screen.getByTestId("search-input"); fireEvent.change(input, { target: { value: "90210" } }); const form = input.closest("form")!; fireEvent.submit(form); expect(mockSubmit).toHaveBeenCalledWith({ searchText: "90210" }); }); it("calls onSubmit with empty string when no text entered", () => { const mockSubmit = jest.fn(); render(); const form = screen.getByTestId("search-input").closest("form")!; fireEvent.submit(form); expect(mockSubmit).toHaveBeenCalledWith({ searchText: "" }); }); it("does not throw when onSubmit is not provided", () => { render(); const form = screen.getByTestId("search-input").closest("form")!; expect(() => fireEvent.submit(form)).not.toThrow(); }); it("prevents default form submission", () => { const mockSubmit = jest.fn(); render(); const form = screen.getByTestId("search-input").closest("form")!; const submitEvent = new Event("submit", { bubbles: true, cancelable: true, }); const prevented = !form.dispatchEvent(submitEvent); expect(prevented).toBe(true); }); }); describe("Input interaction", () => { it("updates input value on change", () => { render(); const input = screen.getByTestId("search-input") as HTMLInputElement; fireEvent.change(input, { target: { value: "test query" } }); expect(input.value).toBe("test query"); }); it("submits the latest typed value", () => { const mockSubmit = jest.fn(); render(); const input = screen.getByTestId("search-input"); fireEvent.change(input, { target: { value: "first" } }); fireEvent.change(input, { target: { value: "second" } }); const form = input.closest("form")!; fireEvent.submit(form); expect(mockSubmit).toHaveBeenCalledWith({ searchText: "second" }); }); }); });