94 lines
3.2 KiB
TypeScript
94 lines
3.2 KiB
TypeScript
import type { Ship } from "@deadhead/schema";
|
|
import { screen, waitFor, within } from "@testing-library/react";
|
|
import userEvent from "@testing-library/user-event";
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { useClock } from "../src/clock/clock";
|
|
import { fakeApi, renderApp, samplePlayerState, shipExtras } from "./render";
|
|
|
|
const NOW = Date.parse("2100-01-01T00:00:00Z");
|
|
|
|
const ship = (id: string, name: string, overrides: Partial<Ship>): Ship => ({
|
|
id,
|
|
name,
|
|
modelId: "freighter",
|
|
status: "idle",
|
|
locationId: "earth",
|
|
dispatchId: null,
|
|
pilotId: null,
|
|
lastArrivalAt: 0,
|
|
...shipExtras("freighter"),
|
|
...overrides,
|
|
});
|
|
|
|
describe("the shop in summaries and on HQ (Step 10I.8)", () => {
|
|
beforeEach(() => {
|
|
vi.useFakeTimers({ toFake: ["Date", "setInterval", "clearInterval"] });
|
|
vi.setSystemTime(NOW);
|
|
useClock.setState({ offsetMs: 0, synced: true, now: NOW });
|
|
});
|
|
afterEach(() => vi.useRealTimers());
|
|
|
|
it("says a ship is out of the shop for an upgrade that finished, and acknowledges it", async () => {
|
|
const api = fakeApi({
|
|
getPlayerState: () =>
|
|
samplePlayerState({
|
|
tutorial: null,
|
|
ships: [
|
|
ship("s1", "Slow Ox", {
|
|
upgrades: { engines: 2 },
|
|
shop: { upgradeId: "engines", level: 2, until: NOW - 60_000 },
|
|
}),
|
|
ship("s2", "Busy Ox", {
|
|
upgrades: { "cargo-bay": 1 },
|
|
inShopUntil: NOW + 60_000,
|
|
shop: { upgradeId: "cargo-bay", level: 1, until: NOW + 60_000 },
|
|
}),
|
|
],
|
|
}),
|
|
});
|
|
renderApp(api, "/");
|
|
const dialog = await screen.findByRole("dialog", { name: /While you were away/ });
|
|
await waitFor(() =>
|
|
expect(dialog).toHaveTextContent("Slow Ox is out of the shop: Engine Tuning level 2"),
|
|
);
|
|
expect(dialog).not.toHaveTextContent("Busy Ox");
|
|
|
|
await userEvent.click(within(dialog).getByRole("button", { name: "Done" }));
|
|
await waitFor(() =>
|
|
expect(api.call).toHaveBeenCalledWith("acknowledgeSummaries", {
|
|
dispatchIds: [],
|
|
shipIds: ["s1"],
|
|
}),
|
|
);
|
|
});
|
|
|
|
it("lists ships in the shop on HQ, soonest first, with countdowns", async () => {
|
|
renderApp(
|
|
fakeApi({
|
|
getPlayerState: () =>
|
|
samplePlayerState({
|
|
tutorial: null,
|
|
ships: [
|
|
ship("s1", "Late Ox", {
|
|
inShopUntil: NOW + 25 * 60_000,
|
|
shop: { upgradeId: "engines", level: 2, until: NOW + 25 * 60_000 },
|
|
}),
|
|
ship("s2", "Soon Ox", {
|
|
inShopUntil: NOW + 4 * 60_000,
|
|
shop: { upgradeId: "cargo-bay", level: 1, until: NOW + 4 * 60_000 },
|
|
}),
|
|
ship("s3", "Free Ox", {}),
|
|
],
|
|
}),
|
|
}),
|
|
"/",
|
|
);
|
|
const card = await screen.findByLabelText("In the shop");
|
|
expect(card).toHaveTextContent("In the shop: 2");
|
|
const [first, second] = within(card).getAllByRole("listitem");
|
|
expect(first).toHaveTextContent("Soon Ox · Cargo Bay Expansion 1 · ready in 4m 00s");
|
|
expect(second).toHaveTextContent("Late Ox · Engine Tuning 2 · ready in 25m 00s");
|
|
expect(card).not.toHaveTextContent("Free Ox");
|
|
});
|
|
});
|