65 lines
2.3 KiB
TypeScript
65 lines
2.3 KiB
TypeScript
// Ported from apps/server/test (CR-014 Step 14.5): now runs on the engine.
|
|
import { content } from "@deadhead/content";
|
|
import { errorResponseSchema, pilotResponseSchema } from "@deadhead/schema";
|
|
import { describe, expect, it } from "vitest";
|
|
import { useTestApp, signUp, call, edit, makeOwner, type Guest } from "../support";
|
|
|
|
const testApp = useTestApp();
|
|
|
|
/** An owner whose avatar has `xp` XP and the given skills and points spent. */
|
|
async function pilotWith(xp: number, skills: Record<string, number> = {}, spent = 0) {
|
|
const guest = await signUp(testApp().app);
|
|
await makeOwner(testApp().app, guest.avatarId);
|
|
await edit(testApp().app, (save) => {
|
|
Object.assign(
|
|
save.pilots.find((p) => p.id === guest.avatarId)!,
|
|
{
|
|
xp,
|
|
skills,
|
|
skillPointsSpent: spent,
|
|
},
|
|
);
|
|
});
|
|
return guest;
|
|
}
|
|
|
|
function spend(guest: Guest, skillId: string) {
|
|
return call(testApp().app, guest, "POST", `/api/pilots/${guest.avatarId}/skills`, { skillId });
|
|
}
|
|
|
|
const errorCode = (response: { json(): unknown }) =>
|
|
errorResponseSchema.parse(response.json()).error.code;
|
|
|
|
// Level 1 gives `skillPointsPerLevel` points.
|
|
const level1Xp = content.config.pilotLevelXpThresholds[0]!;
|
|
|
|
describe("spending skill points", () => {
|
|
it("raises the skill by one and uses one point", async () => {
|
|
const guest = await pilotWith(level1Xp);
|
|
const response = await spend(guest, "heavy-cargo");
|
|
expect(response.statusCode).toBe(200);
|
|
const { pilot } = pilotResponseSchema.parse(response.json());
|
|
expect(pilot.skills).toEqual({ "heavy-cargo": 1 });
|
|
expect(pilot.skillPointsAvailable).toBe(content.config.skillPointsPerLevel - 1);
|
|
});
|
|
|
|
it("refuses with no points available", async () => {
|
|
const guest = await pilotWith(0);
|
|
const response = await spend(guest, "heavy-cargo");
|
|
expect(response.statusCode).toBe(409);
|
|
expect(errorCode(response)).toBe("no-skill-points");
|
|
});
|
|
|
|
it("refuses a skill already at max level", async () => {
|
|
const guest = await pilotWith(level1Xp, { "long-haul": 5 });
|
|
expect(errorCode(await spend(guest, "long-haul"))).toBe("skill-maxed");
|
|
});
|
|
|
|
it("refuses an unknown skill", async () => {
|
|
const guest = await pilotWith(level1Xp);
|
|
const response = await spend(guest, "juggling");
|
|
expect(response.statusCode).toBe(404);
|
|
expect(errorCode(response)).toBe("unknown-skill");
|
|
});
|
|
});
|