import { describe, it, expect, beforeEach, afterEach } from "vitest"; import { render, screen } from "@testing-library/react"; import { TextInput } from "./input"; describe("TextInput Component", () => { const originalEnv = process.env; beforeEach(() => { process.env = { ...originalEnv }; }); afterEach(() => { process.env = originalEnv; }); describe("Component Rendering", () => { it("should render input with label", () => { render(); expect(screen.getByText("Email")).toBeTruthy(); }); it("should render input with placeholder", () => { const { container } = render(); const input = container.querySelector("input"); expect(input?.placeholder).toBe("Enter username"); }); it("should render input with default value", () => { const { container } = render(); const input = container.querySelector("input"); expect(input?.defaultValue).toBe("John Doe"); }); it("should show required indicator when required", () => { render(); expect(screen.getByText(/\*/)).toBeTruthy(); }); }); describe("Input States", () => { it("should render disabled state", () => { const { container } = render(); const input = container.querySelector("input"); expect(input?.disabled).toBe(true); // Should have disabled/pointer-events styles expect(input?.className).toMatch(/pointer-events/); }); it("should render error state with message", () => { render(); expect(screen.getByText("Invalid email")).toBeTruthy(); }); it("should apply error styling when error is present", () => { const { container } = render(); const input = container.querySelector("input"); expect(input).toBeTruthy(); // Should have border-warn or warn-related styles expect(input?.className).toMatch(/border-warn/); }); it("should render success state with message", () => { render(); expect(screen.getByText("Valid email")).toBeTruthy(); }); }); describe("Theme Integration", () => { it("should apply theme-based roundness", () => { const { container } = render(); const input = container.querySelector("input"); // Should have some roundness class applied expect(input?.className).toBeTruthy(); expect(input?.className).toMatch(/rounded/); }); it("should completely override theme roundness with custom roundness prop", () => { // Set theme to have full roundness process.env.NEXT_PUBLIC_THEME_ROUNDNESS = "full"; const customRoundness = "custom-input-round"; const { container } = render(); const input = container.querySelector("input"); // Should contain the custom roundness expect(input?.className).toContain(customRoundness); // The custom prop completely replaces theme roundness expect(input).toBeTruthy(); }); it("should respect theme roundness changes", () => { // Default theme const { container: container1 } = render(); const input1 = container1.querySelector("input"); const defaultClasses = input1?.className; // Change theme process.env.NEXT_PUBLIC_THEME_ROUNDNESS = "full"; const { container: container2 } = render(); const input2 = container2.querySelector("input"); // Classes should be present expect(defaultClasses).toBeTruthy(); expect(input2?.className).toBeTruthy(); }); }); describe("Input Behavior", () => { it("should have autocomplete off by default", () => { const { container } = render(); const input = container.querySelector("input"); expect(input?.autocomplete).toBe("off"); }); it("should allow custom autocomplete", () => { const { container } = render(); const input = container.querySelector("input"); expect(input?.autocomplete).toBe("email"); }); it("should pass through native input props", () => { const { container } = render(); const input = container.querySelector("input"); expect(input?.maxLength).toBe(10); expect(input?.type).toBe("email"); }); }); describe("Styling", () => { it("should have consistent base styling", () => { const { container } = render(); const input = container.querySelector("input"); expect(input).toBeTruthy(); expect(input?.className).toBeTruthy(); expect(input?.className.length).toBeGreaterThan(0); // Should have transition styles expect(input?.className).toMatch(/transition/); }); it("should apply border styles", () => { const { container } = render(); const input = container.querySelector("input"); expect(input).toBeTruthy(); // Should have border-related classes expect(input?.className).toMatch(/border/); }); it("should have focus styles", () => { const { container } = render(); const input = container.querySelector("input"); expect(input).toBeTruthy(); // Should have focus-related classes expect(input?.className).toMatch(/focus:/); }); }); describe("Label Styling", () => { it("should apply error color to label when error exists", () => { const { container } = render(); const label = container.querySelector("label"); expect(label).toBeTruthy(); }); it("should have default label styling", () => { const { container } = render(); const label = container.querySelector("label"); expect(label).toBeTruthy(); expect(label?.className).toBeTruthy(); }); }); describe("Accessibility", () => { it("should connect label to input", () => { const { container } = render(); const label = container.querySelector("label"); const input = container.querySelector("input"); expect(label).toBeTruthy(); expect(input).toBeTruthy(); }); it("should show required indicator", () => { const { container } = render(); const label = container.querySelector("label"); expect(label?.textContent).toContain("*"); }); }); });