// Vitest coverage for the report view's race-exit-warnings section and // the personal exit-warning banner. The section lists other races // within a few turns of inactivity removal and hides entirely when the // list is empty; the banner shows the local race's own countdown only // when it is non-zero. Both read the report through the rendered-report // context, mirroring the other report sections. import "@testing-library/jest-dom/vitest"; import { render } from "@testing-library/svelte"; import { beforeEach, describe, expect, test } from "vitest"; import { i18n } from "../src/lib/i18n/index.svelte"; import type { GameReport } from "../src/api/game-state"; import { RENDERED_REPORT_CONTEXT_KEY } from "../src/lib/rendered-report.svelte"; import { EMPTY_SHIP_GROUPS } from "./helpers/empty-ship-groups"; import SectionRaceExitWarnings from "../src/lib/active-view/report/section-race-exit-warnings.svelte"; import PersonalExitBanner from "../src/lib/active-view/report/personal-exit-banner.svelte"; beforeEach(() => { i18n.resetForTests("en"); }); function makeReport(overrides: Partial = {}): GameReport { return { turn: 1, mapWidth: 1000, mapHeight: 1000, planetCount: 0, planets: [], race: "Self", localShipClass: [], routes: [], localPlayerDrive: 0, localPlayerWeapons: 0, localPlayerShields: 0, localPlayerCargo: 0, ...EMPTY_SHIP_GROUPS, ...overrides, }; } function mount( component: typeof SectionRaceExitWarnings | typeof PersonalExitBanner, report: GameReport | null, ) { const context = new Map([ [ RENDERED_REPORT_CONTEXT_KEY, { get report() { return report; }, }, ], ]); return render(component, { context }); } describe("report race-exit-warnings section", () => { test("renders nothing before the report lands", () => { const ui = mount(SectionRaceExitWarnings, null); expect( ui.queryByTestId("report-section-race-exit-warnings"), ).not.toBeInTheDocument(); }); test("hides the section entirely when no races are leaving", () => { const ui = mount( SectionRaceExitWarnings, makeReport({ racesLeavingSoon: [] }), ); expect( ui.queryByTestId("report-section-race-exit-warnings"), ).not.toBeInTheDocument(); }); test("lists each race with its remaining turns", () => { const ui = mount( SectionRaceExitWarnings, makeReport({ racesLeavingSoon: [ { race: "Bajori", turnsLeft: 2 }, { race: "Cardassian", turnsLeft: 1 }, ], }), ); expect( ui.getByTestId("report-section-race-exit-warnings"), ).toBeInTheDocument(); const rows = ui.getAllByTestId("race-exit-warnings-row"); expect(rows).toHaveLength(2); expect(rows[0]).toHaveAttribute("data-race", "Bajori"); expect(rows[0]).toHaveTextContent("Bajori"); expect(rows[0]).toHaveTextContent("2"); expect(rows[1]).toHaveAttribute("data-race", "Cardassian"); expect(rows[1]).toHaveTextContent("Cardassian"); expect(rows[1]).toHaveTextContent("1"); }); }); describe("personal exit-warning banner", () => { test("renders nothing before the report lands", () => { const ui = mount(PersonalExitBanner, null); expect( ui.queryByTestId("report-personal-exit-banner"), ).not.toBeInTheDocument(); }); test("stays hidden when there is no personal warning", () => { const ui = mount( PersonalExitBanner, makeReport({ personalExitWarning: 0 }), ); expect( ui.queryByTestId("report-personal-exit-banner"), ).not.toBeInTheDocument(); }); test("shows the danger banner with the countdown when warned", () => { const ui = mount( PersonalExitBanner, makeReport({ personalExitWarning: 3 }), ); const banner = ui.getByTestId("report-personal-exit-banner"); expect(banner).toBeInTheDocument(); expect(banner).toHaveAttribute("role", "alert"); expect(banner).toHaveTextContent("3"); }); });