integration tests
This commit is contained in:
113
tests/integration/leagues/standings/GetLeagueStandings.test.ts
Normal file
113
tests/integration/leagues/standings/GetLeagueStandings.test.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { LeaguesTestContext } from '../LeaguesTestContext';
|
||||
import { Driver } from '../../../../core/racing/domain/entities/Driver';
|
||||
import { Standing } from '../../../../core/racing/domain/entities/Standing';
|
||||
|
||||
describe('GetLeagueStandings', () => {
|
||||
let context: LeaguesTestContext;
|
||||
|
||||
beforeEach(() => {
|
||||
context = new LeaguesTestContext();
|
||||
});
|
||||
|
||||
describe('Success Path', () => {
|
||||
it('should retrieve championship standings with all driver statistics', async () => {
|
||||
// Given: A league exists with multiple drivers
|
||||
const leagueId = 'league-123';
|
||||
const driver1Id = 'driver-1';
|
||||
const driver2Id = 'driver-2';
|
||||
|
||||
await context.racingDriverRepository.create(Driver.create({
|
||||
id: driver1Id,
|
||||
name: 'Driver One',
|
||||
iracingId: 'ir-1',
|
||||
country: 'US',
|
||||
}));
|
||||
|
||||
await context.racingDriverRepository.create(Driver.create({
|
||||
id: driver2Id,
|
||||
name: 'Driver Two',
|
||||
iracingId: 'ir-2',
|
||||
country: 'DE',
|
||||
}));
|
||||
|
||||
// And: Each driver has points
|
||||
await context.standingRepository.save(Standing.create({
|
||||
leagueId,
|
||||
driverId: driver1Id,
|
||||
points: 100,
|
||||
position: 1,
|
||||
}));
|
||||
|
||||
await context.standingRepository.save(Standing.create({
|
||||
leagueId,
|
||||
driverId: driver2Id,
|
||||
points: 80,
|
||||
position: 2,
|
||||
}));
|
||||
|
||||
// When: GetLeagueStandingsUseCase.execute() is called with league ID
|
||||
const result = await context.getLeagueStandingsUseCase.execute({ leagueId });
|
||||
|
||||
// Then: The result should contain all drivers ranked by points
|
||||
expect(result.isOk()).toBe(true);
|
||||
const data = result.unwrap();
|
||||
expect(data.standings).toHaveLength(2);
|
||||
expect(data.standings[0].driverId).toBe(driver1Id);
|
||||
expect(data.standings[0].points).toBe(100);
|
||||
expect(data.standings[0].rank).toBe(1);
|
||||
expect(data.standings[1].driverId).toBe(driver2Id);
|
||||
expect(data.standings[1].points).toBe(80);
|
||||
expect(data.standings[1].rank).toBe(2);
|
||||
});
|
||||
|
||||
it('should retrieve standings with minimal driver statistics', async () => {
|
||||
const leagueId = 'league-123';
|
||||
const driverId = 'driver-1';
|
||||
|
||||
await context.racingDriverRepository.create(Driver.create({
|
||||
id: driverId,
|
||||
name: 'Driver One',
|
||||
iracingId: 'ir-1',
|
||||
country: 'US',
|
||||
}));
|
||||
|
||||
await context.standingRepository.save(Standing.create({
|
||||
leagueId,
|
||||
driverId,
|
||||
points: 10,
|
||||
position: 1,
|
||||
}));
|
||||
|
||||
const result = await context.getLeagueStandingsUseCase.execute({ leagueId });
|
||||
|
||||
expect(result.isOk()).toBe(true);
|
||||
expect(result.unwrap().standings).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Edge Cases', () => {
|
||||
it('should handle drivers with no championship standings', async () => {
|
||||
const leagueId = 'league-empty';
|
||||
const result = await context.getLeagueStandingsUseCase.execute({ leagueId });
|
||||
|
||||
expect(result.isOk()).toBe(true);
|
||||
expect(result.unwrap().standings).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Error Handling', () => {
|
||||
it('should handle repository errors gracefully', async () => {
|
||||
// Mock repository error
|
||||
context.standingRepository.findByLeagueId = async () => {
|
||||
throw new Error('Database error');
|
||||
};
|
||||
|
||||
const result = await context.getLeagueStandingsUseCase.execute({ leagueId: 'any' });
|
||||
|
||||
expect(result.isErr()).toBe(true);
|
||||
// The Result class in this project seems to use .error for the error value
|
||||
expect((result as any).error.code).toBe('REPOSITORY_ERROR');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,91 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { LeaguesTestContext } from '../LeaguesTestContext';
|
||||
import { Driver } from '../../../../core/racing/domain/entities/Driver';
|
||||
import { Standing } from '../../../../core/racing/domain/entities/Standing';
|
||||
import { Result } from '../../../../core/racing/domain/entities/result/Result';
|
||||
import { Race } from '../../../../core/racing/domain/entities/Race';
|
||||
import { League } from '../../../../core/racing/domain/entities/League';
|
||||
|
||||
describe('StandingsCalculation', () => {
|
||||
let context: LeaguesTestContext;
|
||||
|
||||
beforeEach(() => {
|
||||
context = new LeaguesTestContext();
|
||||
});
|
||||
|
||||
it('should correctly calculate driver statistics from race results', async () => {
|
||||
// Given: A league exists
|
||||
const leagueId = 'league-123';
|
||||
const driverId = 'driver-1';
|
||||
|
||||
await context.racingLeagueRepository.create(League.create({
|
||||
id: leagueId,
|
||||
name: 'Test League',
|
||||
description: 'Test Description',
|
||||
ownerId: 'owner-1',
|
||||
}));
|
||||
|
||||
await context.racingDriverRepository.create(Driver.create({
|
||||
id: driverId,
|
||||
name: 'Driver One',
|
||||
iracingId: 'ir-1',
|
||||
country: 'US',
|
||||
}));
|
||||
|
||||
// And: A driver has completed races
|
||||
const race1Id = 'race-1';
|
||||
const race2Id = 'race-2';
|
||||
|
||||
await context.raceRepository.create(Race.create({
|
||||
id: race1Id,
|
||||
leagueId,
|
||||
scheduledAt: new Date(),
|
||||
track: 'Daytona',
|
||||
car: 'GT3',
|
||||
status: 'completed',
|
||||
}));
|
||||
|
||||
await context.raceRepository.create(Race.create({
|
||||
id: race2Id,
|
||||
leagueId,
|
||||
scheduledAt: new Date(),
|
||||
track: 'Sebring',
|
||||
car: 'GT3',
|
||||
status: 'completed',
|
||||
}));
|
||||
|
||||
// And: The driver has results (1 win, 1 podium)
|
||||
await context.resultRepository.create(Result.create({
|
||||
id: 'res-1',
|
||||
raceId: race1Id,
|
||||
driverId,
|
||||
position: 1,
|
||||
fastestLap: 120000,
|
||||
incidents: 0,
|
||||
startPosition: 1,
|
||||
}));
|
||||
|
||||
await context.resultRepository.create(Result.create({
|
||||
id: 'res-2',
|
||||
raceId: race2Id,
|
||||
driverId,
|
||||
position: 3,
|
||||
fastestLap: 121000,
|
||||
incidents: 2,
|
||||
startPosition: 5,
|
||||
}));
|
||||
|
||||
// When: Standings are recalculated
|
||||
await context.standingRepository.recalculate(leagueId);
|
||||
|
||||
// Then: Driver statistics should show correct values
|
||||
const standings = await context.standingRepository.findByLeagueId(leagueId);
|
||||
const driverStanding = standings.find(s => s.driverId.toString() === driverId);
|
||||
|
||||
expect(driverStanding).toBeDefined();
|
||||
expect(driverStanding?.wins).toBe(1);
|
||||
expect(driverStanding?.racesCompleted).toBe(2);
|
||||
// Points depend on the points system (default f1-2024: 1st=25, 3rd=15)
|
||||
expect(driverStanding?.points.toNumber()).toBe(40);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user