import { renderWithProviders as render, screen, fireEvent, } from "../utils/test-utils"; import { describe, it, expect, vi } from "vitest"; import Rule from "../../app/components/cards/Rule"; describe("Rule Component", () => { const defaultProps = { title: "Test Rule", description: "This is a test rule description", }; it("renders rule card with all required information", () => { render(); expect(screen.getByText("Test Rule")).toBeInTheDocument(); expect( screen.getByText("This is a test rule description"), ).toBeInTheDocument(); }); it("renders with custom className", () => { const customClass = "custom-rule-card"; render(); const card = screen.getByRole("button"); expect(card).toHaveClass(customClass); }); it("applies default background color", () => { render(); const card = screen.getByRole("button"); expect(card).toHaveClass("bg-[var(--color-community-teal-100)]"); }); it("applies custom background color", () => { const customBg = "bg-blue-100"; render(); const card = screen.getByRole("button"); expect(card).toHaveClass(customBg); }); it("renders with icon when provided", () => { const Icon = () => 🚀; render(} />); expect(screen.getByTestId("icon")).toBeInTheDocument(); }); it("handles click events", () => { const handleClick = vi.fn(); render(); const card = screen.getByRole("button"); fireEvent.click(card); expect(handleClick).toHaveBeenCalledTimes(1); }); it("handles keyboard events", () => { const handleClick = vi.fn(); render(); const card = screen.getByRole("button"); // Test Enter key fireEvent.keyDown(card, { key: "Enter" }); expect(handleClick).toHaveBeenCalledTimes(1); // Test Space key fireEvent.keyDown(card, { key: " " }); expect(handleClick).toHaveBeenCalledTimes(2); }); it("applies hover effects correctly", () => { render(); const card = screen.getByRole("button"); expect(card).toHaveClass( "hover:shadow-[0px_0px_64px_0px_rgba(0,0,0,0.15)]", "transition-shadow", ); }); it("renders with proper accessibility attributes", () => { render(); const card = screen.getByRole("button"); expect(card).toHaveAttribute( "aria-label", "Learn more about Test Rule governance pattern", ); expect(card).toHaveAttribute("tabIndex", "0"); }); it("handles empty description gracefully", () => { render(); expect(screen.getByText("Test Rule")).toBeInTheDocument(); expect( screen.queryByText("This is a test rule description"), ).not.toBeInTheDocument(); }); it("clicking editable title calls onTitleClick and does not fire card onClick", () => { const onCard = vi.fn(); const onTitle = vi.fn(); render( , ); fireEvent.click(screen.getByTestId("rule-title-edit")); expect(onTitle).toHaveBeenCalledTimes(1); expect(onCard).not.toHaveBeenCalled(); }); it("clicking editable description calls onDescriptionClick and does not fire card onClick", () => { const onCard = vi.fn(); const onDesc = vi.fn(); render( , ); fireEvent.click(screen.getByTestId("rule-description-edit")); expect(onDesc).toHaveBeenCalledTimes(1); expect(onCard).not.toHaveBeenCalled(); }); it("applies proper sizing for expanded states", () => { render(); const card = screen.getByRole("button"); expect(card).toHaveClass("w-[568px]"); }); it("fluidWidth expanded cards fill the container", () => { render(); const card = screen.getByRole("button"); expect(card).not.toHaveClass("w-[568px]"); expect(card).toHaveClass("w-full"); }); it("applies proper accessibility attributes", () => { render(); const card = screen.getByRole("button"); expect(card).toHaveAttribute("aria-expanded", "true"); expect(card).toHaveAttribute("tabIndex", "0"); }); it("renders without icon when not provided", () => { render(); expect(screen.queryByTestId("icon")).not.toBeInTheDocument(); }); it("applies proper border and shadow classes", () => { render(); const card = screen.getByRole("button"); expect(card).toHaveClass("shadow-[0px_0px_48px_0px_rgba(0,0,0,0.1)]"); expect(card).toHaveClass("rounded-[var(--radius-measures-radius-small)]"); }); it("maintains proper heading structure", () => { render(); const heading = screen.getByRole("heading", { level: 3 }); expect(heading).toHaveTextContent("Test Rule"); expect(heading.tagName).toBe("H3"); }); it("applies proper font classes for title", () => { render(); const heading = screen.getByRole("heading", { level: 3 }); // Check for responsive font classes - at 1440px+ it should have font-bricolage-grotesque and font-extrabold expect(heading?.className).toMatch( /min-\[1440px\]:font-bricolage-grotesque/, ); expect(heading?.className).toMatch(/min-\[1440px\]:font-extrabold/); }); it("renders expanded state with categories", () => { const categories = [ { name: "Values", chipOptions: [ { id: "v1", label: "Consciousness", state: "unselected" }, ], }, ]; render( , ); expect(screen.getByText("Values")).toBeInTheDocument(); }); it("renders with logo URL", () => { render( , ); const logo = screen.getByAltText("Test Logo"); expect(logo).toBeInTheDocument(); }); it("renders with community initials fallback", () => { render(); expect(screen.getByText("CE")).toBeInTheDocument(); }); it("shows template recommended tag when collapsed and recommended is true", () => { render(); expect(screen.getByText("RECOMMENDED")).toBeInTheDocument(); }); it("does not show template recommended tag when expanded", () => { render(); expect(screen.queryByText("RECOMMENDED")).not.toBeInTheDocument(); }); });