67 lines
2.4 KiB
TypeScript
67 lines
2.4 KiB
TypeScript
import { content } from "@deadhead/content";
|
|
import type { Ship } from "@deadhead/schema";
|
|
import { checkRoute, gameToReal, realToGame } from "@deadhead/sim";
|
|
import { screen, within } from "@testing-library/react";
|
|
import userEvent from "@testing-library/user-event";
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
import { useClock } from "../src/clock/clock";
|
|
import { fakeApi, renderApp, samplePlayerState, shipExtras } from "./render";
|
|
|
|
const MONTH = 30.44 * 24 * 3_600_000;
|
|
const gameStart = realToGame(Date.parse(content.config.epoch.realStart), content.config);
|
|
const clipper = content.shipModel("clipper")!;
|
|
const [mars, ceres] = [content.location("mars")!, content.location("ceres-station")!];
|
|
|
|
/** The first monthly date on which a Clipper at Mars can reach Ceres. */
|
|
const NOW = (() => {
|
|
for (let i = 0; i <= 16 * 12; i++) {
|
|
const t = gameStart + i * MONTH;
|
|
if (checkRoute(clipper, mars, ceres, t).ok) return gameToReal(t, content.config);
|
|
}
|
|
throw new Error("no such date");
|
|
})();
|
|
|
|
const atMars: Ship = {
|
|
id: "s1",
|
|
modelId: "clipper",
|
|
name: "Swift Heron",
|
|
status: "idle",
|
|
locationId: "mars",
|
|
dispatchId: null,
|
|
pilotId: null,
|
|
lastArrivalAt: 0,
|
|
...shipExtras("clipper"),
|
|
};
|
|
|
|
describe("map reachability per origin (Step 10L.8)", () => {
|
|
afterEach(() => vi.useRealTimers());
|
|
|
|
it("lists the Clipper from Mars, where it is, and not from Earth", async () => {
|
|
vi.useFakeTimers({ toFake: ["Date", "setInterval", "clearInterval"] });
|
|
vi.setSystemTime(NOW);
|
|
useClock.setState({ offsetMs: 0, synced: true, now: NOW });
|
|
const state = samplePlayerState({
|
|
bays: [{ id: "b-earth", locationId: "earth" }],
|
|
ships: [atMars],
|
|
});
|
|
state.locations = state.locations.map((l) =>
|
|
l.id === "mars" ? { ...l, discovered: true } : l,
|
|
);
|
|
renderApp(fakeApi({ getPlayerState: () => state }), "/map");
|
|
|
|
const canvas = await screen.findByTestId("map-canvas");
|
|
await userEvent.click(
|
|
within(canvas).getByRole("button", { name: "Tap Ceres Station (locked)" }),
|
|
);
|
|
const text = screen.getByLabelText("Reachable with").textContent ?? "";
|
|
const parts = Object.fromEntries(
|
|
text.split(" · ").map((part) => {
|
|
const [origin, list] = part.split(": ");
|
|
return [origin!, list!.split(", ")];
|
|
}),
|
|
);
|
|
expect(parts["From Mars"]).toContain("Clipper");
|
|
expect(parts["From Earth"] ?? []).not.toContain("Clipper");
|
|
});
|
|
});
|