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

69 lines
2.6 KiB
TypeScript

// Ported from apps/server/test (CR-014 Step 14.5): now runs on the engine.
import { dispatchResponseSchema, errorResponseSchema } from "@deadhead/schema";
import { describe, expect, it } from "vitest";
import { useTestApp, call, getState, setCredits, signUpOwner } from "../support";
const testApp = useTestApp();
/** An owner with only the Earth bay, a crewed Courier at Earth and 10,000 credits. */
async function owner() {
const guest = await signUpOwner(testApp().app);
await setCredits(testApp().app, 10_000);
return guest;
}
describe("deadhead dispatch", () => {
it("flies the ship empty to a discovered location without a bay, costing only fuel", async () => {
const { app, clock } = testApp();
const guest = await owner();
const response = await call(app, guest, "POST", "/api/dispatches", {
kind: "reposition",
shipId: guest.shipId,
pilotId: guest.avatarId,
destinationId: "moon",
});
expect(response.statusCode).toBe(200);
const { dispatch } = dispatchResponseSchema.parse(response.json());
expect(dispatch).toMatchObject({ contract: null, expectedPayout: 0, destinationId: "moon" });
expect(dispatch.fuelCost).toBeGreaterThan(0);
clock.now = dispatch.arrivalAt;
const state = await getState(app, guest);
expect(state.bays.map((b) => b.locationId)).toEqual(["earth"]);
expect(state.ships[0]).toMatchObject({ status: "idle", locationId: "moon" });
expect(state.pilots[0]).toMatchObject({ status: "idle", locationId: "moon", xp: 0 });
// Fuel came out of the tank (CR-015); on Manual, the default since CR-018,
// nothing is bought on landing.
const [summary] = state.summaries;
expect(state.summaries).toHaveLength(1);
expect(summary).toMatchObject({
deadhead: true,
fuelCost: dispatch.fuelCost,
credits: 0,
pilotXp: 0,
topUp: null,
});
expect(state.company.credits).toBe(10_000);
expect(state.ships[0]!.fuelFu).toBeCloseTo(
state.ships[0]!.stats.tankCapacityFu - dispatch.fuelBurnedFu,
);
});
it("refuses an undiscovered destination and changes nothing", async () => {
const { app } = testApp();
const guest = await owner();
const response = await call(app, guest, "POST", "/api/dispatches", {
kind: "reposition",
shipId: guest.shipId,
pilotId: guest.avatarId,
destinationId: "mars",
});
expect(response.statusCode).toBe(409);
expect(errorResponseSchema.parse(response.json()).error.code).toBe("location-undiscovered");
const state = await getState(app, guest);
expect(state.company.credits).toBe(10_000);
expect(state.ships[0]!.status).toBe("idle");
});
});