import { describe, expect, it } from 'vitest';
import { AppError } from '../errors.js';
import { requireOwnerOrAdmin, requireRole, type CurrentUser } from '../auth.js';

const customer: CurrentUser = { id: 'user-a', email: 'a@example.com', role: 'customer' };
const admin: CurrentUser = { id: 'user-admin', email: 'admin@example.com', role: 'admin' };

function codeOf(fn: () => void): string | undefined {
  try {
    fn();
  } catch (error) {
    return error instanceof AppError ? error.code : undefined;
  }
  return undefined;
}

describe('requireRole', () => {
  it('allows a matching role', () => {
    expect(() => requireRole(admin, 'admin')).not.toThrow();
    expect(() => requireRole(customer, 'customer')).not.toThrow();
  });

  it('throws 403 FORBIDDEN for a missing role', () => {
    expect(codeOf(() => requireRole(customer, 'admin'))).toBe('FORBIDDEN');
  });
});

describe('requireOwnerOrAdmin', () => {
  it('allows the owner regardless of role', () => {
    expect(() => requireOwnerOrAdmin(customer, 'user-a')).not.toThrow();
  });

  it('allows an admin on any user', () => {
    expect(() => requireOwnerOrAdmin(admin, 'user-b')).not.toThrow();
  });

  it('throws 403 FORBIDDEN for a non-owner customer', () => {
    expect(codeOf(() => requireOwnerOrAdmin(customer, 'user-b'))).toBe('FORBIDDEN');
  });
});
