deadhead-space-freight-tycoon/apps/web/test/locations.test.tsx

83 lines
3.4 KiB
TypeScript

import { content } from "@deadhead/content";
import { screen, within } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { describe, expect, it } from "vitest";
import { HQ_EXPLANATION } from "../src/screens/Locations";
import { fakeApi, renderApp, samplePlayerState } from "./render";
const item = (name: string) => screen.getByText(name).closest("li")!;
describe("locations screen", () => {
it("hides details of undiscovered locations", async () => {
renderApp(fakeApi({ getPlayerState: () => samplePlayerState() }), "/locations");
await screen.findByText("Mars");
const mars = item("Mars");
expect(mars).toHaveTextContent("Undiscovered — deliver here to unlock.");
expect(mars).not.toHaveTextContent("Produces");
expect(within(mars).queryByRole("button")).not.toBeInTheDocument();
});
it("shows details of discovered locations, with distance from Earth", async () => {
renderApp(fakeApi({ getPlayerState: () => samplePlayerState() }), "/locations");
await screen.findByText("Moon");
const moon = item("Moon");
expect(moon).toHaveTextContent("TypeAirless body");
expect(moon).toHaveTextContent("LandingAny ship");
expect(moon).toHaveTextContent("ProducesStandard, Heavy");
expect(moon).toHaveTextContent(/M km from Earth/);
expect(item("Earth")).toHaveTextContent("Home");
});
it("offers leasing, with the HQ explanation, only at discovered locations without a bay", async () => {
const api = fakeApi({
getPlayerState: () =>
samplePlayerState({
company: { id: "c", name: "D", credits: 100_000, loanBalance: 0 },
bays: [{ id: "b1", locationId: "earth" }],
}),
});
renderApp(api, "/locations");
await screen.findByText("Moon");
expect(item("Earth")).toHaveTextContent("Your HQ is here");
expect(within(item("Earth")).queryByRole("button")).not.toBeInTheDocument();
expect(item("Earth")).not.toHaveTextContent(HQ_EXPLANATION);
expect(item("Moon")).toHaveTextContent(
"Open an HQ here: hire pilots and take delivery of new ships at this location.",
);
const moonPrice = content.location("moon")!.bayLeasePrice;
const lease = within(item("Moon")).getByRole("button", { name: "Lease bay at Moon" });
expect(lease).toHaveTextContent(`Lease bay (${moonPrice.toLocaleString("en-US")} cr)`);
await userEvent.click(lease);
expect(api.call).toHaveBeenCalledWith("leaseBay", { locationId: "moon" });
expect(screen.queryByRole("button", { name: "Lease bay at Mars" })).not.toBeInTheDocument();
});
it("links every discovered location to its contracts, with or without a bay", async () => {
renderApp(
fakeApi({
getPlayerState: () => samplePlayerState({ bays: [{ id: "b1", locationId: "earth" }] }),
}),
"/locations",
);
await screen.findByText("Moon");
for (const [name, id] of [
["Earth", "earth"],
["Moon", "moon"],
] as const) {
expect(within(item(name)).getByRole("link", { name: "View contracts" })).toHaveAttribute(
"href",
`/contracts?location=${id}`,
);
}
expect(within(item("Mars")).queryByRole("link")).not.toBeInTheDocument();
});
it("disables leasing the player cannot afford", async () => {
renderApp(fakeApi({ getPlayerState: () => samplePlayerState() }), "/locations");
expect(await screen.findByRole("button", { name: "Lease bay at Earth" })).toBeDisabled();
});
});