import type { PlayerState, RadioCall, Ship } from "@deadhead/schema"; import { screen, within } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { describe, expect, it } from "vitest"; import { needsYou } from "../src/components/NeedsYou"; import { tabAttention } from "../src/layout/attention"; import { fakeApi, renderApp, samplePlayerState, shipExtras } from "./render"; const base = samplePlayerState(); const avatar = base.pilots[0]!; const ship: Ship = { id: "s1", modelId: "courier", name: "Restless Sparrow", status: "idle", locationId: "earth", dispatchId: null, lastArrivalAt: 0, ...shipExtras("courier"), pilotId: "avatar", }; const owner = (overrides: Partial = {}): PlayerState => samplePlayerState({ tutorial: null, ships: [ship], bays: [{ id: "b", locationId: "earth" }], pilots: [{ ...avatar, assignedShipId: "s1", skillPointsAvailable: 2 }], goals: [{ id: "buy-a-ship", status: "ready" }], ...overrides, } as Partial); const call = { dispatchId: "d1", eventId: "debris-field", pilotId: avatar.id } as RadioCall; describe("Needs you (decision 0.5.168)", () => { it("orders radio calls, ready ships, skill points, then goals", () => { const items = needsYou(owner({ radioCalls: [{ ...call, windowEndsAt: 1 }] })); expect(items.map((i) => i.kind)).toEqual(["radio", "ready", "skills", "goal"]); }); it("badges count what the list holds, tab by tab", () => { const state = owner({ radioCalls: [{ ...call, windowEndsAt: 1 }] }); const items = needsYou(state); const badges = tabAttention(state); expect(badges).toEqual({ "/": 2, "/contracts": 1, "/fleet": 2 }); const total = items.reduce((sum, i) => sum + i.count, 0); expect(Object.values(badges).reduce((sum, n) => sum + n, 0)).toBe(total); }); it("names who has skill points and opens Crew", async () => { renderApp(fakeApi({ getPlayerState: () => owner() })); const list = await screen.findByRole("region", { name: "Needs you" }); await userEvent.click(within(list).getByRole("link", { name: /2 skill points to spend/ })); expect(await screen.findByRole("heading", { level: 1, name: "Crew" })).toBeInTheDocument(); }); it("sends a ready ship to the jobs where it is", async () => { renderApp( fakeApi({ getPlayerState: () => owner(), getContractBoard: () => ({ contracts: [], periodEndsAt: Date.now() + 60_000 }) as never, }), ); const list = await screen.findByRole("region", { name: "Needs you" }); expect(within(list).getByRole("link", { name: /Restless Sparrow is ready/ })).toHaveAttribute( "href", "/contracts?location=earth", ); }); });