From a26294446d4deb39588e68531a8d225d4c5cfc9e Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 7 May 2026 00:53:07 +0000 Subject: [PATCH] Add StandingsPreview component tests covering avatar rendering Tests were missing for the StandingsPreview component, which is the component that actually renders team avatars on the full standings page. Covers uploaded image, flag SVG, owner avatar inheritance, and the generated-flag fallback, plus basic content rendering (team names, owner names, points, description, full standings link). https://claude.ai/code/session_01CVt5Vo2PDGY4G3wSWbsmRG --- .../__tests__/StandingsPreview.test.tsx | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 app/components/league/__tests__/StandingsPreview.test.tsx 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"); + }); + }); +});