import { UnauthorizedException } from '@nestjs/common';
import type { Request } from 'express';
import type { Principal, Privilege } from 'shared-auth';
import { MeController } from './me.controller';

function makeReq(
  privileges: readonly Privilege[] | null,
  overrides: { displayName?: string } = {},
): Request {
  if (privileges === null) {
    return { session: {} } as unknown as Request;
  }
  const principal: Principal = {
    user: {
      id: 'user-oid',
      personId: 'user-oid',
      entraOid: 'user-oid',
      tenantId: 'tenant-1',
      displayName: overrides.displayName ?? 'Jane',
    },
    privileges,
    roles: [],
    scopes: [{ kind: 'unrestricted' }],
    amr: ['pwd', 'mfa'],
  };
  return { session: { principal } } as unknown as Request;
}

describe('MeController', () => {
  const controller = new MeController();

  it('returns canAccessAdmin: true when the principal carries Portal.Admin', () => {
    const result = controller.capabilities(makeReq(['Portal.Admin', 'Portal.DPO']));
    expect(result).toEqual({ canAccessAdmin: true });
  });

  it('returns canAccessAdmin: false when the principal carries other privileges only', () => {
    const result = controller.capabilities(makeReq(['Portal.Auditor']));
    expect(result).toEqual({ canAccessAdmin: false });
  });

  it('returns canAccessAdmin: false when the principal has no privileges', () => {
    const result = controller.capabilities(makeReq([]));
    expect(result).toEqual({ canAccessAdmin: false });
  });

  it('throws Unauthorized when no session principal is present', () => {
    expect(() => controller.capabilities(makeReq(null))).toThrow(UnauthorizedException);
  });

  it('does NOT echo the raw privileges array in the response (curated view contract)', () => {
    const result = controller.capabilities(makeReq(['Portal.Admin', 'Portal.DPO']));
    expect(Object.keys(result)).toEqual(['canAccessAdmin']);
    expect(JSON.stringify(result)).not.toContain('Portal.DPO');
    expect(JSON.stringify(result)).not.toContain('Portal.Admin');
  });
});
