Files
computer-playbook/tests/unit/javascript/roles/web-app-postmarks/files/sso/patch_server.test.js
T
kevinveenbirkenbach d391b4cbb8 test(unit): cover the postmarks, mediawiki and baserow shims
Bookwyrm has tests for the same trusted-header SSO bridge and settings
patcher; postmarks and baserow ship theirs untested, and the composer
require-dev stripper is a pure transformation nobody exercised.

Each test was checked by breaking its source: the admin gate failing
open, the group matcher loosened to a prefix, require-dev left in place
and the SSO gate forced open all turn the new tests red.
2026-08-22 22:31:37 +02:00

99 lines
3.0 KiB
JavaScript

const test = require("node:test");
const assert = require("node:assert/strict");
const fs = require("node:fs");
const os = require("node:os");
const path = require("node:path");
const { spawnSync } = require("node:child_process");
const PROJECT_ROOT = path.resolve(__dirname, "../../../../../../..");
const PATCHER = path.join(
PROJECT_ROOT,
"roles/web-app-postmarks/files/sso/patch_server.js",
);
const IMPORT_ANCHOR = "import routes from './src/routes/index.js';";
const MOUNT_ANCHOR = "app.use(session());";
const IMPORT_LINE = "import proxyHeaderSso from './src/sso-header-auth.js';";
const MOUNT_LINE = "app.use(proxyHeaderSso);";
const ADMIN_GATE = "app.use('/admin', isAuthenticated, routes.admin);";
const UPSTREAM = [
"import express from 'express';",
"import session from 'express-session';",
IMPORT_ANCHOR,
"",
"const app = express();",
"",
MOUNT_ANCHOR,
"",
"app.use((req, res, next) => {",
" res.locals.loggedIn = req.session.loggedIn;",
" next();",
"});",
"",
ADMIN_GATE,
"",
].join("\n");
function patch(source) {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "postmarks-patch-"));
const server = path.join(dir, "server.js");
fs.writeFileSync(server, source);
return () => {
const result = spawnSync(process.execPath, [PATCHER, server], {
encoding: "utf8",
});
const text = fs.readFileSync(server, "utf8");
return { ...result, text, rows: text.split("\n") };
};
}
test("the bridge import lands directly under the upstream import block", () => {
const run = patch(UPSTREAM);
const result = run();
assert.equal(result.status, 0, result.stderr);
assert.match(result.stdout, /patched for trusted-header SSO/);
assert.equal(
result.rows.indexOf(IMPORT_LINE),
result.rows.indexOf(IMPORT_ANCHOR) + 1,
);
});
test("the middleware mounts between the session and the admin gate", () => {
const { rows } = patch(UPSTREAM)();
assert.equal(rows.indexOf(MOUNT_LINE), rows.indexOf(MOUNT_ANCHOR) + 1);
assert.ok(
rows.indexOf(MOUNT_LINE) < rows.indexOf(ADMIN_GATE),
"the gate must see a session the middleware already touched",
);
});
test("a second run changes nothing and says so", () => {
const run = patch(UPSTREAM);
const once = run().text;
const twice = run();
assert.equal(twice.status, 0, twice.stderr);
assert.match(twice.stdout, /already patched, skipping/);
assert.equal(twice.text, once);
});
test("a moved import anchor aborts instead of shipping an un-bridged server", () => {
const source = UPSTREAM.replace(IMPORT_ANCHOR, "import routes from './r.js';");
const result = patch(source)();
assert.equal(result.status, 1);
assert.match(result.stderr, /import anchor not found/);
assert.equal(result.text, source);
});
test("a moved mount anchor aborts instead of shipping an un-bridged server", () => {
const source = UPSTREAM.replace(MOUNT_ANCHOR, "app.use(session(options));");
const result = patch(source)();
assert.equal(result.status, 1);
assert.match(result.stderr, /mount anchor not found/);
assert.equal(result.text, source);
});