import { test, beforeEach } from 'node:test'; import assert from 'node:assert/strict'; import { addPermissionHook, listScope } from '../dist/index.js'; const ROOT = '00000000-0000-0000-0000-000000000000'; const A = '00000000-0000-4000-8000-00000000000a'; const B = '00000000-0000-4000-8000-00000000000b'; const TREE = { [ROOT]: [ROOT, A, B], [A]: [A], [B]: [B] }; function fakeDb(allowed) { return { async query(sql, params) { if (sql.includes('get_org_scope')) return { rows: [...new Set(params[0].flatMap((o) => TREE[o]))].map((id) => ({ id })) }; if (sql.includes('FROM morbac.orgs')) return { rows: Object.keys(TREE).map((id) => ({ id })) }; if (sql.includes('morbac.is_allowed')) return { rows: params[1].filter((o) => allowed.has(o)).map((o) => ({ o })) }; throw new Error(`unexpected query ${sql}`); }, }; } const req = { user: { id: 'u' } }; let removers = []; beforeEach(() => { removers.forEach((r) => r()); removers = []; }); test('the root org stands for its subtree, decided org by org', async () => { const { expr, params } = await listScope(fakeDb(new Set([ROOT, A])), req, [ROOT], 'read', 'users', 'x.org_id'); assert.equal(expr, 'x.org_id = ANY($1::UUID[])'); assert.deepEqual(params[0].sort(), [ROOT, A].sort()); }); test('an org the hooks refuse is left out of every list', async () => { removers.push(addPermissionHook('pre', (c) => c.orgId !== B)); const { params } = await listScope(fakeDb(new Set([ROOT, A, B])), req, [], 'read', 'users', 'x.org_id'); assert.deepEqual(params[0].sort(), [ROOT, A].sort()); }); test('an unpinned list also shows rows with no org', async () => { const { expr } = await listScope(fakeDb(new Set([A])), req, [], 'read', 'roles', 'r.org_id', 2); assert.equal(expr, '(r.org_id = ANY($3::UUID[]) OR r.org_id IS NULL)'); });