import type { PlayerState, RouteName, RouteRequest, RouteResponse } from "@deadhead/schema"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { render } from "@testing-library/react"; import { MemoryRouter } from "react-router"; import { vi } from "vitest"; import { App } from "../src/App"; import { ApiError, type ApiClient } from "../src/api/client"; import { ApiProvider } from "../src/api/context"; type Handlers = { [N in RouteName]?: (input: RouteRequest) => RouteResponse | Promise>; }; /** * A fake API: each route answers from its handler. Unhandled routes fail with * `not-found`; `getServerTime` defaults to the device clock. */ export function fakeApi(handlers: Handlers) { const call = vi.fn(async (name: RouteName, input: unknown) => { if (name === "getServerTime" && !handlers.getServerTime) { return { realTime: Date.now(), gameTime: 0 }; } const handler = handlers[name] as ((input: unknown) => unknown) | undefined; if (!handler) throw new ApiError(404, "not-found", `No fake for ${name}`); return handler(input); }); return { call } as unknown as ApiClient & { call: typeof call }; } export const unauthorized = () => { throw new ApiError(401, "unauthorized", "Sign in to continue."); }; /** A brand-new tutorial player, as guest sign-up returns it. */ export function samplePlayerState(overrides: Partial = {}): PlayerState { return { company: { id: "co1", name: "Deadhead Freight", credits: 0 }, ships: [], pilots: [ { id: "avatar", name: "Captain", isAvatar: true, xp: 0, level: 0, skills: {}, skillPointsAvailable: 0, assignedShipId: null, status: "idle", locationId: "earth", }, ], bays: [], locations: [ { id: "earth", discovered: true }, { id: "moon", discovered: true }, { id: "mars", discovered: false }, { id: "ceres-station", discovered: false }, { id: "jupiter-cloud-platform", discovered: false }, ], tutorial: { loanerLocationId: "earth", runInFlight: false }, activeDispatches: [], summaries: [], ...overrides, }; } /** Renders the whole app at `path` with a fresh query cache and the given API. */ export function renderApp(api: ApiClient, path = "/") { const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false }, mutations: { retry: false } }, }); const result = render( , ); return { ...result, queryClient }; }