/*
 * 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(['*']);
  });
});
