diff --git a/app/components/league/__tests__/StandingsPreview.test.tsx b/app/components/league/__tests__/StandingsPreview.test.tsx new file mode 100644 index 0000000..d692858 --- /dev/null +++ b/app/components/league/__tests__/StandingsPreview.test.tsx @@ -0,0 +1,104 @@ +import { describe, it, expect } from "vitest"; +import { render, screen } from "@testing-library/react"; +import { BrowserRouter } from "react-router"; +import { StandingsPreview, type StandingsPreviewEntry } from "../StandingsPreview"; + +function renderWithRouter(ui: React.ReactElement) { + return render({ui}); +} + +const baseEntry: StandingsPreviewEntry = { + teamId: "team-1", + teamName: "Lightning Wolves", + ownerName: "alice", + displayRank: 1, + currentRank: 1, + points: 2500, + href: "/leagues/1/standings/1/teams/team-1", +}; + +describe("StandingsPreview", () => { + describe("Avatar rendering", () => { + it("renders an img for uploaded avatar type", () => { + const entry: StandingsPreviewEntry = { + ...baseEntry, + avatarType: "uploaded", + logoUrl: "https://example.com/team-logo.png", + }; + renderWithRouter(); + + const img = screen.getByAltText("Lightning Wolves"); + expect(img.tagName).toBe("IMG"); + }); + + it("renders an SVG for flag avatar type", () => { + const entry: StandingsPreviewEntry = { + ...baseEntry, + avatarType: "flag", + flagConfig: { pattern: "triband-h", colors: ["#ff0000", "#ffffff", "#0000ff"] }, + }; + const { container } = renderWithRouter(); + + expect(container.querySelector("svg")).toBeInTheDocument(); + }); + + it("renders owner image when avatarType is owner with image ownerAvatarData", () => { + const entry: StandingsPreviewEntry = { + ...baseEntry, + avatarType: "owner", + ownerAvatarData: { type: "image", url: "https://example.com/owner.png" }, + }; + renderWithRouter(); + + const img = screen.getByAltText("Lightning Wolves"); + expect(img.tagName).toBe("IMG"); + }); + + it("falls back to a generated flag when no avatar data is provided", () => { + const entry: StandingsPreviewEntry = { ...baseEntry, avatarType: undefined }; + const { container } = renderWithRouter(); + + expect(container.querySelector("svg")).toBeInTheDocument(); + }); + }); + + describe("Basic rendering", () => { + it("renders team names for all entries", () => { + const entries: StandingsPreviewEntry[] = [ + { ...baseEntry, teamId: "t1", teamName: "Team Alpha", displayRank: 1 }, + { ...baseEntry, teamId: "t2", teamName: "Team Beta", displayRank: 2 }, + ]; + renderWithRouter(); + + expect(screen.getByText("Team Alpha")).toBeInTheDocument(); + expect(screen.getByText("Team Beta")).toBeInTheDocument(); + }); + + it("renders owner name below team name", () => { + renderWithRouter(); + + expect(screen.getByText("alice")).toBeInTheDocument(); + }); + + it("renders rounded points", () => { + renderWithRouter(); + + expect(screen.getByText("1,500")).toBeInTheDocument(); + }); + + it("renders description when provided", () => { + renderWithRouter(); + + expect(screen.getByText("Current Standings")).toBeInTheDocument(); + }); + + it("renders full standings link when fullStandingsHref is provided", () => { + renderWithRouter( + + ); + + const link = screen.getByRole("link", { name: "Full Standings" }); + expect(link).toHaveAttribute("href", "/leagues/1/standings/1"); + }); + }); +});