40467-vm/backend/test/coachingAuthorization.test.js
2026-07-22 16:45:10 +00:00

99 lines
2.8 KiB
JavaScript

const assert = require("node:assert/strict");
const test = require("node:test");
const {
authorizeCoachingRoute,
clientAccessWhere,
isAdministratorUser,
isClientUser,
isStaffUser,
requireStaff,
} = require("../src/security/coachingAuthorization");
function user(role) {
return { id: `${role}-id`, app_role: { name: role } };
}
function response() {
return {
body: null,
statusCode: null,
status(code) {
this.statusCode = code;
return this;
},
send(body) {
this.body = body;
return this;
},
};
}
test("role helpers classify workspace roles", () => {
assert.equal(isAdministratorUser(user("Administrator")), true);
assert.equal(isAdministratorUser(user("Workspace Owner")), true);
assert.equal(isAdministratorUser(user("Coach")), false);
assert.equal(isStaffUser(user("Coach")), true);
assert.equal(isStaffUser(user("Assistant")), true);
assert.equal(isClientUser(user("Client")), true);
});
test("client scope follows the deployment role policy", () => {
assert.deepEqual(clientAccessWhere(user("Administrator")), {});
assert.deepEqual(clientAccessWhere(user("Workspace Owner")), {});
assert.deepEqual(clientAccessWhere(user("Coach")), { ownerId: "Coach-id" });
assert.deepEqual(clientAccessWhere(user("Assistant")), { ownerId: "Assistant-id" });
assert.deepEqual(clientAccessWhere(user("Client")), { id: null });
});
test("client is rejected from coach-only endpoints", () => {
const res = response();
let nextCalled = false;
requireStaff({ currentUser: user("Client") }, res, () => {
nextCalled = true;
});
assert.equal(nextCalled, false);
assert.equal(res.statusCode, 403);
assert.deepEqual(res.body, { error: "coach_only" });
});
test("staff is allowed through coach-only endpoints", () => {
for (const role of ["Administrator", "Workspace Owner", "Coach", "Assistant"]) {
const res = response();
let nextCalled = false;
requireStaff({ currentUser: user(role) }, res, () => {
nextCalled = true;
});
assert.equal(nextCalled, true, role);
assert.equal(res.statusCode, null, role);
}
});
test("client can use only the client-portal coaching namespace", () => {
for (const path of ["/client-portal/me", "/client-portal/client-id", "/client-portal/action-items/item-id"]) {
const res = response();
let nextCalled = false;
authorizeCoachingRoute({ path, currentUser: user("Client") }, res, () => {
nextCalled = true;
});
assert.equal(nextCalled, true, path);
}
for (const path of ["/clients", "/intake-leads", "/session-memory", "/sessions/session-id/audio"]) {
const res = response();
let nextCalled = false;
authorizeCoachingRoute({ path, currentUser: user("Client") }, res, () => {
nextCalled = true;
});
assert.equal(nextCalled, false, path);
assert.equal(res.statusCode, 403, path);
}
});