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

71 lines
2.7 KiB
TypeScript

import { content } from "@deadhead/content";
import type { Ship } from "@deadhead/schema";
import { screen, within } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { describe, expect, it } from "vitest";
import { fakeApi, renderApp, samplePlayerState } from "./render";
const courierPrice = content.shipModel("courier")!.price;
const freighterPrice = content.shipModel("freighter")!.price;
describe("market screen", () => {
it("lists every ship model with its stats", async () => {
renderApp(fakeApi({ getPlayerState: () => samplePlayerState() }), "/market");
const items = await screen.findAllByRole("listitem");
expect(items).toHaveLength(content.purchasableShipModels.length);
expect(screen.queryByText("Company Courier")).not.toBeInTheDocument();
const courier = items[0]!;
expect(courier).toHaveTextContent("Courier");
expect(courier).toHaveTextContent("3.00M km/h");
expect(courier).toHaveTextContent("Capacity20 t");
expect(courier).toHaveTextContent("Range5.00M km");
expect(courier).toHaveTextContent("LandingAtmospheric");
});
it("disables Buy for ships the player cannot afford", async () => {
renderApp(
fakeApi({
getPlayerState: () =>
samplePlayerState({ company: { id: "c", name: "D", credits: courierPrice } }),
}),
"/market",
);
expect(await screen.findByRole("button", { name: "Buy Courier" })).toBeEnabled();
expect(screen.getByRole("button", { name: "Buy Freighter" })).toBeDisabled();
expect(screen.getByRole("button", { name: "Buy Bulk Hauler" })).toBeDisabled();
});
it("buys a ship, which then appears in the Fleet", async () => {
const bought: Ship = {
id: "s-new",
modelId: "freighter",
name: "Lucky Heron",
status: "idle",
locationId: "earth",
dispatchId: null,
pilotId: null,
};
let owned: Ship[] = [];
const api = fakeApi({
getPlayerState: () =>
samplePlayerState({
tutorial: null,
ships: owned,
company: { id: "c", name: "D", credits: owned.length ? 1 : freighterPrice },
}),
buyShip: () => {
owned = [bought];
return { ship: bought };
},
});
renderApp(api, "/market");
await userEvent.click(await screen.findByRole("button", { name: "Buy Freighter" }));
expect(api.call).toHaveBeenCalledWith("buyShip", { modelId: "freighter" });
expect(await screen.findByRole("status")).toHaveTextContent("Lucky Heron is waiting at Earth.");
const nav = screen.getByRole("navigation", { name: "Main" });
await userEvent.click(within(nav).getByRole("link", { name: "Fleet" }));
expect(await screen.findByText("Lucky Heron")).toBeInTheDocument();
});
});