import { content } from "@deadhead/content"; import type { PlayerState } from "@deadhead/schema"; import { screen, waitFor, within } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { describe, expect, it } from "vitest"; import { fakeApi, renderApp, samplePlayerState, shipExtras } from "./render"; function returningPlayer(acknowledged: boolean): PlayerState { return samplePlayerState({ tutorial: null, company: { id: "c", name: "D", credits: 900, loanBalance: 4000 }, ships: [ { id: "s1", modelId: "courier", name: "Dusty Mule", status: "idle", locationId: "moon", dispatchId: null, lastArrivalAt: 0, ...shipExtras("courier"), pilotId: "avatar", }, ], summaries: acknowledged ? [] : [ { dispatchId: "d1", shipId: "s1", pilotId: "avatar", originId: "earth", destinationId: "moon", tutorial: false, credits: 538, deadhead: false, independent: false, fuelCost: 0, topUp: null, goodId: "consumer-goods", massTonnes: 12, shipper: "Pacific Orbital Logistics", loanRepayment: 230, pilotPay: 0, pilotXp: 10, discoveredLocationId: null, scriptedId: null, restEndsAt: null, resolvedAt: 1, }, ], goals: content.onboardingGoals.map((g) => ({ id: g.id, status: g.id === "first-own-delivery" ? "ready" : "incomplete", })), }); } describe("something waiting on return", () => { it("lists ready goals alongside the delivery, and the link opens HQ's goals", async () => { let acknowledged = false; const api = fakeApi({ getPlayerState: () => returningPlayer(acknowledged), acknowledgeSummaries: () => { acknowledged = true; return { acknowledged: 1 }; }, }); renderApp(api, "/fleet"); const dialog = await screen.findByRole("dialog", { name: "While you were away" }); expect(dialog).toHaveTextContent("Dusty Mule"); const ready = within(dialog).getByRole("list", { name: "Ready goals" }); expect(ready).toHaveTextContent(content.onboardingGoal("first-own-delivery")!.title); await userEvent.click(within(dialog).getByRole("button", { name: "Claim on the Bridge" })); expect(screen.queryByRole("dialog", { name: "While you were away" })).not.toBeInTheDocument(); expect(await screen.findByRole("heading", { level: 1, name: "Dashboard" })).toBeInTheDocument(); const goals = screen.getByRole("region", { name: "Goals" }); expect(within(goals).getByRole("button", { name: "Claim" })).toBeInTheDocument(); await waitFor(() => expect(api.call).toHaveBeenCalledWith("acknowledgeSummaries", { dispatchIds: ["d1"] }), ); }); it("does not list goals when none are ready", async () => { const state = returningPlayer(false); const quiet = { ...state, goals: state.goals.map((g) => ({ ...g, status: "incomplete" as const })), }; renderApp(fakeApi({ getPlayerState: () => quiet })); const dialog = await screen.findByRole("dialog", { name: "While you were away" }); expect(within(dialog).queryByRole("list", { name: "Ready goals" })).not.toBeInTheDocument(); }); });