/// import React from "react"; import { Checkbox } from "./index"; import { fireEvent, render, screen } from "@testing-library/react"; jest.mock("@shared/components/button", () => { const MockButton = React.forwardRef< HTMLButtonElement, React.ButtonHTMLAttributes >(({ children, ...props }, ref) => ( )); MockButton.displayName = "MockButton"; return { Button: MockButton }; }); jest.mock("@shared/utils", () => ({ cx: (...args: unknown[]) => args.filter(Boolean).join(" "), })); describe("Checkbox", () => { describe("rendering", () => { it("renders an unchecked checkbox by default", () => { render(); const input = screen.getByRole("checkbox"); expect(input).not.toBeChecked(); }); it("renders a checked checkbox when checked is true", () => { render(); const input = screen.getByRole("checkbox"); expect(input).toBeChecked(); }); it("renders with the correct name attribute", () => { render(); const input = screen.getByRole("checkbox"); expect(input).toHaveAttribute("name", "agreement"); }); it("renders with the correct value attribute", () => { render(); const input = screen.getByRole("checkbox"); expect(input).toHaveAttribute("value", "yes"); }); it("applies displayName correctly", () => { expect(Checkbox.displayName).toBe("Checkbox"); }); }); describe("label", () => { it("renders a string label", () => { render(); expect(screen.getByText("Accept terms")).toBeInTheDocument(); }); it("renders a ReactNode label", () => { render( Custom} /> ); expect(screen.getByTestId("custom-label")).toBeInTheDocument(); }); it("does not render label element when label is not provided", () => { const { container } = render(); const labels = container.querySelectorAll("label"); // Only the icon label, no text label expect(labels.length).toBe(1); }); it("applies labelClassName to the label", () => { render( ); const label = screen.getByText("Label"); expect(label.className).toContain("custom-label"); }); it("applies error class to label when error is true", () => { render(); const label = screen.getByText("Label"); expect(label.className).toContain("text-text-critical"); }); }); describe("interactive behavior", () => { it("calls onChange with boolean when handler expects a parameter", () => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const handleChange = jest.fn((_isChecked: boolean) => undefined); render(); const input = screen.getByRole("checkbox"); fireEvent.click(input); expect(handleChange).toHaveBeenCalledWith(true); }); it("calls onChange without parameters for zero-arity handler", () => { const handleChange = jest.fn(); // Override length to simulate zero-arity Object.defineProperty(handleChange, "length", { value: 0 }); render(); const input = screen.getByRole("checkbox"); fireEvent.click(input); expect(handleChange).toHaveBeenCalled(); }); it("does not call onChange when disabled", () => { const handleChange = jest.fn(); render(); const input = screen.getByRole("checkbox"); fireEvent.click(input); expect(handleChange).not.toHaveBeenCalled(); }); it("does not call onChange when state is disabled", () => { const handleChange = jest.fn(); render(); const input = screen.getByRole("checkbox"); fireEvent.click(input); expect(handleChange).not.toHaveBeenCalled(); }); }); describe("disabled state", () => { it("sets disabled attribute when disabled prop is true", () => { render(); const input = screen.getByRole("checkbox"); expect(input).toBeDisabled(); }); it("sets disabled attribute when state is disabled", () => { render(); const input = screen.getByRole("checkbox"); expect(input).toBeDisabled(); }); it("applies disabled styling to unchecked icon", () => { const { container } = render(); const rect = container.querySelector("rect"); expect(rect).toHaveClass("fill-checkbox-bg-surface-disabled"); }); it("applies disabled styling to checked icon", () => { const { container } = render( ); const rect = container.querySelector("rect"); expect(rect).toHaveClass("fill-checkbox-bg-surface-selected-disabled"); }); }); describe("focus state", () => { it("applies focus outline class when state is focus", () => { const { container } = render(); const label = container.querySelector("label"); expect(label?.className).toContain("outline"); }); }); describe("required", () => { it("sets required attribute when required is true", () => { render(); const input = screen.getByRole("checkbox"); expect(input).toBeRequired(); }); }); describe("id handling", () => { it("uses provided id for input and label", () => { render(); const input = screen.getByRole("checkbox"); expect(input).toHaveAttribute("id", "custom-id"); }); it("falls back to name when id is not provided", () => { render(); const input = screen.getByRole("checkbox"); expect(input).toHaveAttribute("id", "fallback-name"); }); }); describe("data-cy attribute", () => { it("passes data-cy to the input element", () => { render(); const input = screen.getByRole("checkbox"); expect(input).toHaveAttribute("data-cy", "checkbox-cy"); }); }); describe("renderInfoIcon", () => { it("renders info icon button when renderInfoIcon is provided", () => { const onClick = jest.fn(); render( ); expect(screen.getByTestId("info-btn")).toBeInTheDocument(); }); it("calls onClick when info icon is clicked", () => { const onClick = jest.fn(); render( ); fireEvent.click(screen.getByTestId("info-btn")); expect(onClick).toHaveBeenCalledTimes(1); }); it("does not render info icon when renderInfoIcon is not provided", () => { const { container } = render(); const buttons = container.querySelectorAll("button"); expect(buttons.length).toBe(0); }); it("applies the provided iconSize to the info icon SVG dimensions", () => { const onClick = jest.fn(); render( ); const svg = screen.getByTestId("info-btn").querySelector("svg"); expect(svg?.getAttribute("width")).toBe("20"); expect(svg?.getAttribute("height")).toBe("20"); }); it("defaults the info icon SVG dimensions to 24 when iconSize is not provided", () => { const onClick = jest.fn(); render( ); const svg = screen.getByTestId("info-btn").querySelector("svg"); expect(svg?.getAttribute("width")).toBe("24"); expect(svg?.getAttribute("height")).toBe("24"); }); }); describe("containerClassName", () => { it("applies containerClassName to the wrapper div", () => { const { container } = render( ); const wrapper = container.firstChild as HTMLElement; expect(wrapper.className).toContain("wrapper-class"); }); }); describe("checked icon rendering", () => { it("renders checkmark SVG when checked", () => { const { container } = render(); const paths = container.querySelectorAll("path"); // Checked state has a checkmark path expect(paths.length).toBeGreaterThan(0); }); it("renders empty box SVG when unchecked", () => { const { container } = render(); const rects = container.querySelectorAll("rect"); // Unchecked state has border rects expect(rects.length).toBeGreaterThan(0); }); }); });