69 lines
2.7 KiB
TypeScript
69 lines
2.7 KiB
TypeScript
import { content } from "@deadhead/content";
|
|
import { contractBoardResponseSchema, errorResponseSchema } from "@deadhead/schema";
|
|
import { boardPeriodMs } from "@deadhead/sim";
|
|
import { describe, expect, it } from "vitest";
|
|
import { discoveredLocations } from "../src/db/schema";
|
|
import { makeOwner, TEST_NOW, useTestDatabase } from "./db";
|
|
import { call, signUp, useTestApp, type Guest } from "./game";
|
|
|
|
const database = useTestDatabase();
|
|
const testApp = useTestApp(database);
|
|
|
|
async function owner(): Promise<Guest> {
|
|
const guest = await signUp(testApp().app);
|
|
await makeOwner(database().db, guest.playerId, guest.avatarId);
|
|
return guest;
|
|
}
|
|
|
|
async function earthBoard(guest: Guest) {
|
|
const response = await call(testApp().app, guest, "GET", "/api/bays/earth/board");
|
|
expect(response.statusCode).toBe(200);
|
|
return contractBoardResponseSchema.parse(response.json());
|
|
}
|
|
|
|
describe("bay contract board", () => {
|
|
it("returns a board of the configured size for an owned bay", async () => {
|
|
const guest = await owner();
|
|
const { contracts, periodEndsAt } = await earthBoard(guest);
|
|
expect(contracts).toHaveLength(content.config.contractBoardSize);
|
|
for (const c of contracts) expect(c.originId).toBe("earth");
|
|
expect(periodEndsAt).toBeGreaterThan(testApp().clock.now);
|
|
});
|
|
|
|
it("refuses a location where the player has no bay", async () => {
|
|
const { app } = testApp();
|
|
const guest = await owner();
|
|
const response = await call(app, guest, "GET", "/api/bays/moon/board");
|
|
expect(response.statusCode).toBe(409);
|
|
expect(errorResponseSchema.parse(response.json()).error.code).toBe("no-bay-at-location");
|
|
});
|
|
|
|
it("returns the same stored board within a period, even after a discovery", async () => {
|
|
const { clock } = testApp();
|
|
const guest = await owner();
|
|
const first = await earthBoard(guest);
|
|
await database()
|
|
.db.insert(discoveredLocations)
|
|
.values(
|
|
["mars", "ceres-station", "jupiter-cloud-platform"].map((locationId) => ({
|
|
playerId: guest.playerId,
|
|
locationId,
|
|
discoveredAt: TEST_NOW,
|
|
})),
|
|
);
|
|
clock.advance(boardPeriodMs(content.config) / 2 - 1);
|
|
expect((await earthBoard(guest)).contracts).toEqual(first.contracts);
|
|
});
|
|
|
|
it("returns a new board after the period rolls over", async () => {
|
|
const { clock } = testApp();
|
|
const guest = await owner();
|
|
const first = await earthBoard(guest);
|
|
clock.now = first.periodEndsAt;
|
|
const next = await earthBoard(guest);
|
|
expect(next.periodEndsAt).toBe(first.periodEndsAt + boardPeriodMs(content.config));
|
|
expect(next.contracts.map((c) => c.id)).not.toEqual(first.contracts.map((c) => c.id));
|
|
for (const c of next.contracts) expect(c.expiresAt).toBe(next.periodEndsAt);
|
|
});
|
|
});
|