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, comeBack } 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, event: 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("highlights a goal ready to claim (claimed on the Bridge's goals card, CR-025)", async () => { comeBack(); 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/ }); const title = content.onboardingGoal("first-own-delivery")!.title; expect(await within(dialog).findByText(`Goal ready to claim: ${title}`)).toBeInTheDocument(); await userEvent.click(within(dialog).getByRole("button", { name: "Done" })); await waitFor(() => expect(api.call).toHaveBeenCalledWith("acknowledgeSummaries", { dispatchIds: ["d1"] }), ); }); it("does not mention goals when none are ready", async () => { comeBack(); 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/ }); await within(dialog).findByRole("list", { name: "What happened" }); expect(dialog).not.toHaveTextContent("Goal ready"); }); });