import { content } from "@deadhead/content"; import { describe, expect, it } from "vitest"; import { encodeSave } from "../src/index"; import { addPilot, addShip, newTestApp, readSave, setCredits, signUp, signUpOwner, TEST_NOW, } from "./support"; const HOUR = 60 * 60_000; describe("fleet sleep in the save (Step 24.1, decisions 0.5.136, 0.5.137)", () => { it("starts a new company with its creation as the last decision and the default threshold", async () => { const { app } = newTestApp(); await signUp(app); const { company } = await readSave(app); expect(company.lastManualDecisionAt).toBe(TEST_NOW); expect(company.sleepAfterHours).toBe(content.config.fleetSleep.defaultHours); }); it("stamps a migrated save's last decision with the time the engine first opens it", async () => { const { app } = newTestApp(); await signUp(app); const current = await readSave(app); // As version 8 wrote it: no sleep fields. const { lastManualDecisionAt: _at, sleepAfterHours: _hours, ...company } = current.company; const v8 = { ...current, saveVersion: 8, company }; const device = newTestApp(); device.clock.now = TEST_NOW + 30 * HOUR; await device.app.call("importSave", { code: await encodeSave(v8 as never) }); const imported = (await readSave(device.app)).company; expect(imported.lastManualDecisionAt).toBe(TEST_NOW + 30 * HOUR); expect(imported.sleepAfterHours).toBe(24); }); }); describe("manual decisions (Step 24.2, decision 0.5.136)", () => { it("stamps the time on a dispatch, not on viewing, dismissing or exporting", async () => { const test = newTestApp(); const owner = await signUpOwner(test.app); const last = async () => (await readSave(test.app)).company.lastManualDecisionAt; const { dispatch } = await test.app.call("createDispatch", { kind: "reposition", shipId: owner.shipId, pilotId: (await readSave(test.app)).pilots.find((p) => p.isAvatar)!.id, destinationId: "moon", }); const dispatchedAt = test.clock.now; expect(await last()).toBe(dispatchedAt); // Later: the trip lands; viewing, dismissing its summary and exporting change nothing. test.clock.now = dispatch.arrivalAt + HOUR; await test.app.call("getPlayerState", {}); await test.app.call("getContractBoard", { locationId: "earth" }); await test.app.call("acknowledgeSummaries", { dispatchIds: [dispatch.id] }); await test.app.call("markWelcomeSeen", {}); await test.app.call("exportSave", {}); expect(await last()).toBe(dispatchedAt); }); it("doesn't count a refused command", async () => { const test = newTestApp(); await signUpOwner(test.app); const start = (await readSave(test.app)).company.lastManualDecisionAt; test.clock.now += HOUR; await expect(test.app.call("buyDispatchOffice", {})).rejects.toThrow(); expect((await readSave(test.app)).company.lastManualDecisionAt).toBe(start); }); it("never counts what Independent pilots do", async () => { const test = newTestApp(); await signUpOwner(test.app); await setCredits(test.app, content.config.independentPilots.dispatchOfficePrice + 50_000); await test.app.call("buyDispatchOffice", {}); await addShip(test.app, { id: "s1", modelId: "courier", name: "Wren" }); await addPilot(test.app, { id: "p1", name: "Ada", assignedShipId: "s1" }); await test.app.call("setPilotMode", { pilotId: "p1", mode: "independent" }); const decided = (await readSave(test.app)).company.lastManualDecisionAt; test.clock.now += 4 * HOUR; await test.app.call("getPlayerState", {}); const save = await readSave(test.app); expect(save.dispatches.some((d) => d.independent)).toBe(true); expect(save.company.lastManualDecisionAt).toBe(decided); }); });