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

76 lines
3.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Ported from apps/server/test (CR-014 Step 14.5): now runs on the engine.
import { content } from "@deadhead/content";
import { errorResponseSchema, shipResponseSchema } from "@deadhead/schema";
import { checkRoute, effectiveStats, wouldStrand } from "@deadhead/sim";
import { describe, expect, it } from "vitest";
import { TEST_NOW, useTestApp, call, getState, edit, setCredits, signUpOwner } from "../support";
const testApp = useTestApp();
describe("Lighter and Clipper (Step 10L.6)", () => {
for (const modelId of ["lighter", "clipper"]) {
it(`buys a ${modelId} at the chosen HQ`, async () => {
const { app } = testApp();
const owner = await signUpOwner(app);
const price = content.shipModel(modelId)!.price;
await setCredits(testApp().app, price);
const response = await call(app, owner, "POST", "/api/ships", {
modelId,
bayId: owner.earthBayId,
});
expect(response.statusCode).toBe(200);
const { ship } = shipResponseSchema.parse(response.json());
expect(ship).toMatchObject({ modelId, status: "idle", locationId: "earth" });
expect((await getState(app, owner)).company.credits).toBe(0);
});
}
it("refuses a deadhead that would strand the ship, changing nothing", async () => {
const { app } = testApp();
const owner = await signUpOwner(app);
await setCredits(app, 100_000);
// A Freighter with maxed tanks at the Moon, with Jupiter discovered but not
// Mars or Ceres (CR-015 fixed map): Jupiter is in range from the Moon
// (667 × 1.3 ≥ 792), but from Jupiter (667 × 1.0) neither Earth nor the Moon is.
await edit(app, (save) => {
Object.assign(
save.ships.find((s) => s.id === owner.shipId)!,
{
modelId: "freighter",
locationId: "moon",
upgrades: { "fuel-tanks": 3 },
},
);
save.discoveredLocations.push({
locationId: "jupiter-cloud-platform",
discoveredAt: TEST_NOW,
});
});
// The scenario as the sim sees it.
const freighter = effectiveStats(content.shipModel("freighter")!, { "fuel-tanks": 3 }, content);
const [moon, jupiter] = [
content.location("moon")!,
content.location("jupiter-cloud-platform")!,
];
expect(checkRoute(freighter, moon, jupiter, content.config).ok).toBe(true);
const discovered = new Set(["earth", "moon", "jupiter-cloud-platform"]);
expect(wouldStrand(freighter, jupiter, discovered, content)).toBe(true);
const before = await getState(app, owner);
const response = await call(app, owner, "POST", "/api/dispatches", {
kind: "reposition",
shipId: owner.shipId,
pilotId: owner.avatarId,
destinationId: "jupiter-cloud-platform",
});
expect(response.statusCode).toBe(409);
expect(errorResponseSchema.parse(response.json()).error.code).toBe("would-strand");
const after = await getState(app, owner);
expect(after.company.credits).toBe(before.company.credits);
expect(after.ships).toEqual(before.ships);
expect(after.activeDispatches).toEqual([]);
});
});