90 lines
3.2 KiB
TypeScript
90 lines
3.2 KiB
TypeScript
import { content } from "@deadhead/content";
|
|
import {
|
|
createGuestResponseSchema,
|
|
errorResponseSchema,
|
|
playerStateSchema,
|
|
} from "@deadhead/schema";
|
|
import { beforeEach, describe, expect, it } from "vitest";
|
|
import { buildApp } from "../src/app";
|
|
import { createRecordingQueue } from "../src/jobs/queue";
|
|
import { useTestDatabase } from "./db";
|
|
import { testConfig } from "./helpers";
|
|
|
|
const database = useTestDatabase();
|
|
|
|
/** Turns Set-Cookie headers into a Cookie request header. */
|
|
function cookieFrom(setCookie: string | string[] | undefined): string {
|
|
const values = Array.isArray(setCookie) ? setCookie : setCookie ? [setCookie] : [];
|
|
return values.map((c) => c.split(";")[0]).join("; ");
|
|
}
|
|
|
|
describe("guest accounts", () => {
|
|
let app: ReturnType<typeof buildApp>;
|
|
beforeEach(() => {
|
|
app = buildApp(testConfig(), { database: database(), jobs: createRecordingQueue() });
|
|
return () => app.close();
|
|
});
|
|
|
|
it("creates a guest with a session cookie and a new tutorial player", async () => {
|
|
const response = await app.inject({ method: "POST", url: "/api/guest" });
|
|
expect(response.statusCode).toBe(200);
|
|
expect(cookieFrom(response.headers["set-cookie"])).toMatch(/session_token=/);
|
|
|
|
const body = createGuestResponseSchema.parse(response.json());
|
|
expect(body.state.company.credits).toBe(content.config.startingCredits);
|
|
expect(body.state.tutorial).toEqual({ loanerLocationId: "earth", runInFlight: false });
|
|
});
|
|
|
|
it("returns the new player's state for that session", async () => {
|
|
const guest = await app.inject({ method: "POST", url: "/api/guest" });
|
|
const cookie = cookieFrom(guest.headers["set-cookie"]);
|
|
|
|
const response = await app.inject({ method: "GET", url: "/api/state", headers: { cookie } });
|
|
expect(response.statusCode).toBe(200);
|
|
const state = playerStateSchema.parse(response.json());
|
|
|
|
expect(state.company.credits).toBe(content.config.startingCredits);
|
|
expect(
|
|
state.locations
|
|
.filter((l) => l.discovered)
|
|
.map((l) => l.id)
|
|
.sort(),
|
|
).toEqual(["earth", "moon"]);
|
|
expect(state.pilots).toHaveLength(1);
|
|
expect(state.pilots[0]).toMatchObject({
|
|
isAvatar: true,
|
|
level: 0,
|
|
xp: 0,
|
|
locationId: "earth",
|
|
status: "idle",
|
|
});
|
|
expect(state.ships).toHaveLength(0);
|
|
expect(state.tutorial).not.toBeNull();
|
|
});
|
|
|
|
it("gives each guest their own player", async () => {
|
|
const a = createGuestResponseSchema.parse(
|
|
(await app.inject({ method: "POST", url: "/api/guest" })).json(),
|
|
);
|
|
const b = createGuestResponseSchema.parse(
|
|
(await app.inject({ method: "POST", url: "/api/guest" })).json(),
|
|
);
|
|
expect(a.playerId).not.toBe(b.playerId);
|
|
});
|
|
|
|
it("rejects a state request with no session", async () => {
|
|
const response = await app.inject({ method: "GET", url: "/api/state" });
|
|
expect(response.statusCode).toBe(401);
|
|
expect(errorResponseSchema.parse(response.json()).error.code).toBe("unauthorized");
|
|
});
|
|
|
|
it("rejects a state request with a forged session cookie", async () => {
|
|
const response = await app.inject({
|
|
method: "GET",
|
|
url: "/api/state",
|
|
headers: { cookie: "better-auth.session_token=forged.value" },
|
|
});
|
|
expect(response.statusCode).toBe(401);
|
|
});
|
|
});
|