Files
MixedAssets/server/services/accessControl.test.js
2026-06-05 04:15:24 -05:00

46 lines
1.9 KiB
JavaScript

/*
* Tests for the capability catalog and default roles used by the RBAC system.
* Roles are stored in the database and editable at runtime; this validates the
* static catalog/defaults and the pure capability-matching helpers.
*/
const accessControl = require('./accessControl');
describe('access control', () => {
test('capability catalog is well-formed', () => {
const { CAPABILITIES, CAPABILITY_KEYS } = accessControl;
expect(CAPABILITIES.length).toBeGreaterThan(0);
for (const cap of CAPABILITIES) {
expect(typeof cap.key).toBe('string');
expect(typeof cap.label).toBe('string');
expect(typeof cap.group).toBe('string');
}
// Keys are unique.
expect(new Set(CAPABILITY_KEYS).size).toBe(CAPABILITY_KEYS.length);
});
test('default roles include the built-ins and PM roles', () => {
const keys = accessControl.DEFAULT_ROLES.map((r) => r.key);
for (const key of ['admin', 'finance', 'operations', 'pm_admin', 'pm_user', 'viewer']) {
expect(keys).toContain(key);
}
const admin = accessControl.DEFAULT_ROLES.find((r) => r.key === 'admin');
expect(admin.capabilities).toEqual(['*']);
const pmUser = accessControl.DEFAULT_ROLES.find((r) => r.key === 'pm_user');
expect(pmUser.capabilities).toContain('pm.complete');
expect(pmUser.capabilities).not.toContain('pm.manage');
});
test('capabilitySetIncludes honors the wildcard', () => {
expect(accessControl.capabilitySetIncludes(['*'], 'anything')).toBe(true);
expect(accessControl.capabilitySetIncludes(['assets.view'], 'assets.view')).toBe(true);
expect(accessControl.capabilitySetIncludes(['assets.view'], 'assets.delete')).toBe(false);
});
test('sanitizeCapabilities drops unknown keys and collapses wildcard', () => {
expect(accessControl.sanitizeCapabilities(['assets.view', 'made.up'])).toEqual(['assets.view']);
expect(accessControl.sanitizeCapabilities(['assets.view', '*'])).toEqual(['*']);
});
});