import { describe, expect, it } from 'vitest';
import type { Role } from '../../../shared/auth.js';
import { REPORTING_ROLE_PERMISSIONS, requireReportingPermission, userReportingPermissions } from '../domain/permissions.js';

function user(role: Role) {
  return { id: 'u1', email: 'u@example.com', role } as const;
}

describe('reporting RBAC matrix (F-142 §9)', () => {
  it('admin holds every reporting permission', () => {
    const grants = userReportingPermissions(user('admin'));
    expect(grants).toContain('REPORTING_VIEW');
    expect(grants).toContain('REPORTING_SALES');
    expect(grants).toContain('REPORTING_EXPORT');
    expect(grants).toContain('REPORTING_ADMIN');
  });

  it('pos_cashier only sees VIEW + SALES (least privilege)', () => {
    expect(userReportingPermissions(user('pos_cashier'))).toEqual([
      'REPORTING_VIEW',
      'REPORTING_SALES',
    ]);
  });

  it('customers never get reporting permissions', () => {
    expect(userReportingPermissions(user('customer'))).toEqual([]);
  });

  it('requireReportingPermission throws AppError(403) for denied perms', () => {
    // customer has no grants -> SALES denied
    expect(() => requireReportingPermission(user('customer'), 'REPORTING_SALES')).toThrow();
    // editor lacks EXPORT
    expect(() => requireReportingPermission(user('editor'), 'REPORTING_EXPORT')).toThrow();
    // admin has everything -> no throw
    expect(() => requireReportingPermission(user('admin'), 'REPORTING_VIEW')).not.toThrow();
  });

  it('REPORTING_FINANCIAL is admin-only (AC6)', () => {
    expect(() => requireReportingPermission(user('editor'), 'REPORTING_FINANCIAL')).toThrow();
    expect(() => requireReportingPermission(user('pos_manager'), 'REPORTING_FINANCIAL')).toThrow();
    expect(() => requireReportingPermission(user('pos_cashier'), 'REPORTING_FINANCIAL')).toThrow();
    expect(() => requireReportingPermission(user('admin'), 'REPORTING_FINANCIAL')).not.toThrow();
  });

  it('the matrix covers every role (no missing keys)', () => {
    for (const role of ['admin', 'editor', 'pos_manager', 'pos_cashier', 'customer'] as const) {
      expect(REPORTING_ROLE_PERMISSIONS[role]).toBeTypeOf('object');
    }
  });
});
