import { describe, it, expect, vi, type Mock } from 'vitest'; import { HandleAuthCallbackUseCase } from './HandleAuthCallbackUseCase'; import type { IdentityProviderPort } from '../ports/IdentityProviderPort'; import type { IdentitySessionPort } from '../ports/IdentitySessionPort'; import type { AuthCallbackCommandDTO } from '../dto/AuthCallbackCommandDTO'; import type { AuthenticatedUserDTO } from '../dto/AuthenticatedUserDTO'; import type { AuthSessionDTO } from '../dto/AuthSessionDTO'; import type { Logger, UseCaseOutputPort } from '@core/shared/application'; describe('HandleAuthCallbackUseCase', () => { let provider: { completeAuth: Mock; }; let sessionPort: { createSession: Mock; getCurrentSession: Mock; clearSession: Mock; }; let logger: Logger; let output: UseCaseOutputPort & { present: Mock }; let useCase: HandleAuthCallbackUseCase; beforeEach(() => { provider = { completeAuth: vi.fn(), }; sessionPort = { createSession: vi.fn(), getCurrentSession: vi.fn(), clearSession: vi.fn(), }; logger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), } as unknown as Logger; output = { present: vi.fn(), }; useCase = new HandleAuthCallbackUseCase( provider as unknown as IdentityProviderPort, sessionPort as unknown as IdentitySessionPort, logger, output, ); }); it('completes auth and creates a session', async () => { const command: AuthCallbackCommandDTO = { provider: 'IRACING_DEMO', code: 'auth-code', state: 'state-123', returnTo: 'https://app/callback', }; const user: AuthenticatedUserDTO = { id: 'user-1', email: 'test@example.com', displayName: 'Test User', }; const session: AuthSessionDTO = { user, issuedAt: Date.now(), expiresAt: Date.now() + 1000, token: 'session-token', }; provider.completeAuth.mockResolvedValue(user); sessionPort.createSession.mockResolvedValue(session); const result = await useCase.execute(command); expect(provider.completeAuth).toHaveBeenCalledWith(command); expect(sessionPort.createSession).toHaveBeenCalledWith(user); expect(output.present).toHaveBeenCalledWith(session); expect(result.isOk()).toBe(true); }); });