import { content } from "@deadhead/content"; import { screen, within } from "@testing-library/react"; import { afterEach, describe, expect, it, vi } from "vitest"; import { useClock } from "../src/clock/clock"; import { fakeApi, renderApp, samplePlayerState } from "./render"; // The map is fixed (CR-015): any time gives the same reach. const NOW = Date.parse(content.config.epoch.realStart) + 3_600_000; async function reachOf(modelName: string, now: number) { vi.useFakeTimers({ toFake: ["Date"] }); vi.setSystemTime(now); useClock.setState({ offsetMs: 0, synced: true, now }); renderApp( fakeApi({ getPlayerState: () => samplePlayerState({ bays: [{ id: "b-earth", locationId: "earth" }] }), }), "/market", ); const card = (await screen.findByRole("button", { name: `Buy ${modelName}` })).closest("li")!; return within(card).getByLabelText("Reach").textContent ?? ""; } describe("market roles and reach (Step 10L.7)", () => { afterEach(() => vi.useRealTimers()); it("shows each model's role", async () => { renderApp(fakeApi({ getPlayerState: () => samplePlayerState() }), "/market"); for (const model of content.purchasableShipModels) { expect(await screen.findByText(model.role)).toBeInTheDocument(); } }); it("lists Mars from Earth for a Clipper, and Ceres by hopping", async () => { const near = await reachOf("Clipper", NOW); expect(near).toContain("From Earth now: Moon, Mars"); expect(near).toContain("By hopping: Ceres Station"); }); it("lists only the Moon for a Lighter", async () => { const reach = await reachOf("Lighter", NOW); expect(reach).toBe("Reach From Earth now: Moon"); }); });