SportIcon renders <img> elements whose onError handler calls setFailed(true), scheduling state updates asynchronously outside React act() in jsdom. With multiple icons on the Sports page this caused the synchronous render test to hit the 5000ms Vitest timeout intermittently. Mock SportIcon in the test using resolveSportIconUrl() so the mock stays in sync with the real URL resolution logic if it ever changes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
123 lines
3.9 KiB
TypeScript
123 lines
3.9 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
import { render, screen } from "@testing-library/react";
|
|
import { BrowserRouter } from "react-router";
|
|
|
|
vi.mock("~/models/sport", () => ({
|
|
findPublicSportsWithCurrentSeasons: vi.fn(),
|
|
}));
|
|
|
|
vi.mock("~/components/SportIcon", async () => {
|
|
const { resolveSportIconUrl } = await import("~/lib/sport-icon-url");
|
|
return {
|
|
SportIcon: ({ sportName, iconUrl }: { sportName: string; iconUrl?: string | null }) => {
|
|
const src = resolveSportIconUrl(iconUrl);
|
|
return src ? <img src={src} alt={sportName} /> : null;
|
|
},
|
|
};
|
|
});
|
|
|
|
import Sports, { loader } from "../sports";
|
|
import { findPublicSportsWithCurrentSeasons } from "~/models/sport";
|
|
import type { PublicSportWithCurrentSeasons } from "~/models/sport";
|
|
|
|
const sports: PublicSportWithCurrentSeasons[] = [
|
|
{
|
|
id: "nfl",
|
|
name: "NFL",
|
|
type: "team",
|
|
slug: "nfl",
|
|
description: "Draft teams in the NFL postseason.",
|
|
iconUrl: "nfl.svg",
|
|
simulatorType: "nfl_bracket",
|
|
excludeFromHomepage: false,
|
|
createdAt: new Date("2026-01-01T00:00:00Z"),
|
|
updatedAt: new Date("2026-01-01T00:00:00Z"),
|
|
currentSeasons: [
|
|
{
|
|
id: "nfl-2026",
|
|
name: "NFL 2026",
|
|
year: 2026,
|
|
status: "active",
|
|
scoringPattern: "playoff_bracket",
|
|
scoringType: "playoffs",
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: "tennis",
|
|
name: "Tennis",
|
|
type: "individual",
|
|
slug: "tennis",
|
|
description: null,
|
|
iconUrl: null,
|
|
simulatorType: "tennis_qualifying_points",
|
|
excludeFromHomepage: false,
|
|
createdAt: new Date("2026-01-01T00:00:00Z"),
|
|
updatedAt: new Date("2026-01-01T00:00:00Z"),
|
|
currentSeasons: [
|
|
{
|
|
id: "tennis-2026",
|
|
name: "Tennis Majors 2026",
|
|
year: 2026,
|
|
status: "upcoming",
|
|
scoringPattern: "qualifying_points",
|
|
scoringType: "majors",
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: "f1",
|
|
name: "Formula 1",
|
|
type: "individual",
|
|
slug: "f1",
|
|
description: "Draft drivers for the full season.",
|
|
iconUrl: "f1.svg",
|
|
simulatorType: "f1_standings",
|
|
excludeFromHomepage: false,
|
|
createdAt: new Date("2026-01-01T00:00:00Z"),
|
|
updatedAt: new Date("2026-01-01T00:00:00Z"),
|
|
currentSeasons: [
|
|
{
|
|
id: "f1-2026",
|
|
name: "Formula 1 2026",
|
|
year: 2026,
|
|
status: "active",
|
|
scoringPattern: "season_standings",
|
|
scoringType: "regular_season",
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
function renderSports(loaderData = { sports }) {
|
|
return render(
|
|
<BrowserRouter>
|
|
<Sports loaderData={loaderData} params={{}} matches={[] as never} />
|
|
</BrowserRouter>
|
|
);
|
|
}
|
|
|
|
describe("/sports route", () => {
|
|
it("loads public sports from the model", async () => {
|
|
vi.mocked(findPublicSportsWithCurrentSeasons).mockResolvedValue(sports);
|
|
|
|
await expect(loader()).resolves.toEqual({ sports });
|
|
});
|
|
|
|
it("renders the sport count, groups, cards, and support CTA", () => {
|
|
renderSports();
|
|
|
|
expect(screen.getByRole("heading", { name: "Sports" })).toBeInTheDocument();
|
|
expect(screen.getByText(/Brackt currently supports 3 sports/i)).toBeInTheDocument();
|
|
expect(screen.getByRole("heading", { name: "Playoffs" })).toBeInTheDocument();
|
|
expect(screen.getByRole("heading", { name: "Season-Long Standings" })).toBeInTheDocument();
|
|
expect(screen.getByRole("heading", { name: "Majors" })).toBeInTheDocument();
|
|
expect(screen.getByText("NFL")).toBeInTheDocument();
|
|
expect(screen.getByText("Draft teams in the NFL postseason.")).toBeInTheDocument();
|
|
expect(screen.getByAltText("NFL")).toHaveAttribute("src", "/sports-icons/nfl.svg");
|
|
expect(screen.getByText("Available for Brackt leagues.")).toBeInTheDocument();
|
|
expect(screen.queryByText(/^1 active season$/i)).not.toBeInTheDocument();
|
|
expect(screen.queryByText("Tennis Majors 2026")).not.toBeInTheDocument();
|
|
expect(screen.getByRole("link", { name: /contact support/i })).toHaveAttribute("href", "/support");
|
|
});
|
|
});
|