import type { Pilot, ResolutionSummary } from "@deadhead/schema"; import { screen, within } from "@testing-library/react"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { useClock } from "../src/clock/clock"; import { formatLocalTime } from "../src/screens/DispatchSheet"; import { fakeApi, renderApp, samplePlayerState } from "./render"; const NOW = Date.parse("2100-01-01T00:00:00Z"); const pilot = (id: string, name: string, extra: Partial = {}): Pilot => ({ id, name, isAvatar: false, xp: 0, level: 0, skills: {}, skillPointsAvailable: 0, assignedShipId: null, status: "idle", locationId: "earth", dutyHours: 0, dutyLimit: 12, resting: false, restEndsAt: null, ...extra, }); const summary = (extra: Partial): ResolutionSummary => ({ dispatchId: "d1", shipId: "s1", pilotId: "p-rae", originId: "earth", destinationId: "moon", tutorial: false, credits: 500, loanRepayment: 0, pilotXp: 10, discoveredLocationId: null, scriptedId: null, restEndsAt: null, resolvedAt: NOW, ...extra, }); const pilots = [ pilot("p-rae", "Rae Okafor", { resting: true, restEndsAt: NOW + 40 * 60_000 }), pilot("p-jun", "Jun Sato", { resting: true, restEndsAt: NOW + 9 * 60_000 }), pilot("p-cy", "Cy Fresh"), ]; describe("rest in summaries and on HQ (Step 10D.9)", () => { beforeEach(() => { vi.useFakeTimers({ toFake: ["Date", "setInterval", "clearInterval"] }); vi.setSystemTime(NOW); useClock.setState({ offsetMs: 0, synced: true, now: NOW }); }); afterEach(() => vi.useRealTimers()); it("says in the away summary that a pilot is resting, only for trips that ended in rest", async () => { const restEndsAt = NOW + 40 * 60_000; renderApp( fakeApi({ getPlayerState: () => samplePlayerState({ tutorial: null, pilots, summaries: [ summary({ dispatchId: "d1", restEndsAt }), summary({ dispatchId: "d2", pilotId: "p-cy" }), ], }), }), "/", ); const dialog = await screen.findByRole("dialog", { name: "While you were away" }); const [rested, plain] = within(dialog).getAllByRole("listitem"); expect(rested).toHaveTextContent(`Rae Okafor is resting until ${formatLocalTime(restEndsAt)}`); expect(plain).not.toHaveTextContent("resting"); }); it("shows how many pilots are resting and who wakes first", async () => { renderApp( fakeApi({ getPlayerState: () => samplePlayerState({ tutorial: null, pilots }) }), "/", ); const card = await screen.findByLabelText("Pilot rest"); expect(card).toHaveTextContent("Pilots resting: 2"); expect(card).toHaveTextContent("Jun Sato wakes in 9m 00s"); }); });