import { randomUUID } from "node:crypto"; import { errorResponseSchema } from "@deadhead/schema"; import { describe, expect, it, vi } from "vitest"; import { dispatches, pilots, ships } from "../src/db/schema"; import { makeOwner, setCredits, TEST_NOW, useTestDatabase } from "./db"; import { call, putBoard, signUp, testContract, useTestApp } from "./game"; // Every base-game ship is atmospheric (decision 0.5.1), so `cannot-land` needs // a test-only vacuum ship in the content the server sees. vi.mock("@deadhead/content", async (importOriginal) => { const original = await importOriginal(); const courier = original.content.shipModel("courier")!; const shipModels = [ ...original.content.shipModels, { ...courier, id: "test-vacuum", landingClass: "vacuum" as const }, ]; return { ...original, content: { ...original.content, shipModels, shipModel: (id: string) => shipModels.find((s) => s.id === id), }, }; }); const database = useTestDatabase(); const testApp = useTestApp(database); describe("contract dispatch landing check", () => { it("rejects cannot-land and changes nothing", async () => { const { app } = testApp(); const { db } = database(); const guest = await signUp(app); await makeOwner(db, guest.playerId, guest.avatarId); await setCredits(db, guest.playerId, 10_000); // A vacuum-only ship at the Moon, crewed by a pilot, offered a Moon→Earth job. const shipId = randomUUID(); await db.insert(ships).values({ id: shipId, playerId: guest.playerId, modelId: "test-vacuum", name: "Moon Crawler", locationId: "moon", createdAt: TEST_NOW, }); const pilotId = randomUUID(); await db.insert(pilots).values({ id: pilotId, playerId: guest.playerId, name: "Vac Pilot", assignedShipId: shipId, createdAt: TEST_NOW, }); const contract = testContract({ originId: "moon", destinationId: "earth" }); await putBoard(db, guest.playerId, [contract]); const response = await call(app, guest, "POST", "/api/dispatches", { kind: "contract", contractId: contract.id, shipId, pilotId, }); expect(response.statusCode).toBe(409); expect(errorResponseSchema.parse(response.json()).error.code).toBe("cannot-land"); expect(await db.select().from(dispatches)).toEqual([]); }); });