// ABOUTME: Unit tests for DayCell component. // ABOUTME: Tests phase coloring, today highlighting, and click handling. import { fireEvent, render, screen } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; import type { CyclePhase } from "@/types"; import { DayCell } from "./day-cell"; describe("DayCell", () => { const baseProps = { date: new Date("2026-01-15"), cycleDay: 5, phase: "FOLLICULAR" as CyclePhase, isToday: false, onClick: vi.fn(), }; describe("rendering", () => { it("renders the day number from date", () => { render(); expect(screen.getByText("15")).toBeInTheDocument(); }); it("renders the cycle day label", () => { render(); expect(screen.getByText("Day 5")).toBeInTheDocument(); }); it("renders as a button", () => { render(); expect(screen.getByRole("button")).toBeInTheDocument(); }); it("renders cycle day 1 correctly", () => { render(); expect(screen.getByText("Day 1")).toBeInTheDocument(); }); it("renders high cycle day numbers", () => { render(); expect(screen.getByText("Day 28")).toBeInTheDocument(); }); }); describe("phase colors", () => { it("applies blue background for MENSTRUAL phase", () => { render(); const button = screen.getByRole("button"); expect(button).toHaveClass("bg-blue-100"); }); it("applies green background for FOLLICULAR phase", () => { render(); const button = screen.getByRole("button"); expect(button).toHaveClass("bg-green-100"); }); it("applies purple background for OVULATION phase", () => { render(); const button = screen.getByRole("button"); expect(button).toHaveClass("bg-purple-100"); }); it("applies yellow background for EARLY_LUTEAL phase", () => { render(); const button = screen.getByRole("button"); expect(button).toHaveClass("bg-yellow-100"); }); it("applies red background for LATE_LUTEAL phase", () => { render(); const button = screen.getByRole("button"); expect(button).toHaveClass("bg-red-100"); }); }); describe("today highlighting", () => { it("does not have ring when isToday is false", () => { render(); const button = screen.getByRole("button"); expect(button).not.toHaveClass("ring-2", "ring-black"); }); it("has ring-2 ring-black when isToday is true", () => { render(); const button = screen.getByRole("button"); expect(button).toHaveClass("ring-2", "ring-black"); }); it("maintains phase color when isToday is true", () => { render(); const button = screen.getByRole("button"); expect(button).toHaveClass("bg-purple-100"); expect(button).toHaveClass("ring-2", "ring-black"); }); }); describe("click handling", () => { it("calls onClick when clicked", () => { const onClick = vi.fn(); render(); const button = screen.getByRole("button"); fireEvent.click(button); expect(onClick).toHaveBeenCalledTimes(1); }); it("does not throw when onClick is undefined", () => { render(); const button = screen.getByRole("button"); expect(() => fireEvent.click(button)).not.toThrow(); }); it("calls onClick once per click", () => { const onClick = vi.fn(); render(); const button = screen.getByRole("button"); fireEvent.click(button); fireEvent.click(button); fireEvent.click(button); expect(onClick).toHaveBeenCalledTimes(3); }); }); describe("styling", () => { it("has rounded corners", () => { render(); const button = screen.getByRole("button"); expect(button).toHaveClass("rounded"); }); it("has padding", () => { render(); const button = screen.getByRole("button"); expect(button).toHaveClass("p-2"); }); it("renders day number with font-medium", () => { render(); const dayNumber = screen.getByText("15"); expect(dayNumber).toHaveClass("font-medium"); }); it("renders cycle day label in gray", () => { render(); const cycleLabel = screen.getByText("Day 5"); expect(cycleLabel).toHaveClass("text-gray-500"); }); }); describe("date variations", () => { it("renders single digit day", () => { render(); expect(screen.getByText("5")).toBeInTheDocument(); }); it("renders last day of month", () => { render(); expect(screen.getByText("31")).toBeInTheDocument(); }); it("renders first day of month", () => { render(); expect(screen.getByText("1")).toBeInTheDocument(); }); }); });