deadhead-space-freight-tycoon/apps/web/test/away-goals.test.tsx

95 lines
3.3 KiB
TypeScript

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,
fuelCost: 0,
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 HQ" }));
expect(screen.queryByRole("dialog", { name: "While you were away" })).not.toBeInTheDocument();
expect(await screen.findByRole("heading", { level: 1, name: "HQ" })).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();
});
});