import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { describe, expect, it, vi } from "vitest"; import { FormInput } from "#/components/features/onboarding/form-input"; describe("FormInput", () => { const defaultProps = { id: "test-input", label: "Test Label", value: "", onChange: vi.fn(), }; it("should render with correct test id", () => { render(); expect(screen.getByTestId("form-input-test-input")).toBeInTheDocument(); }); it("should render the label", () => { render(); expect(screen.getByText("Test Label")).toBeInTheDocument(); }); it("should display the provided value", () => { render(); const input = screen.getByTestId("form-input-test-input"); expect(input).toHaveValue("Hello World"); }); it("should call onChange when user types", async () => { const mockOnChange = vi.fn(); const user = userEvent.setup(); render(); const input = screen.getByTestId("form-input-test-input"); await user.type(input, "a"); expect(mockOnChange).toHaveBeenCalledWith("a"); }); it("should render as a text input by default", () => { render(); const input = screen.getByTestId("form-input-test-input"); expect(input).toHaveAttribute("type", "text"); }); it("should render as an email input when type is email", () => { render(); const input = screen.getByTestId("form-input-test-input"); expect(input).toHaveAttribute("type", "email"); }); it("should render a textarea when rows prop is provided", () => { render(); const textarea = screen.getByTestId("form-input-test-input"); expect(textarea.tagName).toBe("TEXTAREA"); expect(textarea).toHaveAttribute("rows", "4"); }); it("should render placeholder text", () => { render(); const input = screen.getByTestId("form-input-test-input"); expect(input).toHaveAttribute("placeholder", "Enter text here"); }); it("should have aria-required attribute when required", () => { render(); const input = screen.getByTestId("form-input-test-input"); expect(input).toHaveAttribute("aria-required", "true"); }); it("should have aria-label attribute", () => { render(); const input = screen.getByTestId("form-input-test-input"); expect(input).toHaveAttribute("aria-label", "Test Label"); }); it("should have required attribute on input when required", () => { render(); const input = screen.getByTestId("form-input-test-input"); expect(input).toBeRequired(); }); it("should have required attribute on textarea when required", () => { render(); const textarea = screen.getByTestId("form-input-test-input"); expect(textarea).toBeRequired(); }); it("should associate label with input via htmlFor", () => { render(); const label = screen.getByText("Test Label"); const input = screen.getByTestId("form-input-test-input"); expect(label).toHaveAttribute("for", "form-input-test-input"); expect(input).toHaveAttribute("id", "form-input-test-input"); }); describe("error state", () => { it("should not show error border by default", () => { render(); const input = screen.getByTestId("form-input-test-input"); expect(input).toHaveClass("border-[#242424]"); expect(input).not.toHaveClass("border-red-500"); }); it("should not show error border when showError is false", () => { render(); const input = screen.getByTestId("form-input-test-input"); expect(input).toHaveClass("border-[#242424]"); expect(input).not.toHaveClass("border-red-500"); }); it("should show error border when showError is true and field is empty and required", () => { render(); const input = screen.getByTestId("form-input-test-input"); expect(input).toHaveClass("border-red-500"); }); it("should not show error border when showError is true but field has value", () => { render(); const input = screen.getByTestId("form-input-test-input"); expect(input).not.toHaveClass("border-red-500"); expect(input).toHaveClass("border-[#242424]"); }); it("should not show error border when showError is true but field is not required", () => { render(); const input = screen.getByTestId("form-input-test-input"); expect(input).not.toHaveClass("border-red-500"); }); it("should have aria-invalid true when showing error", () => { render(); const input = screen.getByTestId("form-input-test-input"); expect(input).toHaveAttribute("aria-invalid", "true"); }); it("should have aria-invalid false when not showing error", () => { render(); const input = screen.getByTestId("form-input-test-input"); expect(input).toHaveAttribute("aria-invalid", "false"); }); it("should show error border on textarea when showError is true and empty", () => { render(); const textarea = screen.getByTestId("form-input-test-input"); expect(textarea).toHaveClass("border-red-500"); }); it("should show error border for invalid email when showError is true", () => { render( , ); const input = screen.getByTestId("form-input-test-input"); expect(input).toHaveClass("border-red-500"); }); it("should not show error border for valid email when showError is true", () => { render( , ); const input = screen.getByTestId("form-input-test-input"); expect(input).not.toHaveClass("border-red-500"); }); }); });