179 lines
4.0 KiB
TypeScript
179 lines
4.0 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import type { LeagueStandingDTO } from '../types/generated/LeagueStandingDTO';
|
|
import { LeagueStandingsViewModel } from './LeagueStandingsViewModel';
|
|
|
|
describe('LeagueStandingsViewModel', () => {
|
|
it('should create instance with standings', () => {
|
|
const standings: LeagueStandingDTO[] = [
|
|
{
|
|
driverId: 'driver-1',
|
|
position: 1,
|
|
points: 100,
|
|
wins: 3,
|
|
podiums: 5,
|
|
races: 8,
|
|
},
|
|
{
|
|
driverId: 'driver-2',
|
|
position: 2,
|
|
points: 85,
|
|
wins: 2,
|
|
podiums: 4,
|
|
races: 8,
|
|
},
|
|
];
|
|
|
|
const viewModel = new LeagueStandingsViewModel(
|
|
{ standings, drivers: [], memberships: [] },
|
|
'driver-1'
|
|
);
|
|
|
|
expect(viewModel.standings).toHaveLength(2);
|
|
expect(viewModel.standings[0].driverId).toBe('driver-1');
|
|
expect(viewModel.standings[1].driverId).toBe('driver-2');
|
|
});
|
|
|
|
it('should pass leader points to first entry', () => {
|
|
const standings: LeagueStandingDTO[] = [
|
|
{
|
|
driverId: 'driver-1',
|
|
position: 1,
|
|
points: 100,
|
|
wins: 3,
|
|
podiums: 5,
|
|
races: 8,
|
|
},
|
|
];
|
|
|
|
const viewModel = new LeagueStandingsViewModel(
|
|
{ standings, drivers: [], memberships: [] },
|
|
'driver-1'
|
|
);
|
|
|
|
expect(viewModel.standings[0].pointsGapToLeader).toBe(0);
|
|
});
|
|
|
|
it('should calculate points gaps correctly', () => {
|
|
const standings: LeagueStandingDTO[] = [
|
|
{
|
|
driverId: 'driver-1',
|
|
position: 1,
|
|
points: 100,
|
|
wins: 3,
|
|
podiums: 5,
|
|
races: 8,
|
|
},
|
|
{
|
|
driverId: 'driver-2',
|
|
position: 2,
|
|
points: 85,
|
|
wins: 2,
|
|
podiums: 4,
|
|
races: 8,
|
|
},
|
|
{
|
|
driverId: 'driver-3',
|
|
position: 3,
|
|
points: 70,
|
|
wins: 1,
|
|
podiums: 3,
|
|
races: 8,
|
|
},
|
|
];
|
|
|
|
const viewModel = new LeagueStandingsViewModel(
|
|
{ standings, drivers: [], memberships: [] },
|
|
'driver-2'
|
|
);
|
|
|
|
expect(viewModel.standings[1].pointsGapToLeader).toBe(-15);
|
|
expect(viewModel.standings[1].pointsGapToNext).toBe(15);
|
|
});
|
|
|
|
it('should identify current user', () => {
|
|
const standings: LeagueStandingDTO[] = [
|
|
{
|
|
driverId: 'driver-1',
|
|
position: 1,
|
|
points: 100,
|
|
wins: 3,
|
|
podiums: 5,
|
|
races: 8,
|
|
},
|
|
{
|
|
driverId: 'driver-2',
|
|
position: 2,
|
|
points: 85,
|
|
wins: 2,
|
|
podiums: 4,
|
|
races: 8,
|
|
},
|
|
];
|
|
|
|
const viewModel = new LeagueStandingsViewModel(
|
|
{ standings, drivers: [], memberships: [] },
|
|
'driver-2'
|
|
);
|
|
|
|
expect(viewModel.standings[0].isCurrentUser).toBe(false);
|
|
expect(viewModel.standings[1].isCurrentUser).toBe(true);
|
|
});
|
|
|
|
it('should handle empty standings', () => {
|
|
const viewModel = new LeagueStandingsViewModel(
|
|
{ standings: [], drivers: [], memberships: [] },
|
|
'driver-1'
|
|
);
|
|
|
|
expect(viewModel.standings).toHaveLength(0);
|
|
});
|
|
|
|
it('should track position changes when previousStandings provided', () => {
|
|
const standings: LeagueStandingDTO[] = [
|
|
{
|
|
driverId: 'driver-1',
|
|
position: 1,
|
|
points: 100,
|
|
wins: 3,
|
|
podiums: 5,
|
|
races: 8,
|
|
},
|
|
{
|
|
driverId: 'driver-2',
|
|
position: 2,
|
|
points: 85,
|
|
wins: 2,
|
|
podiums: 4,
|
|
races: 8,
|
|
},
|
|
];
|
|
|
|
const previousStandings: LeagueStandingDTO[] = [
|
|
{
|
|
driverId: 'driver-1',
|
|
position: 2,
|
|
points: 80,
|
|
wins: 2,
|
|
podiums: 4,
|
|
races: 7,
|
|
},
|
|
{
|
|
driverId: 'driver-2',
|
|
position: 1,
|
|
points: 90,
|
|
wins: 3,
|
|
podiums: 5,
|
|
races: 7,
|
|
},
|
|
];
|
|
|
|
const viewModel = new LeagueStandingsViewModel(
|
|
{ standings, drivers: [], memberships: [] },
|
|
'driver-1',
|
|
previousStandings
|
|
);
|
|
|
|
expect(viewModel.standings[0].trend).toBe('up');
|
|
expect(viewModel.standings[1].trend).toBe('down');
|
|
});
|
|
}); |