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

81 lines
2.8 KiB
TypeScript

import { content } from "@deadhead/content";
import { boardPeriodIndex, boardPeriodMs } from "@deadhead/sim";
import { describe, expect, it } from "vitest";
import { acceptedContracts, contractBoards } from "../src/db/schema";
import { BOARD_RETENTION_PERIODS, cleanupExpiredContracts } from "../src/jobs/cleanup";
import { appJobs, CLEANUP_CONTRACTS_JOB } from "../src/jobs/definitions";
import { makeOwner, TEST_NOW, useTestDatabase } from "./db";
import { insertDispatch, putBoard, signUp, testContract, useTestApp } from "./game";
const database = useTestDatabase();
const testApp = useTestApp(database);
describe("expired contract cleanup", () => {
it("deletes old boards and accepted contracts and keeps current ones", async () => {
const { db } = database();
const guest = await signUp(testApp().app);
const { shipId } = await makeOwner(db, guest.playerId, guest.avatarId);
const period = boardPeriodMs(content.config);
const current = boardPeriodIndex(TEST_NOW, content.config);
const old = current - BOARD_RETENTION_PERIODS - 1;
// A board from long ago and one from the current period.
await putBoard(db, guest.playerId, [testContract()], TEST_NOW - (current - old) * period);
await putBoard(db, guest.playerId, [testContract()], TEST_NOW);
// An accepted contract from each period, both pointing at real dispatches.
const record = await insertDispatch(db, {
playerId: guest.playerId,
shipId,
pilotId: guest.avatarId,
departAt: TEST_NOW,
});
await db.insert(acceptedContracts).values([
{
playerId: guest.playerId,
contractId: "old",
periodIndex: old,
dispatchId: record.id,
acceptedAt: TEST_NOW,
},
{
playerId: guest.playerId,
contractId: "new",
periodIndex: current,
dispatchId: record.id,
acceptedAt: TEST_NOW,
},
]);
expect(await cleanupExpiredContracts(db, TEST_NOW)).toEqual({
boards: 1,
acceptedContracts: 1,
});
expect((await db.select().from(contractBoards)).map((b) => b.periodIndex)).toEqual([current]);
expect((await db.select().from(acceptedContracts)).map((a) => a.contractId)).toEqual(["new"]);
});
it("keeps boards inside the retention window", async () => {
const { db } = database();
const guest = await signUp(testApp().app);
const period = boardPeriodMs(content.config);
await putBoard(
db,
guest.playerId,
[testContract()],
TEST_NOW - BOARD_RETENTION_PERIODS * period,
);
expect(await cleanupExpiredContracts(db, TEST_NOW)).toEqual({
boards: 0,
acceptedContracts: 0,
});
});
it("runs as an hourly job", () => {
const job = appJobs({ db: database().db, clock: () => TEST_NOW }).find(
(j) => j.name === CLEANUP_CONTRACTS_JOB,
);
expect(job?.cron).toBe("0 * * * *");
});
});