// ABOUTME: Unit tests for DecisionCard component. // ABOUTME: Tests rendering of decision status, icon, and reason. import { render, screen } from "@testing-library/react"; import { describe, expect, it } from "vitest"; import type { Decision } from "@/types"; import { DecisionCard } from "./decision-card"; describe("DecisionCard", () => { describe("rendering", () => { it("renders the decision icon", () => { const decision: Decision = { status: "REST", reason: "Your body needs recovery today", icon: "🛌", }; render(); expect(screen.getByText("🛌")).toBeInTheDocument(); }); it("renders the decision status", () => { const decision: Decision = { status: "TRAIN", reason: "Good to go", icon: "🏃", }; render(); expect(screen.getByText("TRAIN")).toBeInTheDocument(); }); it("renders the decision reason", () => { const decision: Decision = { status: "GENTLE", reason: "Take it easy today", icon: "🧘", }; render(); expect(screen.getByText("Take it easy today")).toBeInTheDocument(); }); }); describe("different status types", () => { it("renders REST status correctly", () => { const decision: Decision = { status: "REST", reason: "HRV unbalanced - recovery day", icon: "🛌", }; render(); expect(screen.getByText("REST")).toBeInTheDocument(); expect(screen.getByText("🛌")).toBeInTheDocument(); expect( screen.getByText("HRV unbalanced - recovery day"), ).toBeInTheDocument(); }); it("renders GENTLE status correctly", () => { const decision: Decision = { status: "GENTLE", reason: "Light movement recommended", icon: "🧘", }; render(); expect(screen.getByText("GENTLE")).toBeInTheDocument(); expect(screen.getByText("🧘")).toBeInTheDocument(); expect( screen.getByText("Light movement recommended"), ).toBeInTheDocument(); }); it("renders LIGHT status correctly", () => { const decision: Decision = { status: "LIGHT", reason: "Keep intensity moderate", icon: "🚶", }; render(); expect(screen.getByText("LIGHT")).toBeInTheDocument(); expect(screen.getByText("🚶")).toBeInTheDocument(); expect(screen.getByText("Keep intensity moderate")).toBeInTheDocument(); }); it("renders REDUCED status correctly", () => { const decision: Decision = { status: "REDUCED", reason: "Lower intensity today", icon: "⬇️", }; render(); expect(screen.getByText("REDUCED")).toBeInTheDocument(); expect(screen.getByText("⬇️")).toBeInTheDocument(); expect(screen.getByText("Lower intensity today")).toBeInTheDocument(); }); it("renders TRAIN status correctly", () => { const decision: Decision = { status: "TRAIN", reason: "Full intensity training approved", icon: "🏃", }; render(); expect(screen.getByText("TRAIN")).toBeInTheDocument(); expect(screen.getByText("🏃")).toBeInTheDocument(); expect( screen.getByText("Full intensity training approved"), ).toBeInTheDocument(); }); }); describe("color-coded backgrounds", () => { it("renders REST with red background", () => { const decision: Decision = { status: "REST", reason: "Recovery day", icon: "🛌", }; const { container } = render(); const card = container.firstChild as HTMLElement; expect(card).toHaveClass("bg-red-100", "border-red-300"); }); it("renders GENTLE with yellow background", () => { const decision: Decision = { status: "GENTLE", reason: "Light movement", icon: "🧘", }; const { container } = render(); const card = container.firstChild as HTMLElement; expect(card).toHaveClass("bg-yellow-100", "border-yellow-300"); }); it("renders LIGHT with yellow background", () => { const decision: Decision = { status: "LIGHT", reason: "Moderate intensity", icon: "🚶", }; const { container } = render(); const card = container.firstChild as HTMLElement; expect(card).toHaveClass("bg-yellow-100", "border-yellow-300"); }); it("renders REDUCED with yellow background", () => { const decision: Decision = { status: "REDUCED", reason: "Lower intensity", icon: "⬇️", }; const { container } = render(); const card = container.firstChild as HTMLElement; expect(card).toHaveClass("bg-yellow-100", "border-yellow-300"); }); it("renders TRAIN with green background", () => { const decision: Decision = { status: "TRAIN", reason: "Full intensity approved", icon: "🏃", }; const { container } = render(); const card = container.firstChild as HTMLElement; expect(card).toHaveClass("bg-green-100", "border-green-300"); }); it("renders reason with appropriate text color for REST", () => { const decision: Decision = { status: "REST", reason: "Rest message", icon: "🛌", }; render(); const reason = screen.getByText("Rest message"); expect(reason).toHaveClass("text-red-700"); }); it("renders reason with appropriate text color for GENTLE", () => { const decision: Decision = { status: "GENTLE", reason: "Gentle message", icon: "🧘", }; render(); const reason = screen.getByText("Gentle message"); expect(reason).toHaveClass("text-yellow-700"); }); it("renders reason with appropriate text color for TRAIN", () => { const decision: Decision = { status: "TRAIN", reason: "Train message", icon: "🏃", }; render(); const reason = screen.getByText("Train message"); expect(reason).toHaveClass("text-green-700"); }); }); describe("styling", () => { it("renders within a bordered container", () => { const decision: Decision = { status: "REST", reason: "Test reason", icon: "🛌", }; const { container } = render(); const card = container.firstChild as HTMLElement; expect(card).toHaveClass("rounded-lg", "p-6"); }); it("renders status as bold heading", () => { const decision: Decision = { status: "TRAIN", reason: "Test", icon: "🏃", }; render(); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toHaveTextContent("TRAIN"); expect(heading).toHaveClass("font-bold"); }); it("renders reason with status-specific color", () => { const decision: Decision = { status: "REST", reason: "Reason with status color", icon: "🛌", }; render(); const reason = screen.getByText("Reason with status color"); expect(reason).toHaveClass("text-red-700"); }); }); });