import { describe, it, expect } from "vitest"; import { render, screen } from "@testing-library/react"; import { BrowserRouter } from "react-router"; import { UpcomingCalendarPanel } from "../UpcomingCalendarPanel"; import type { CalendarPanelEvent } from "../UpcomingCalendarPanel"; function renderWithRouter(ui: React.ReactElement) { return render({ui}); } function makeEvent(overrides: Partial = {}): CalendarPanelEvent { return { id: overrides.id ?? "event-1", name: overrides.name ?? "UCL Quarterfinals", // Use explicit key check so callers can pass null to test the null-date path eventDate: "eventDate" in overrides ? (overrides.eventDate as string | null) : "2099-04-09", earliestGameTime: "earliestGameTime" in overrides ? (overrides.earliestGameTime as string | null) : null, matchLabel: overrides.matchLabel ?? null, eventType: overrides.eventType ?? "playoff_game", sportsSeasonId: overrides.sportsSeasonId ?? "ss-1", sportName: overrides.sportName ?? "Football", sportSeasonName: overrides.sportSeasonName ?? "UCL 2025", leagueName: overrides.leagueName, leagueId: overrides.leagueId, sportsSeasonPageUrl: overrides.sportsSeasonPageUrl, relevantParticipants: overrides.relevantParticipants ?? [ { id: "p1", name: "Man City" }, ], }; } describe("UpcomingCalendarPanel", () => { describe("empty state", () => { it("shows empty state message when no events", () => { renderWithRouter(); expect(screen.getByText(/No upcoming events in the next 30 days/i)).toBeInTheDocument(); }); it("renders the panel title", () => { renderWithRouter(); expect(screen.getByText("Upcoming Events")).toBeInTheDocument(); }); }); describe("event display", () => { it("shows event name and formatted date", () => { renderWithRouter( ); expect(screen.getByText("UCL QF")).toBeInTheDocument(); expect(screen.getByText("Apr 9")).toBeInTheDocument(); }); it("shows sport name and season name", () => { renderWithRouter( ); expect(screen.getByText(/Football · UCL 2025/)).toBeInTheDocument(); }); it("shows participant badge for bracket events", () => { renderWithRouter( ); expect(screen.getByText("Man City")).toBeInTheDocument(); }); it("shows 'N of your picks' for all-compete events with multiple participants", () => { renderWithRouter( ); expect(screen.getByText("5 of your picks")).toBeInTheDocument(); }); it("renders TBD when both eventDate and earliestGameTime are null", () => { renderWithRouter( ); expect(screen.getByText("TBD")).toBeInTheDocument(); }); it("uses earliestGameTime date when eventDate is null", () => { renderWithRouter( ); // Should not show TBD expect(screen.queryByText("TBD")).not.toBeInTheDocument(); }); it("shows matchLabel appended to event name when present", () => { renderWithRouter( ); expect(screen.getByText(/PDC World Championship — Semifinals Game #1/)).toBeInTheDocument(); }); it("shows plain event name when matchLabel is null", () => { renderWithRouter( ); expect(screen.getByText("UCL QF")).toBeInTheDocument(); }); }); describe("participant overflow", () => { it("shows first 3 participants and an overflow badge for 4+", () => { renderWithRouter( ); expect(screen.getByText("Alpha")).toBeInTheDocument(); expect(screen.getByText("Beta")).toBeInTheDocument(); expect(screen.getByText("Gamma")).toBeInTheDocument(); expect(screen.queryByText("Delta")).not.toBeInTheDocument(); expect(screen.getByText("+2 more")).toBeInTheDocument(); }); it("shows all participants when exactly 3", () => { renderWithRouter( ); expect(screen.getByText("Alpha")).toBeInTheDocument(); expect(screen.getByText("Gamma")).toBeInTheDocument(); expect(screen.queryByText(/\+\d+ more/)).not.toBeInTheDocument(); }); }); describe("league display", () => { it("does not show league name when showLeague is false (default)", () => { renderWithRouter( ); expect(screen.queryByText("My League")).not.toBeInTheDocument(); }); it("shows league name badge when showLeague is true", () => { renderWithRouter( ); expect(screen.getByText("My League")).toBeInTheDocument(); }); it("renders multiple events from different leagues", () => { renderWithRouter( ); expect(screen.getByText("League A")).toBeInTheDocument(); expect(screen.getByText("League B")).toBeInTheDocument(); }); }); describe("link behaviour", () => { it("wraps event row in a link when sportsSeasonPageUrl is provided", () => { renderWithRouter( ); const link = screen.getByRole("link"); expect(link).toHaveAttribute("href", "/leagues/l1/sports-seasons/ss1"); }); }); });