b265aace57
CI Pipeline / test (20) (pull_request) Successful in 7m32s
CI Pipeline / test (18) (pull_request) Successful in 7m34s
CI Pipeline / e2e (chromium) (pull_request) Successful in 3m13s
CI Pipeline / e2e (firefox) (pull_request) Successful in 3m46s
CI Pipeline / e2e (webkit) (pull_request) Successful in 3m57s
CI Pipeline / performance (pull_request) Successful in 3m41s
CI Pipeline / visual-regression (pull_request) Failing after 8m6s
CI Pipeline / storybook (pull_request) Successful in 1m31s
CI Pipeline / lint (pull_request) Successful in 1m6s
CI Pipeline / build (pull_request) Successful in 1m24s
148 lines
4.3 KiB
React
148 lines
4.3 KiB
React
import { render, screen, fireEvent } from "@testing-library/react";
|
|
import { describe, it, expect, vi } from "vitest";
|
|
import RuleCard from "../../app/components/RuleCard";
|
|
|
|
describe("RuleCard Component", () => {
|
|
const defaultProps = {
|
|
title: "Test Rule",
|
|
description: "This is a test rule description",
|
|
};
|
|
|
|
it("renders rule card with all required information", () => {
|
|
render(<RuleCard {...defaultProps} />);
|
|
|
|
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(<RuleCard {...defaultProps} className={customClass} />);
|
|
|
|
const card = screen.getByRole("button");
|
|
expect(card).toHaveClass(customClass);
|
|
});
|
|
|
|
it("applies default background color", () => {
|
|
render(<RuleCard {...defaultProps} />);
|
|
|
|
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(<RuleCard {...defaultProps} backgroundColor={customBg} />);
|
|
|
|
const card = screen.getByRole("button");
|
|
expect(card).toHaveClass(customBg);
|
|
});
|
|
|
|
it("renders with icon when provided", () => {
|
|
const Icon = () => <span data-testid="icon">🚀</span>;
|
|
render(<RuleCard {...defaultProps} icon={<Icon />} />);
|
|
|
|
expect(screen.getByTestId("icon")).toBeInTheDocument();
|
|
});
|
|
|
|
it("handles click events", () => {
|
|
const handleClick = vi.fn();
|
|
render(<RuleCard {...defaultProps} onClick={handleClick} />);
|
|
|
|
const card = screen.getByRole("button");
|
|
fireEvent.click(card);
|
|
|
|
expect(handleClick).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("handles keyboard events", () => {
|
|
const handleClick = vi.fn();
|
|
render(<RuleCard {...defaultProps} onClick={handleClick} />);
|
|
|
|
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(<RuleCard {...defaultProps} />);
|
|
|
|
const card = screen.getByRole("button");
|
|
expect(card).toHaveClass(
|
|
"hover:shadow-xl",
|
|
"hover:scale-[1.02]",
|
|
"transition-all",
|
|
);
|
|
});
|
|
|
|
it("renders with proper accessibility attributes", () => {
|
|
render(<RuleCard {...defaultProps} />);
|
|
|
|
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(<RuleCard {...defaultProps} description="" />);
|
|
|
|
expect(screen.getByText("Test Rule")).toBeInTheDocument();
|
|
expect(
|
|
screen.queryByText("This is a test rule description"),
|
|
).not.toBeInTheDocument();
|
|
});
|
|
|
|
it("applies proper responsive sizing", () => {
|
|
render(<RuleCard {...defaultProps} />);
|
|
|
|
const card = screen.getByRole("button");
|
|
expect(card).toHaveClass("md:h-[210px]", "lg:h-[277px]");
|
|
});
|
|
|
|
it("applies focus styles correctly", () => {
|
|
render(<RuleCard {...defaultProps} />);
|
|
|
|
const card = screen.getByRole("button");
|
|
expect(card).toHaveClass("focus:outline-none", "focus:ring-2");
|
|
});
|
|
|
|
it("renders without icon when not provided", () => {
|
|
render(<RuleCard {...defaultProps} />);
|
|
|
|
expect(screen.queryByTestId("icon")).not.toBeInTheDocument();
|
|
});
|
|
|
|
it("applies proper border and shadow classes", () => {
|
|
render(<RuleCard {...defaultProps} />);
|
|
|
|
const card = screen.getByRole("button");
|
|
expect(card).toHaveClass("shadow-lg", "backdrop-blur-sm");
|
|
});
|
|
|
|
it("maintains proper heading structure", () => {
|
|
render(<RuleCard {...defaultProps} />);
|
|
|
|
const heading = screen.getByRole("heading", { level: 3 });
|
|
expect(heading).toHaveTextContent("Test Rule");
|
|
expect(heading.tagName).toBe("H3");
|
|
});
|
|
|
|
it("applies proper font classes", () => {
|
|
render(<RuleCard {...defaultProps} />);
|
|
|
|
const heading = screen.getByRole("heading", { level: 3 });
|
|
expect(heading).toHaveClass("font-space-grotesk", "font-bold");
|
|
});
|
|
});
|