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 }); }); });