import { content } from "@deadhead/content"; import { errorResponseSchema, shipResponseSchema } from "@deadhead/schema"; import { describe, expect, it } from "vitest"; import { shipName } from "../src/game/names"; import { setCredits, useTestDatabase } from "./db"; import { call, getState, signUp, useTestApp } from "./game"; const database = useTestDatabase(); const testApp = useTestApp(database); describe("buy a ship", () => { it("deducts the price and adds an idle, uncrewed ship at Earth", async () => { const { app } = testApp(); const guest = await signUp(app); const price = content.shipModel("courier")!.price; await setCredits(database().db, guest.playerId, price + 500); const response = await call(app, guest, "POST", "/api/ships", { modelId: "courier" }); expect(response.statusCode).toBe(200); const { ship } = shipResponseSchema.parse(response.json()); expect(ship).toMatchObject({ modelId: "courier", status: "idle", locationId: "earth", pilotId: null, dispatchId: null, }); expect(ship.name.length).toBeGreaterThan(0); const state = await getState(app, guest); expect(state.company.credits).toBe(500); expect(state.ships.map((s) => s.id)).toEqual([ship.id]); }); it("returns insufficient-funds and changes nothing without enough credits", async () => { const { app } = testApp(); const guest = await signUp(app); const price = content.shipModel("freighter")!.price; await setCredits(database().db, guest.playerId, price - 1); const response = await call(app, guest, "POST", "/api/ships", { modelId: "freighter" }); expect(response.statusCode).toBe(409); expect(errorResponseSchema.parse(response.json()).error.code).toBe("insufficient-funds"); const state = await getState(app, guest); expect(state.company.credits).toBe(price - 1); expect(state.ships).toHaveLength(0); }); it("rejects an unknown model", async () => { const { app } = testApp(); const guest = await signUp(app); const response = await call(app, guest, "POST", "/api/ships", { modelId: "x-wing" }); expect(response.statusCode).toBe(404); expect(errorResponseSchema.parse(response.json()).error.code).toBe("not-found"); }); }); describe("ship names", () => { it("are stable for a world seed and differ between ships", () => { expect(shipName(42, 0)).toBe(shipName(42, 0)); const names = new Set(Array.from({ length: 10 }, (_, i) => shipName(42, i))); expect(names.size).toBeGreaterThan(1); }); });