deadhead-space-freight-tycoon/packages/engine/test/ported/new-company.test.ts

74 lines
2.6 KiB
TypeScript

// Ported from apps/server/test (CR-014 Step 14.5): now runs on the engine.
import { content } from "@deadhead/content";
import { playerStateSchema, type PlayerState } from "@deadhead/schema";
import { describe, expect, it } from "vitest";
import {
newTestApp,
useTestApp,
signUp,
call,
getState,
readSave,
setCredits,
testContract,
insertDispatch,
signUpOwner,
} from "../support";
const testApp = useTestApp();
/** The parts of a state that must match a brand-new guest's (ids differ). */
const shape = (s: PlayerState) => ({
credits: s.company.credits,
loanBalance: s.company.loanBalance,
ships: s.ships.length,
bays: s.bays.length,
pilots: s.pilots.map((p) => ({
isAvatar: p.isAvatar,
locationId: p.locationId,
level: p.level,
assignedShipId: p.assignedShipId,
})),
discovered: s.locations.filter((l) => l.discovered).map((l) => l.id),
tutorial: s.tutorial,
activeDispatches: s.activeDispatches.length,
summaries: s.summaries.length,
goals: s.goals,
});
describe("start a new company (Step 10K.6)", () => {
it("turns a mid-game company back into a fresh guest start, with a new world seed", async () => {
const { app, clock } = testApp();
const owner = await signUpOwner(app);
await setCredits(testApp().app, 50_000);
await call(app, owner, "POST", "/api/bays", { locationId: "moon" });
await call(app, owner, "POST", `/api/ships/${owner.shipId}/upgrades`, { upgradeId: "engines" });
const flight = await insertDispatch(testApp().app, {
shipId: owner.shipId,
pilotId: owner.avatarId,
departAt: clock.now,
contract: testContract(),
});
const before = await readSave(app);
const response = await call(app, owner, "POST", "/api/company/new", {});
expect(response.statusCode).toBe(200);
const fresh = playerStateSchema.parse(response.json());
// A brand-new company on another device.
const other = newTestApp();
const guest = await signUp(other.app);
expect(shape(fresh)).toEqual(shape(await getState(other.app, guest)));
expect(fresh.tutorial).toMatchObject({ loanerLocationId: "earth", runsCompleted: 0 });
expect(fresh.company.credits).toBe(content.config.startingCredits);
expect(shape(fresh).discovered.sort()).toEqual(["earth", "moon"]);
const after = await readSave(app);
expect(after.player.worldSeed).not.toBe(before.player.worldSeed);
expect(after.saveId).toBe(before.saveId);
// The old flight is gone: nothing lands when its arrival time passes.
clock.now = flight.arrivalAt + 1000;
expect(shape(await getState(app, owner))).toEqual(shape(fresh));
});
});