import { describe, it, expect, vi, type Mock } from 'vitest'; import { RecordEngagementUseCase, type RecordEngagementInput } from './RecordEngagementUseCase'; import type { IEngagementRepository } from '../../domain/repositories/IEngagementRepository'; import { EngagementEvent } from '../../domain/entities/EngagementEvent'; import type { Logger } from '@core/shared/application'; import type { EngagementAction, EngagementEntityType } from '../../domain/types/EngagementEvent'; describe('RecordEngagementUseCase', () => { let engagementRepository: { save: Mock; }; let logger: Logger; let useCase: RecordEngagementUseCase; beforeEach(() => { engagementRepository = { save: vi.fn(), } as unknown as IEngagementRepository as any; logger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), } as unknown as Logger; useCase = new RecordEngagementUseCase( engagementRepository as unknown as IEngagementRepository, logger, ); }); it('creates and saves an EngagementEvent and returns its id and weight', async () => { const input: RecordEngagementInput = { action: 'view' as EngagementAction, entityType: 'league' as EngagementEntityType, entityId: 'league-1', actorId: 'driver-1', actorType: 'driver', sessionId: 'session-1', metadata: { foo: 'bar' }, }; engagementRepository.save.mockResolvedValue(undefined); const result = await useCase.execute(input); expect(engagementRepository.save).toHaveBeenCalledTimes(1); const saved = (engagementRepository.save as unknown as Mock).mock.calls[0][0] as EngagementEvent; expect(saved).toBeInstanceOf(EngagementEvent); expect(saved.id).toBeDefined(); expect(saved.entityId).toBe(input.entityId); expect(saved.entityType).toBe(input.entityType); expect(result.eventId).toBe(saved.id); expect(typeof result.engagementWeight).toBe('number'); expect((logger.info as unknown as Mock)).toHaveBeenCalled(); }); it('logs and rethrows when repository save fails', async () => { const input: RecordEngagementInput = { action: 'view' as EngagementAction, entityType: 'league' as EngagementEntityType, entityId: 'league-1', actorType: 'anonymous', sessionId: 'session-1', }; const error = new Error('DB error'); engagementRepository.save.mockRejectedValue(error); await expect(useCase.execute(input)).rejects.toThrow('DB error'); expect((logger.error as unknown as Mock)).toHaveBeenCalled(); }); });