deadhead-space-freight-tycoon/packages/engine/test/deal-five-runs.test.ts

69 lines
3.1 KiB
TypeScript

import { content } from "@deadhead/content";
import { describe, expect, it } from "vitest";
import { encodeSave, GameEngine, MemoryBackend, SaveStorage } from "../src/index";
import { flyTutorialRun, getState, readSave, signUp, TestClock, useTestApp } from "./support";
const testApp = useTestApp();
describe("the deal after five runs (Step 17.4, decisions 0.5.106, 0.5.108)", () => {
it("comes after the fifth run, at the Moon, not after the fourth", async () => {
const { app } = testApp();
await signUp(app);
for (let run = 1; run <= 4; run++) await flyTutorialRun(testApp());
expect((await getState(app)).tutorial).toMatchObject({
runsCompleted: 4,
dealAvailable: false,
});
await expect(app.call("acceptDeal", {})).rejects.toMatchObject({ code: "deal-not-available" });
const afterFive = await flyTutorialRun(testApp());
expect(afterFive.tutorial).toMatchObject({
runsCompleted: 5,
loanerLocationId: "moon",
dealAvailable: true,
});
});
it("puts the avatar on the Courier and Rosa on the Clipper, both at Earth, with no loaner", async () => {
const { app } = testApp();
await signUp(app);
for (let run = 1; run <= 5; run++) await flyTutorialRun(testApp());
const state = await app.call("acceptDeal", {});
const avatar = state.pilots.find((p) => p.isAvatar)!;
const rosa = state.pilots.find((p) => p.isVeteran)!;
expect(rosa.name).toBe(content.veteranPilot.name);
const shipOf = (pilotId: string) => state.ships.find((s) => s.pilotId === pilotId)!;
expect(avatar.locationId).toBe("earth");
expect(shipOf(avatar.id)).toMatchObject({ modelId: "courier", locationId: "earth" });
expect(rosa.locationId).toBe("earth");
expect(shipOf(rosa.id)).toMatchObject({ modelId: "clipper", locationId: "earth" });
// The loaner is gone with the tutorial.
expect(state.tutorial).toBeNull();
expect(state.ships.map((s) => s.modelId).sort()).toEqual(["clipper", "courier"]);
});
it("asks a save from before CR-017, four runs done, for one more run", async () => {
// A tutorial save with four runs done: under the old rule, the deal was on offer.
const { app } = testApp();
await signUp(app);
for (let run = 1; run <= 4; run++) await flyTutorialRun(testApp());
const old = await readSave(app);
expect(old.player).toMatchObject({ tutorialRunsCompleted: 4, loanerLocationId: "earth" });
// Opened on this build (a new device importing it).
const clock = new TestClock();
clock.now = testApp().clock.now;
const device = new GameEngine({
storage: new SaveStorage(new MemoryBackend()),
clock: { now: () => clock.now },
});
const { state } = await device.call("importSave", { code: await encodeSave(old) });
expect(state.tutorial).toMatchObject({ runsCompleted: 4, dealAvailable: false });
expect((await readSave(device)).player.tutorialRunsCompleted).toBe(4);
const afterFive = await flyTutorialRun({ ...testApp(), app: device, clock });
expect(afterFive.tutorial).toMatchObject({ runsCompleted: 5, dealAvailable: true });
});
});