import { Standing } from './Standing'; import { RacingDomainValidationError } from '../errors/RacingDomainError'; describe('Standing', () => { const validProps = { id: 'standing-123', leagueId: 'league-456', driverId: 'driver-789', points: 100, wins: 5, position: 2, racesCompleted: 10, }; describe('create', () => { it('should create a Standing with valid props', () => { const standing = Standing.create(validProps); expect(standing.id).toBe('standing-123'); expect(standing.leagueId.toString()).toBe('league-456'); expect(standing.driverId.toString()).toBe('driver-789'); expect(standing.points.toNumber()).toBe(100); expect(standing.wins).toBe(5); expect(standing.position.toNumber()).toBe(2); expect(standing.racesCompleted).toBe(10); }); it('should generate id if not provided', () => { const propsWithoutId = { leagueId: 'league-456', driverId: 'driver-789', points: 100, wins: 5, position: 2, racesCompleted: 10, }; const standing = Standing.create(propsWithoutId); expect(standing.id).toBe('league-456:driver-789'); }); it('should use defaults for optional props', () => { const minimalProps = { leagueId: 'league-456', driverId: 'driver-789', }; const standing = Standing.create(minimalProps); expect(standing.points.toNumber()).toBe(0); expect(standing.wins).toBe(0); expect(standing.position.toNumber()).toBe(1); expect(standing.racesCompleted).toBe(0); }); it('should throw for invalid leagueId', () => { expect(() => Standing.create({ ...validProps, leagueId: '' })).toThrow(RacingDomainValidationError); }); it('should throw for invalid driverId', () => { expect(() => Standing.create({ ...validProps, driverId: '' })).toThrow(RacingDomainValidationError); }); it('should throw for negative points', () => { expect(() => Standing.create({ ...validProps, points: -1 })).toThrow(RacingDomainValidationError); }); it('should throw for invalid position', () => { expect(() => Standing.create({ ...validProps, position: 0 })).toThrow(RacingDomainValidationError); }); }); describe('addRaceResult', () => { it('should add points and increment races completed', () => { const standing = Standing.create(validProps); const pointsSystem = { 1: 25, 2: 18, 3: 15 }; const updated = standing.addRaceResult(1, pointsSystem); expect(updated.points.toNumber()).toBe(125); // 100 + 25 expect(updated.wins).toBe(6); // 5 + 1 expect(updated.racesCompleted).toBe(11); // 10 + 1 }); it('should not add win for non-first position', () => { const standing = Standing.create(validProps); const pointsSystem = { 1: 25, 2: 18, 3: 15 }; const updated = standing.addRaceResult(2, pointsSystem); expect(updated.points.toNumber()).toBe(118); // 100 + 18 expect(updated.wins).toBe(5); // no change expect(updated.racesCompleted).toBe(11); }); it('should handle position not in points system', () => { const standing = Standing.create(validProps); const pointsSystem = { 1: 25, 2: 18 }; const updated = standing.addRaceResult(5, pointsSystem); expect(updated.points.toNumber()).toBe(100); // no points expect(updated.wins).toBe(5); expect(updated.racesCompleted).toBe(11); }); }); describe('updatePosition', () => { it('should update position', () => { const standing = Standing.create(validProps); const updated = standing.updatePosition(1); expect(updated.position.toNumber()).toBe(1); expect(updated.points.toNumber()).toBe(100); // unchanged }); it('should throw for invalid position', () => { const standing = Standing.create(validProps); expect(() => standing.updatePosition(0)).toThrow(RacingDomainValidationError); }); }); describe('getAveragePoints', () => { it('should calculate average points', () => { const standing = Standing.create(validProps); expect(standing.getAveragePoints()).toBe(10); // 100 / 10 }); it('should return 0 for no races completed', () => { const standing = Standing.create({ ...validProps, racesCompleted: 0 }); expect(standing.getAveragePoints()).toBe(0); }); }); describe('getWinPercentage', () => { it('should calculate win percentage', () => { const standing = Standing.create(validProps); expect(standing.getWinPercentage()).toBe(50); // 5 / 10 * 100 }); it('should return 0 for no races completed', () => { const standing = Standing.create({ ...validProps, racesCompleted: 0 }); expect(standing.getWinPercentage()).toBe(0); }); }); });