import { SignJWT } from 'jose';
import { describe, expect, it } from 'vitest';
import { ForbiddenError, UnauthorizedError } from '@bytelyst/errors';
import { requireAuth, requireRole, verifyJwtToken } from './auth.js';

describe('mcp auth helpers', () => {
  const secret = new TextEncoder().encode('test-secret');

  it('verifyJwtToken accepts tokens from the bytelyst-platform issuer', async () => {
    const token = await new SignJWT({ sub: 'user_1', role: 'admin' })
      .setProtectedHeader({ alg: 'HS256' })
      .setIssuer('bytelyst-platform')
      .setExpirationTime('1h')
      .sign(secret);

    await expect(verifyJwtToken(token, secret)).resolves.toMatchObject({
      sub: 'user_1',
      role: 'admin',
    });
  });

  it('verifyJwtToken rejects tokens from the wrong issuer', async () => {
    const token = await new SignJWT({ sub: 'user_1' })
      .setProtectedHeader({ alg: 'HS256' })
      .setIssuer('wrong-issuer')
      .setExpirationTime('1h')
      .sign(secret);

    await expect(verifyJwtToken(token, secret)).rejects.toThrow();
  });

  it('requireAuth throws when jwtPayload is missing', () => {
    expect(() => requireAuth({ headers: {} })).toThrow(UnauthorizedError);
  });

  it('requireRole throws when role is below the minimum required level', () => {
    expect(() =>
      requireRole(
        {
          headers: {},
          jwtPayload: { sub: 'user_1', role: 'viewer' },
        },
        'admin'
      )
    ).toThrow(ForbiddenError);
  });
});
