brackt/app/components/sports/__tests__/SportSeasonCard.test.tsx
2026-03-12 10:12:38 -07:00

215 lines
7.5 KiB
TypeScript

import { describe, it, expect } from "vitest";
import { render, screen } from "@testing-library/react";
import { BrowserRouter } from "react-router";
import { SportSeasonCard } from "../SportSeasonCard";
import type { UpcomingParticipantEvent } from "~/models/scoring-event";
function renderWithRouter(ui: React.ReactElement) {
return render(<BrowserRouter>{ui}</BrowserRouter>);
}
function makeEvent(overrides: Partial<UpcomingParticipantEvent> = {}): UpcomingParticipantEvent {
return {
id: overrides.id ?? "event-1",
name: overrides.name ?? "UCL Quarterfinals",
eventDate: overrides.eventDate ?? "2025-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",
relevantParticipants: overrides.relevantParticipants ?? [
{ id: "p1", name: "Man City" },
],
};
}
const BASE_PROPS = {
leagueId: "league-1",
sportSeasonId: "ss-1",
sportName: "Football",
seasonName: "UCL 2025",
status: "active" as const,
};
describe("SportSeasonCard", () => {
describe("base rendering", () => {
it("shows sport name and season name", () => {
renderWithRouter(<SportSeasonCard {...BASE_PROPS} />);
expect(screen.getByText("Football")).toBeInTheDocument();
expect(screen.getByText("UCL 2025")).toBeInTheDocument();
});
it("links to the sports season page", () => {
renderWithRouter(<SportSeasonCard {...BASE_PROPS} />);
expect(screen.getByRole("link")).toHaveAttribute(
"href",
"/leagues/league-1/sports-seasons/ss-1"
);
});
it("shows Active badge for active status", () => {
renderWithRouter(<SportSeasonCard {...BASE_PROPS} status="active" />);
expect(screen.getByText("Active")).toBeInTheDocument();
});
it("shows Upcoming badge for upcoming status", () => {
renderWithRouter(<SportSeasonCard {...BASE_PROPS} status="upcoming" />);
expect(screen.getByText("Upcoming")).toBeInTheDocument();
});
it("shows Completed badge for completed status", () => {
renderWithRouter(<SportSeasonCard {...BASE_PROPS} status="completed" />);
expect(screen.getByText("Completed")).toBeInTheDocument();
});
});
describe("no upcoming events", () => {
it("renders without error when upcomingParticipantEvents is empty", () => {
renderWithRouter(<SportSeasonCard {...BASE_PROPS} upcomingParticipantEvents={[]} />);
expect(screen.getByText("Football")).toBeInTheDocument();
});
it("renders without error when upcomingParticipantEvents is omitted (pre-draft)", () => {
renderWithRouter(<SportSeasonCard {...BASE_PROPS} />);
expect(screen.getByText("Football")).toBeInTheDocument();
});
});
describe("bracket event display", () => {
it("shows event name and date for a bracket event", () => {
renderWithRouter(
<SportSeasonCard
{...BASE_PROPS}
upcomingParticipantEvents={[
makeEvent({ name: "UCL QF", eventDate: "2025-04-09", eventType: "playoff_game" }),
]}
/>
);
expect(screen.getByText("UCL QF")).toBeInTheDocument();
expect(screen.getByText("— Apr 9")).toBeInTheDocument();
});
it("shows participant badge for bracket events with one pick", () => {
renderWithRouter(
<SportSeasonCard
{...BASE_PROPS}
upcomingParticipantEvents={[
makeEvent({
eventType: "playoff_game",
relevantParticipants: [{ id: "p1", name: "Man City" }],
}),
]}
/>
);
expect(screen.getByText("Man City")).toBeInTheDocument();
});
it("shows participant badges for two picks in same bracket event", () => {
renderWithRouter(
<SportSeasonCard
{...BASE_PROPS}
upcomingParticipantEvents={[
makeEvent({
eventType: "playoff_game",
relevantParticipants: [
{ id: "p1", name: "Man City" },
{ id: "p2", name: "Arsenal" },
],
}),
]}
/>
);
expect(screen.getByText("Man City")).toBeInTheDocument();
expect(screen.getByText("Arsenal")).toBeInTheDocument();
});
});
describe("all-compete event display", () => {
it("shows participant count badge for schedule_event with multiple picks", () => {
renderWithRouter(
<SportSeasonCard
{...BASE_PROPS}
upcomingParticipantEvents={[
makeEvent({
eventType: "schedule_event",
name: "Australian GP",
relevantParticipants: [
{ id: "p1", name: "Verstappen" },
{ id: "p2", name: "Hamilton" },
{ id: "p3", name: "Leclerc" },
{ id: "p4", name: "Norris" },
{ id: "p5", name: "Russell" },
],
}),
]}
/>
);
// Shows count badge, not individual names
expect(screen.getByText("5")).toBeInTheDocument();
expect(screen.queryByText("Verstappen")).not.toBeInTheDocument();
});
});
describe("event overflow", () => {
it("shows up to 3 events without overflow message", () => {
renderWithRouter(
<SportSeasonCard
{...BASE_PROPS}
upcomingParticipantEvents={[
makeEvent({ id: "e1", name: "Event One" }),
makeEvent({ id: "e2", name: "Event Two" }),
makeEvent({ id: "e3", name: "Event Three" }),
]}
/>
);
expect(screen.getByText("Event One")).toBeInTheDocument();
expect(screen.getByText("Event Three")).toBeInTheDocument();
expect(screen.queryByText(/more event/i)).not.toBeInTheDocument();
});
it("shows overflow count when more than 3 events", () => {
renderWithRouter(
<SportSeasonCard
{...BASE_PROPS}
upcomingParticipantEvents={[
makeEvent({ id: "e1", name: "Event One" }),
makeEvent({ id: "e2", name: "Event Two" }),
makeEvent({ id: "e3", name: "Event Three" }),
makeEvent({ id: "e4", name: "Event Four" }),
makeEvent({ id: "e5", name: "Event Five" }),
]}
/>
);
expect(screen.getByText("Event One")).toBeInTheDocument();
expect(screen.queryByText("Event Four")).not.toBeInTheDocument();
expect(screen.getByText("+2 more events")).toBeInTheDocument();
});
it("uses singular 'event' when overflow is 1", () => {
renderWithRouter(
<SportSeasonCard
{...BASE_PROPS}
upcomingParticipantEvents={[
makeEvent({ id: "e1", name: "Event One" }),
makeEvent({ id: "e2", name: "Event Two" }),
makeEvent({ id: "e3", name: "Event Three" }),
makeEvent({ id: "e4", name: "Event Four" }),
]}
/>
);
expect(screen.getByText("+1 more event")).toBeInTheDocument();
});
});
describe("scoring pattern label", () => {
it("shows Playoff Bracket label", () => {
renderWithRouter(<SportSeasonCard {...BASE_PROPS} scoringPattern="playoff_bracket" />);
expect(screen.getByText("Playoff Bracket")).toBeInTheDocument();
});
it("shows Season Standings label", () => {
renderWithRouter(<SportSeasonCard {...BASE_PROPS} scoringPattern="season_standings" />);
expect(screen.getByText("Season Standings")).toBeInTheDocument();
});
});
});