import { Test, TestingModule } from '@nestjs/testing'; import { AuthController } from './auth.controller'; import { UsersService } from 'src/users/user.service'; import { WebauthnService } from 'src/auth/webauthn.service'; import { JwtService } from '@nestjs/jwt'; import type { PublicKeyCredentialCreationOptionsJSON } from '@simplewebauthn/server'; describe('AuthController', () => { let controller: AuthController; let usersService: jest.Mocked; let webauthnService: jest.Mocked; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [AuthController], providers: [ { provide: UsersService, useValue: { findByEmail: jest.fn(), createUser: jest.fn() } }, { provide: WebauthnService, useValue: { generateRegistrationOptions: jest.fn() } }, { provide: JwtService, useValue: { sign: jest.fn().mockReturnValue('mock-jwt') } }, ], }).compile(); controller = module.get(AuthController); usersService = module.get(UsersService); webauthnService = module.get(WebauthnService); }); describe('webauthn-register-options', () => { it('should return registration options for a valid user', async () => { const session: Record = {}; const mockUser = { id: 'u123', username: 'u123@user.com', devices: [] }; // Mock DB + WebAuthn jest.spyOn(controller, 'getUserFromDb').mockResolvedValue(mockUser); webauthnService.generateRegistrationOptions.mockResolvedValueOnce( createMockRegistrationOptions({ challenge: 'abc123' }), ); const result = await controller.getRegistrationOptions({ username: 'u123' }, session); expect(result.challenge).toBe('abc123'); expect(session.challenge).toBe('abc123'); expect(webauthnService.generateRegistrationOptions).toHaveBeenCalledWith(mockUser); }); }); }); /** * Factory for mock registration options */ export function createMockRegistrationOptions( overrides: Partial = {}, ): PublicKeyCredentialCreationOptionsJSON { return { challenge: 'mock-challenge', rp: { name: 'Mock RP' }, user: { id: 'user-id', name: 'test@example.com', displayName: 'Test User', }, pubKeyCredParams: [{ type: 'public-key', alg: -7 }], ...overrides, }; } /** * Factory for mock authentication (login) options */ export function createMockAuthenticationOptions( overrides: Partial = {}, ): PublicKeyCredentialRequestOptionsJSON { return { challenge: 'mock-challenge', timeout: 60000, rpId: 'localhost', allowCredentials: [], userVerification: 'preferred', ...overrides, }; }