Files
plainpages/src/context.test.ts
T

55 lines
2.3 KiB
TypeScript

import assert from "node:assert/strict";
import { IncomingMessage, ServerResponse } from "node:http";
import { Socket } from "node:net";
import { test } from "node:test";
import { buildContext, type User } from "./context.ts";
import { createLogger } from "./logger.ts";
// A req/res pair without a live server — enough to build and inspect a context.
function reqRes(url?: string): { req: IncomingMessage; res: ServerResponse } {
const req = new IncomingMessage(new Socket());
if (url !== undefined) req.url = url;
req.method = "GET";
return { req, res: new ServerResponse(req) };
}
test("buildContext parses the URL, exposes query, and defaults to an anonymous user", () => {
const { req, res } = reqRes("/users?q=ann&page=2");
const ctx = buildContext(req, res);
assert.equal(ctx.req, req);
assert.equal(ctx.res, res);
assert.equal(ctx.url.pathname, "/users");
assert.equal(ctx.query, ctx.url.searchParams); // same instance, not a copy
assert.equal(ctx.query.get("q"), "ann");
assert.equal(ctx.query.get("page"), "2");
assert.equal(ctx.user, null);
assert.deepEqual(ctx.roles, []);
assert.deepEqual(ctx.params, {});
});
test("buildContext threads path params supplied by the router", () => {
const { req, res } = reqRes("/users/42");
const ctx = buildContext(req, res, { params: { id: "42" } });
assert.equal(ctx.params.id, "42");
});
test("buildContext threads the user and derives roles from it", () => {
const { req, res } = reqRes("/");
const user: User = { email: "a@b.c", id: "u1", roles: ["admin", "editor"] };
const ctx = buildContext(req, res, { user });
assert.equal(ctx.user, user);
assert.equal(ctx.roles, user.roles); // same reference, never a divergent copy — buildContext is the only writer
});
test("buildContext defaults a missing request URL to /", () => {
const { req, res } = reqRes();
assert.equal(buildContext(req, res).url.pathname, "/");
});
test("buildContext provides a logger: a silent default, or the host's request logger", () => {
const { req, res } = reqRes("/");
assert.equal(typeof buildContext(req, res).log.info, "function"); // always present (silent default)
const log = createLogger({ level: "none" });
assert.equal(buildContext(req, res, { log }).log, log); // host's request logger threads through
});