import { beforeEach, describe, expect, it, vi } from "vitest";
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
import { Checkbox } from "@components/UI/Checkbox/index.tsx";
import React from "react";
vi.mock("@components/UI/Label.tsx", () => ({
Label: (
{ children, className, htmlFor, id }: {
children: React.ReactNode;
className: string;
htmlFor: string;
id: string;
},
) => (
),
}));
describe("Checkbox", () => {
beforeEach(cleanup);
it("renders unchecked by default", () => {
render();
const checkbox = screen.getByRole("checkbox");
expect(checkbox).not.toBeChecked();
expect(screen.queryByText("Check")).not.toBeInTheDocument();
});
it("renders checked when checked prop is true", () => {
render();
expect(screen.getByRole("checkbox")).toBeChecked();
expect(screen.getByRole("presentation")).toBeInTheDocument();
});
it("calls onChange when clicked", () => {
const onChange = vi.fn();
render();
fireEvent.click(screen.getByRole("presentation"));
expect(onChange).toHaveBeenCalledWith(true);
fireEvent.click(screen.getByRole("presentation"));
expect(onChange).toHaveBeenCalledWith(false);
});
it("uses provided id", () => {
render();
expect(screen.getByRole("checkbox").id).toBe("custom-id");
});
it("renders children in Label component", () => {
render(Test Label);
expect(screen.getByTestId("label-component")).toHaveTextContent(
"Test Label",
);
});
it("applies custom className", () => {
const { container } = render();
expect(container.firstChild).toHaveClass("custom-class");
});
it("applies labelClassName to Label", () => {
render(Test);
expect(screen.getByTestId("label-component")).toHaveClass("label-class");
});
it("disables checkbox when disabled prop is true", () => {
render();
expect(screen.getByRole("checkbox")).toBeDisabled();
expect(screen.getByRole("presentation")).toHaveClass("opacity-50");
});
it("does not call onChange when disabled", () => {
const onChange = vi.fn();
render();
fireEvent.click(screen.getByRole("presentation"));
expect(onChange).not.toHaveBeenCalled();
});
it("sets required attribute when required prop is true", () => {
render();
expect(screen.getByRole("checkbox")).toHaveAttribute("required");
});
it("sets name attribute when name prop is provided", () => {
render();
expect(screen.getByRole("checkbox")).toHaveAttribute("name", "test-name");
});
it("passes through additional props", () => {
render();
expect(screen.getByRole("checkbox")).toHaveAttribute(
"data-testid",
"extra-prop",
);
});
it("toggles checked state correctly", () => {
render();
const checkbox = screen.getByRole("checkbox");
const presentation = screen.getByRole("presentation");
expect(checkbox).not.toBeChecked();
fireEvent.click(presentation);
expect(checkbox).toBeChecked();
fireEvent.click(presentation);
expect(checkbox).not.toBeChecked();
});
});