import type { Dispatch } 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"; describe("developer tools in Settings (Step 10K.11)", () => { it("advances the clock, adds credits and finishes flights", async () => { const now = Date.now(); const flight = { id: "d1", shipId: "loaner", pilotId: "avatar", contract: null, originId: "earth", destinationId: "moon", tutorial: true, departureAt: now - 60_000, arrivalAt: now + 5 * 60_000, distanceMillionKm: 0.4, fuelCost: 0, fuelBurnedFu: 0, expectedPayout: 0, seed: 1, status: "in-flight", resolvedAt: null, } as unknown as Dispatch; const api = fakeApi({ getPlayerState: () => samplePlayerState({ activeDispatches: [flight] }), devAdvanceClock: ({ advanceMs }) => ({ offsetMs: advanceMs, realTime: now + advanceMs }), devAddCredits: ({ amount }) => ({ company: { id: "co1", name: "D", credits: amount, loanBalance: 0 }, }), }); renderApp(api, "/settings"); const dev = await screen.findByRole("region", { name: "Developer" }); await userEvent.click(within(dev).getByRole("button", { name: "Advance 10 minutes" })); await waitFor(() => expect(api.call).toHaveBeenCalledWith("devAdvanceClock", { advanceMs: 600_000 }), ); await userEvent.click(within(dev).getByRole("button", { name: "Advance 1 hour" })); await waitFor(() => expect(api.call).toHaveBeenCalledWith("devAdvanceClock", { advanceMs: 3_600_000 }), ); await userEvent.click(within(dev).getByRole("button", { name: "Add 10,000 credits" })); await waitFor(() => expect(api.call).toHaveBeenCalledWith("devAddCredits", { amount: 10_000 })); await userEvent.click(within(dev).getByRole("button", { name: "Finish all flights" })); await waitFor(() => { const advances = api.call.mock.calls.filter(([name]) => name === "devAdvanceClock"); const last = advances.at(-1)![1] as { advanceMs: number }; // To just past the last arrival (5 minutes away), give or take the test's own runtime. expect(last.advanceMs).toBeGreaterThan(5 * 60_000 - 5_000); expect(last.advanceMs).toBeLessThan(5 * 60_000 + 5_000); }); }); it("levels a pilot, maxes a ship's upgrades, moves it and discovers everywhere", async () => { const base = samplePlayerState({ tutorial: null }); const state = { ...base, ships: [ { id: "s1", modelId: "courier", name: "Dusty Mule", status: "idle" as const, locationId: "earth", dispatchId: null, lastArrivalAt: 0, ...shipExtras("courier"), pilotId: "avatar", }, ], pilots: [{ ...base.pilots[0]!, assignedShipId: "s1" }], }; const api = fakeApi({ getPlayerState: () => state, devPilot: () => state, devShip: () => state, devDiscoverAll: () => state, }); renderApp(api, "/settings"); const dev = await screen.findByRole("region", { name: "Developer" }); await userEvent.click(within(dev).getByRole("button", { name: "Level up" })); await waitFor(() => expect(api.call).toHaveBeenCalledWith("devPilot", { pilotId: "avatar", action: "level-up" }), ); await userEvent.click(within(dev).getByRole("button", { name: "Max upgrades" })); await waitFor(() => expect(api.call).toHaveBeenCalledWith("devShip", { shipId: "s1", action: "max-upgrades" }), ); // Already at Earth: pick the Moon, then move. expect(within(dev).getByRole("button", { name: "Move here" })).toBeDisabled(); await userEvent.selectOptions(within(dev).getByLabelText("Move to"), "moon"); await userEvent.click(within(dev).getByRole("button", { name: "Move here" })); await waitFor(() => expect(api.call).toHaveBeenCalledWith("devShip", { shipId: "s1", action: "move", locationId: "moon", }), ); await userEvent.click(within(dev).getByRole("button", { name: "Discover everywhere" })); await waitFor(() => expect(api.call).toHaveBeenCalledWith("devDiscoverAll", {})); }); });