deadhead-space-freight-tycoon/apps/server/test/reposition.test.ts

67 lines
2.5 KiB
TypeScript

import { randomUUID } from "node:crypto";
import { dispatchResponseSchema, errorResponseSchema } from "@deadhead/schema";
import { describe, expect, it } from "vitest";
import { bays } from "../src/db/schema";
import { makeOwner, setCredits, TEST_NOW, useTestDatabase } from "./db";
import { call, getState, signUp, useTestApp } from "./game";
const database = useTestDatabase();
const testApp = useTestApp(database);
async function ownerWithMoonBay(withMoonBay = true) {
const { app } = testApp();
const { db } = database();
const guest = await signUp(app);
const shipId = await makeOwner(db, guest.playerId, guest.avatarId);
await setCredits(db, guest.playerId, 10_000);
if (withMoonBay) {
await db.insert(bays).values({
id: randomUUID(),
playerId: guest.playerId,
locationId: "moon",
createdAt: TEST_NOW,
});
}
return { guest, shipId };
}
describe("reposition dispatch", () => {
it("flies the ship empty to another bay, costing only fuel", async () => {
const { app, clock } = testApp();
const { guest, shipId } = await ownerWithMoonBay();
const response = await call(app, guest, "POST", "/api/dispatches", {
kind: "reposition",
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.ships[0]).toMatchObject({ status: "idle", locationId: "moon" });
expect(state.pilots[0]).toMatchObject({ status: "idle", locationId: "moon", xp: 0 });
expect(state.company.credits).toBe(10_000 - dispatch.fuelCost);
});
it("refuses an undiscovered destination and changes nothing", async () => {
const { app } = testApp();
const { guest, shipId } = await ownerWithMoonBay(false);
const response = await call(app, guest, "POST", "/api/dispatches", {
kind: "reposition",
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");
});
});