← back to Butlr

test/admin-gate.test.js

83 lines

#!/usr/bin/env node
// Unit test for lib/admin-gate.requireAdmin.
//
// Tests the role-gate without spinning up Express. Mocks req/res/next
// and asserts the middleware short-circuits with 403+render for
// no-user / wrong-role, and calls next() for role === 'admin'.

const assert = require('assert');
const { requireAdmin } = require('../lib/admin-gate');

function ok(name, fn) {
  try { fn(); console.log(`  ✓ ${name}`); return 1; }
  catch (e) { console.error(`  ✗ ${name}`); console.error('     ', e.message); return 0; }
}

function fakeRes() {
  return {
    _status: 200,
    _rendered: null,
    status(c) { this._status = c; return this; },
    render(tpl, locals) { this._rendered = { tpl, locals }; return this; },
  };
}

let pass = 0, total = 0;

total++; pass += ok('no req.user → 403 + 404 template', () => {
  const req = {};
  const res = fakeRes();
  let nextCalled = false;
  requireAdmin(req, res, () => { nextCalled = true; });
  assert.strictEqual(nextCalled, false, 'next should NOT be called');
  assert.strictEqual(res._status, 403);
  assert.strictEqual(res._rendered.tpl, 'public/404');
});

total++; pass += ok("req.user.role==='user' → 403", () => {
  const req = { user: { id: 'u1', email: 'a@b.co', role: 'user' } };
  const res = fakeRes();
  let nextCalled = false;
  requireAdmin(req, res, () => { nextCalled = true; });
  assert.strictEqual(nextCalled, false);
  assert.strictEqual(res._status, 403);
});

total++; pass += ok("req.user.role==='admin' → next()", () => {
  const req = { user: { id: 'u1', email: 'admin@x.co', role: 'admin' } };
  const res = fakeRes();
  let nextCalled = false;
  requireAdmin(req, res, () => { nextCalled = true; });
  assert.strictEqual(nextCalled, true, 'next() must be called for admin');
  assert.strictEqual(res._status, 200, 'status untouched');
  assert.strictEqual(res._rendered, null, 'render NOT called');
});

total++; pass += ok('req.user with no role field → 403', () => {
  const req = { user: { id: 'u1', email: 'a@b.co' } };
  const res = fakeRes();
  let nextCalled = false;
  requireAdmin(req, res, () => { nextCalled = true; });
  assert.strictEqual(nextCalled, false);
  assert.strictEqual(res._status, 403);
});

total++; pass += ok("'ADMIN' (uppercase) is NOT 'admin' (case-sensitive)", () => {
  const req = { user: { role: 'ADMIN' } };
  const res = fakeRes();
  let nextCalled = false;
  requireAdmin(req, res, () => { nextCalled = true; });
  assert.strictEqual(nextCalled, false);
  assert.strictEqual(res._status, 403);
});

total++; pass += ok('rendered 404 has Butlr title', () => {
  const req = {};
  const res = fakeRes();
  requireAdmin(req, res, () => {});
  assert.ok(res._rendered.locals && /Butlr/.test(res._rendered.locals.title));
});

console.log(`\n${pass}/${total} passed`);
process.exit(pass === total ? 0 : 1);