import { screen, waitFor, within } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { describe, expect, it } from "vitest"; import { ApiError } from "../src/api/client"; import { fakeApi, renderApp, samplePlayerState, sampleTutorialBoard, unauthorized } from "./render"; describe("guest onboarding", () => { it("shows the start screen without a session; starting goes straight to the contracts with an intro", async () => { // Like the real server: no session until the guest is created. let signedUp = false; const api = fakeApi({ getPlayerState: () => (signedUp ? samplePlayerState() : unauthorized()), createGuest: () => { signedUp = true; return { playerId: "p1", state: samplePlayerState() }; }, getTutorialBoard: () => sampleTutorialBoard(), }); renderApp(api, "/fleet"); const start = await screen.findByRole("button", { name: "Start your company" }); expect(screen.queryByRole("navigation", { name: "Main" })).not.toBeInTheDocument(); await userEvent.click(start); expect(api.call).toHaveBeenCalledWith("createGuest", {}); // Lands on Contracts with the intro and the light contract suggested. expect(await screen.findByRole("heading", { level: 1, name: "Contracts" })).toBeInTheDocument(); expect(screen.getByLabelText("Intro")).toHaveTextContent( "Halvorsen Lunar Freight needs a pilot.", ); const suggested = (await screen.findByText("Suggested")).closest("li")!; expect(suggested).toHaveTextContent("5 t"); // One tap sends the first run. await userEvent.click(within(suggested).getByRole("button", { name: "Fly it" })); await waitFor(() => expect(api.call).toHaveBeenCalledWith("createDispatch", { kind: "tutorial", contractId: "tutorial:earth:1:0:0", }), ); }); it("skips the start screen when a stored session is still valid", async () => { const api = fakeApi({ getPlayerState: () => samplePlayerState() }); renderApp(api); expect(await screen.findByRole("heading", { level: 1, name: "HQ" })).toBeInTheDocument(); expect(screen.queryByRole("button", { name: "Start your company" })).not.toBeInTheDocument(); expect(api.call).not.toHaveBeenCalledWith("createGuest", expect.anything()); }); it("shows an error and stays on the start screen if creating the guest fails", async () => { const api = fakeApi({ getPlayerState: unauthorized, createGuest: () => { throw new ApiError(500, "internal-error", "boom"); }, }); renderApp(api); await userEvent.click(await screen.findByRole("button", { name: "Start your company" })); expect(await screen.findByRole("alert")).toHaveTextContent("Could not start a company"); expect(screen.getByRole("button", { name: "Start your company" })).toBeEnabled(); }); });