Add component tests for P3.11 (82 tests across 5 files)

- DecisionCard tests: 11 tests covering rendering, status icons, styling
- DataPanel tests: 18 tests covering biometrics display, null handling, styling
- NutritionPanel tests: 12 tests covering seeds, carbs, keto guidance display
- OverrideToggles tests: 18 tests covering toggle states, callbacks, styling
- DayCell tests: 23 tests covering phase coloring, today highlighting, click handling

Total tests now: 707 passing across 40 test files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-11 09:02:34 +00:00
parent 39198fdf8c
commit 267d45f98a
6 changed files with 874 additions and 23 deletions

View File

@@ -0,0 +1,136 @@
// ABOUTME: Unit tests for NutritionPanel component.
// ABOUTME: Tests display of seeds, carb range, and keto guidance.
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import type { NutritionGuidance } from "@/types";
import { NutritionPanel } from "./nutrition-panel";
describe("NutritionPanel", () => {
const baseNutrition: NutritionGuidance = {
seeds: "Flax & Pumpkin",
carbRange: "100-150g",
ketoGuidance: "Moderate carbs today",
};
describe("rendering", () => {
it("renders the NUTRITION TODAY heading", () => {
render(<NutritionPanel nutrition={baseNutrition} />);
expect(screen.getByText("NUTRITION TODAY")).toBeInTheDocument();
});
it("renders seeds guidance with emoji", () => {
render(<NutritionPanel nutrition={baseNutrition} />);
expect(screen.getByText(/🌱 Flax & Pumpkin/)).toBeInTheDocument();
});
it("renders carb range with emoji", () => {
render(<NutritionPanel nutrition={baseNutrition} />);
expect(screen.getByText(/🍽️ Carbs: 100-150g/)).toBeInTheDocument();
});
it("renders keto guidance with emoji", () => {
render(<NutritionPanel nutrition={baseNutrition} />);
expect(
screen.getByText(/🥑 Keto: Moderate carbs today/),
).toBeInTheDocument();
});
});
describe("seed cycling phases", () => {
it("displays follicular phase seeds (flax & pumpkin)", () => {
const nutrition: NutritionGuidance = {
...baseNutrition,
seeds: "Flax & Pumpkin",
};
render(<NutritionPanel nutrition={nutrition} />);
expect(screen.getByText(/🌱 Flax & Pumpkin/)).toBeInTheDocument();
});
it("displays luteal phase seeds (sunflower & sesame)", () => {
const nutrition: NutritionGuidance = {
...baseNutrition,
seeds: "Sunflower & Sesame",
};
render(<NutritionPanel nutrition={nutrition} />);
expect(screen.getByText(/🌱 Sunflower & Sesame/)).toBeInTheDocument();
});
});
describe("carb range variations", () => {
it("displays low carb range", () => {
const nutrition: NutritionGuidance = {
...baseNutrition,
carbRange: "50-75g",
};
render(<NutritionPanel nutrition={nutrition} />);
expect(screen.getByText(/🍽️ Carbs: 50-75g/)).toBeInTheDocument();
});
it("displays high carb range", () => {
const nutrition: NutritionGuidance = {
...baseNutrition,
carbRange: "150-200g",
};
render(<NutritionPanel nutrition={nutrition} />);
expect(screen.getByText(/🍽️ Carbs: 150-200g/)).toBeInTheDocument();
});
});
describe("keto guidance variations", () => {
it("displays keto-friendly guidance", () => {
const nutrition: NutritionGuidance = {
...baseNutrition,
ketoGuidance: "Good day for keto",
};
render(<NutritionPanel nutrition={nutrition} />);
expect(
screen.getByText(/🥑 Keto: Good day for keto/),
).toBeInTheDocument();
});
it("displays carb-loading guidance", () => {
const nutrition: NutritionGuidance = {
...baseNutrition,
ketoGuidance: "Consider carb loading",
};
render(<NutritionPanel nutrition={nutrition} />);
expect(
screen.getByText(/🥑 Keto: Consider carb loading/),
).toBeInTheDocument();
});
});
describe("styling", () => {
it("renders within a bordered container", () => {
const { container } = render(
<NutritionPanel nutrition={baseNutrition} />,
);
const panel = container.firstChild as HTMLElement;
expect(panel).toHaveClass("rounded-lg", "border", "p-4");
});
it("renders heading with semibold font", () => {
render(<NutritionPanel nutrition={baseNutrition} />);
const heading = screen.getByText("NUTRITION TODAY");
expect(heading).toHaveClass("font-semibold");
});
});
});