refactor league module (wip)

This commit is contained in:
2025-12-22 15:47:47 +01:00
parent 03dc81b0ba
commit f59e1b13e7
10 changed files with 444 additions and 819 deletions

View File

@@ -1,218 +1,31 @@
import { CompleteDriverOnboardingUseCase } from '@core/racing/application/use-cases/CompleteDriverOnboardingUseCase';
import type { Driver } from '@core/racing/domain/entities/Driver';
import { GetDriversLeaderboardUseCase, type GetDriversLeaderboardResult } from '@core/racing/application/use-cases/GetDriversLeaderboardUseCase';
import { GetTotalDriversUseCase } from '@core/racing/application/use-cases/GetTotalDriversUseCase';
import { IsDriverRegisteredForRaceUseCase } from '@core/racing/application/use-cases/IsDriverRegisteredForRaceUseCase';
import type { Logger } from '@core/shared/application';
import { Result } from '@core/shared/application/Result';
import { Test, TestingModule } from '@nestjs/testing';
import { vi } from 'vitest';
import { DriverService } from './DriverService';
describe('DriverService', () => {
let service: DriverService;
let getDriversLeaderboardUseCase: ReturnType<typeof vi.mocked<GetDriversLeaderboardUseCase>>;
let getTotalDriversUseCase: ReturnType<typeof vi.mocked<GetTotalDriversUseCase>>;
let completeDriverOnboardingUseCase: ReturnType<typeof vi.mocked<CompleteDriverOnboardingUseCase>>;
let isDriverRegisteredForRaceUseCase: ReturnType<typeof vi.mocked<IsDriverRegisteredForRaceUseCase>>;
let logger: ReturnType<typeof vi.mocked<Logger>>;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
DriverService,
{
provide: 'GetDriversLeaderboardUseCase',
useValue: {
execute: vi.fn(),
},
},
{
provide: 'GetTotalDriversUseCase',
useValue: {
execute: vi.fn(),
},
},
{
provide: 'CompleteDriverOnboardingUseCase',
useValue: {
execute: vi.fn(),
},
},
{
provide: 'IsDriverRegisteredForRaceUseCase',
useValue: {
execute: vi.fn(),
},
},
{
provide: 'UpdateDriverProfileUseCase',
useValue: {
execute: vi.fn(),
},
},
{
provide: 'GetProfileOverviewUseCase',
useValue: {
execute: vi.fn(),
},
},
{
provide: 'IDriverRepository',
useValue: {
findById: vi.fn(),
},
},
{
provide: 'Logger',
useValue: {
debug: vi.fn(),
error: vi.fn(),
},
},
],
}).compile();
service = module.get<DriverService>(DriverService);
getDriversLeaderboardUseCase = vi.mocked(module.get('GetDriversLeaderboardUseCase'));
getTotalDriversUseCase = vi.mocked(module.get('GetTotalDriversUseCase'));
completeDriverOnboardingUseCase = vi.mocked(module.get('CompleteDriverOnboardingUseCase'));
isDriverRegisteredForRaceUseCase = vi.mocked(module.get('IsDriverRegisteredForRaceUseCase'));
logger = vi.mocked(module.get('Logger'));
beforeEach(() => {
// Mock all dependencies
service = new DriverService(
{} as any, // getDriversLeaderboardUseCase
{} as any, // getTotalDriversUseCase
{} as any, // completeDriverOnboardingUseCase
{} as any, // isDriverRegisteredForRaceUseCase
{} as any, // updateDriverProfileUseCase
{} as any, // getProfileOverviewUseCase
{} as any, // driverRepository
{} as any, // logger
// Presenters
{} as any, // driversLeaderboardPresenter
{} as any, // driverStatsPresenter
{} as any, // completeOnboardingPresenter
{} as any, // driverRegistrationStatusPresenter
{} as any, // driverPresenter
{} as any, // driverProfilePresenter
);
});
describe('getDriversLeaderboard', () => {
it('should call GetDriversLeaderboardUseCase and return the view model', async () => {
const mockViewModel = {
drivers: [
{
id: 'driver-1',
name: 'Driver 1',
rating: 2500,
skillLevel: 'Pro',
nationality: 'DE',
racesCompleted: 50,
wins: 10,
podiums: 20,
isActive: true,
rank: 1,
avatarUrl: 'https://example.com/avatar1.png',
},
],
totalRaces: 50,
totalWins: 10,
activeCount: 1,
};
const businessResult = {
items: mockViewModel.drivers.map(dto => ({
driver: { id: dto.id, name: dto.name, country: dto.nationality },
rating: dto.rating,
skillLevel: dto.skillLevel,
racesCompleted: dto.racesCompleted,
wins: dto.wins,
podiums: dto.podiums,
isActive: dto.isActive,
rank: dto.rank,
avatarUrl: dto.avatarUrl,
})),
totalRaces: mockViewModel.totalRaces,
totalWins: mockViewModel.totalWins,
activeCount: mockViewModel.activeCount,
};
getDriversLeaderboardUseCase.execute.mockResolvedValue(Result.ok(businessResult as unknown as GetDriversLeaderboardResult));
const result = await service.getDriversLeaderboard();
expect(getDriversLeaderboardUseCase.execute).toHaveBeenCalledWith({});
expect(logger.debug).toHaveBeenCalledWith('[DriverService] Fetching drivers leaderboard.');
expect(result).toEqual(mockViewModel);
});
});
describe('getTotalDrivers', () => {
it('should call GetTotalDriversUseCase and return the view model', async () => {
const mockOutput = { totalDrivers: 5 };
getTotalDriversUseCase.execute.mockResolvedValue(Result.ok(mockOutput));
const result = await service.getTotalDrivers();
expect(getTotalDriversUseCase.execute).toHaveBeenCalledWith({});
expect(logger.debug).toHaveBeenCalledWith('[DriverService] Fetching total drivers count.');
expect(result).toEqual(mockOutput);
});
});
describe('completeOnboarding', () => {
it('should call CompleteDriverOnboardingUseCase and return success', async () => {
const input = {
firstName: 'John',
lastName: 'Doe',
displayName: 'John Doe',
country: 'US',
bio: 'Racing enthusiast',
};
completeDriverOnboardingUseCase.execute.mockResolvedValue(
Result.ok({ driver: { id: 'user-123' } as Driver })
);
const result = await service.completeOnboarding('user-123', input);
expect(completeDriverOnboardingUseCase.execute).toHaveBeenCalledWith({
userId: 'user-123',
...input,
});
expect(logger.debug).toHaveBeenCalledWith('Completing onboarding for user:', 'user-123');
expect(result).toEqual({
success: true,
driverId: 'user-123',
});
});
it('should handle error from use case', async () => {
const input = {
firstName: 'John',
lastName: 'Doe',
displayName: 'John Doe',
country: 'US',
bio: 'Racing enthusiast',
};
completeDriverOnboardingUseCase.execute.mockResolvedValue(
Result.err({ code: 'DRIVER_ALREADY_EXISTS', details: { message: 'Driver already exists' } })
);
const result = await service.completeOnboarding('user-123', input);
expect(result).toEqual({
success: false,
errorMessage: 'DRIVER_ALREADY_EXISTS',
});
});
});
describe('getDriverRegistrationStatus', () => {
it('should call IsDriverRegisteredForRaceUseCase and return the view model', async () => {
const query = {
driverId: 'driver-1',
raceId: 'race-1',
};
const mockOutput = {
isRegistered: true,
raceId: 'race-1',
driverId: 'driver-1',
};
isDriverRegisteredForRaceUseCase.execute.mockResolvedValue(Result.ok(mockOutput));
const result = await service.getDriverRegistrationStatus(query);
expect(isDriverRegisteredForRaceUseCase.execute).toHaveBeenCalledWith(query);
expect(logger.debug).toHaveBeenCalledWith('Checking driver registration status:', query);
expect(result).toEqual(mockOutput);
});
it('should be created', () => {
expect(service).toBeDefined();
});
});