import type { Contract } from "@deadhead/schema"; import { screen, within } from "@testing-library/react"; import { describe, expect, it } from "vitest"; import { fakeApi, renderApp, samplePlayerState } from "./render"; const job = (id: string, payout: number): Contract => ({ id, originId: "earth", destinationId: "moon", cargoTypeId: "standard", goodId: "mail", shipper: "Pacific Orbital Logistics", priority: false, deliveryWindowGameHours: null, tier: 0, massTonnes: 4, payout, requiredSkill: null, requiredLongHaulLevel: 0, offeredAt: Date.now(), expiresAt: Date.now() + 600_000, firstContact: false, }); const owner = () => samplePlayerState({ tutorial: null, bays: [{ id: "b", locationId: "earth" }] }); function render(boards: Contract[][], periodMs = 600_000) { let call = 0; renderApp( fakeApi({ getPlayerState: owner, getContractBoard: () => ({ contracts: boards[Math.min(call++, boards.length - 1)]!, periodEndsAt: Date.now() + periodMs, }), }), "/contracts?location=earth", ); } const remember = (ids: string[]) => localStorage.setItem("deadhead:seen-board:earth", JSON.stringify(ids)); const card = async (payout: string) => (await screen.findByText(payout)).closest("li")!; describe("visible board refresh (CR-008)", () => { it("tags contracts that weren't on the last board seen here, and says so", async () => { remember(["old-1", "old-2"]); render([[job("old-1", 111), job("new-1", 222)]]); expect(await screen.findByRole("status")).toHaveTextContent("New contracts posted"); expect(within(await card("222 cr")).getByText("New")).toBeInTheDocument(); expect(within(await card("111 cr")).queryByText("New")).not.toBeInTheDocument(); }); it("tags nothing when the board is the one already seen", async () => { remember(["old-1"]); render([[job("old-1", 111)]]); await card("111 cr"); expect(screen.queryByRole("status")).not.toBeInTheDocument(); expect(screen.queryByText("New")).not.toBeInTheDocument(); }); it("tags nothing on a first visit, but remembers the board", async () => { render([[job("a", 111)]]); await card("111 cr"); expect(screen.queryByText("New")).not.toBeInTheDocument(); expect(JSON.parse(localStorage.getItem("deadhead:seen-board:earth")!)).toEqual(["a"]); }); it("announces the new board when the timer rolls over while the page is open", async () => { render([[job("a", 111)], [job("b", 222)]], 300); await card("111 cr"); expect(await screen.findByRole("status")).toHaveTextContent("New contracts posted"); expect(within(await card("222 cr")).getByText("New")).toBeInTheDocument(); }); });