import type { Logger } from '@core/shared/domain/Logger'; import { beforeEach, describe, expect, it, vi, type Mock } from 'vitest'; import { EngagementEvent } from '../../domain/entities/EngagementEvent'; import type { EngagementRepository } from '../../domain/repositories/EngagementRepository'; import type { EngagementAction, EngagementEntityType } from '../../domain/types/EngagementEvent'; import { RecordEngagementUseCase, type RecordEngagementInput } from './RecordEngagementUseCase'; describe('RecordEngagementUseCase', () => { let engagementRepository: { save: Mock; }; let logger: Logger; let useCase: RecordEngagementUseCase; beforeEach(() => { engagementRepository = { save: vi.fn(), }; logger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), } as unknown as Logger; useCase = new RecordEngagementUseCase( engagementRepository as unknown as EngagementRepository, 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(result.isOk()).toBe(true); const data = result.unwrap(); 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(data.eventId).toBe(saved.id); expect(data.engagementWeight).toBe(saved.getEngagementWeight()); expect((logger.info as unknown as Mock)).toHaveBeenCalled(); }); it('logs and returns error 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); const result = await useCase.execute(input); expect(result.isErr()).toBe(true); expect((logger.error as unknown as Mock)).toHaveBeenCalled(); }); });