69 lines
3.1 KiB
TypeScript
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 });
|
|
});
|
|
});
|