import { beforeEach, describe, expect, it, vi, type Mock } from 'vitest'; import { GetCurrentUserSocialUseCase, type GetCurrentUserSocialApplicationError, type GetCurrentUserSocialInput, type GetCurrentUserSocialResult, } from './GetCurrentUserSocialUseCase'; import type { ISocialGraphRepository } from '../../domain/repositories/ISocialGraphRepository'; import type { Logger, UseCaseOutputPort } from '@core/shared/application'; import { Driver } from '@core/racing/domain/entities/Driver'; describe('GetCurrentUserSocialUseCase', () => { let socialGraphRepository: ISocialGraphRepository & { getFriends: Mock }; let logger: Logger & { debug: Mock; info: Mock; warn: Mock; error: Mock }; let output: UseCaseOutputPort & { present: Mock }; let useCase: GetCurrentUserSocialUseCase; beforeEach(() => { socialGraphRepository = { getFriends: vi.fn(), getFriendIds: vi.fn(), getSuggestedFriends: vi.fn(), } as unknown as ISocialGraphRepository & { getFriends: Mock }; logger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), } as unknown as Logger & { debug: Mock; info: Mock; warn: Mock; error: Mock }; output = { present: vi.fn(), } as unknown as UseCaseOutputPort & { present: Mock }; useCase = new GetCurrentUserSocialUseCase(socialGraphRepository, logger, output); }); it('presents current user social with mapped friends', async () => { vi.useFakeTimers(); vi.setSystemTime(new Date('2025-01-01T00:00:00.000Z')); const friends = [ Driver.create({ id: 'friend-1', iracingId: '123', name: 'Friend One', country: 'US', }), ]; socialGraphRepository.getFriends.mockResolvedValue(friends); const input: GetCurrentUserSocialInput = { driverId: 'driver-1' }; const result = await useCase.execute(input); expect(result.isOk()).toBe(true); expect(result.unwrap()).toBeUndefined(); expect(output.present).toHaveBeenCalledTimes(1); const presented = (output.present as Mock).mock.calls[0]![0] as GetCurrentUserSocialResult; expect(presented.currentUser).toEqual({ driverId: 'driver-1', displayName: '', avatarUrl: '', countryCode: '', }); expect(presented.friends).toHaveLength(1); expect(presented.friends[0]).toEqual({ driverId: 'friend-1', displayName: 'Friend One', avatarUrl: '', countryCode: '', isOnline: false, lastSeen: new Date('2025-01-01T00:00:00.000Z'), }); expect(logger.warn).not.toHaveBeenCalled(); vi.useRealTimers(); }); it('warns and presents empty friends list when no friends exist', async () => { socialGraphRepository.getFriends.mockResolvedValue([]); const input: GetCurrentUserSocialInput = { driverId: 'driver-1' }; const result = await useCase.execute(input); expect(result.isOk()).toBe(true); expect(output.present).toHaveBeenCalledTimes(1); const presented = (output.present as Mock).mock.calls[0]![0] as GetCurrentUserSocialResult; expect(presented.friends).toEqual([]); expect(logger.warn).toHaveBeenCalledTimes(1); expect((logger.warn as Mock).mock.calls[0]![0]).toBe( 'GetCurrentUserSocialUseCase.execute: No friends found for driverId: driver-1', ); }); it('returns REPOSITORY_ERROR when repository throws', async () => { socialGraphRepository.getFriends.mockRejectedValue(new Error('DB error')); const input: GetCurrentUserSocialInput = { driverId: 'driver-1' }; const result = await useCase.execute(input); expect(result.isErr()).toBe(true); const err = result.unwrapErr() as GetCurrentUserSocialApplicationError; expect(err.code).toBe('REPOSITORY_ERROR'); expect(err.details.message).toBe('DB error'); expect(output.present).not.toHaveBeenCalled(); expect(logger.error).toHaveBeenCalledTimes(1); }); });