188 lines
5.7 KiB
TypeScript
188 lines
5.7 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { RacesViewDataBuilder } from './RacesViewDataBuilder';
|
|
import type { RacesPageDataDTO } from '@/lib/types/generated/RacesPageDataDTO';
|
|
|
|
describe('RacesViewDataBuilder', () => {
|
|
describe('happy paths', () => {
|
|
it('should transform RacesPageDataDTO to RacesViewData correctly', () => {
|
|
const now = new Date();
|
|
const pastDate = new Date(now.getTime() - 24 * 60 * 60 * 1000);
|
|
const futureDate = new Date(now.getTime() + 24 * 60 * 60 * 1000);
|
|
|
|
const apiDto: RacesPageDataDTO = {
|
|
races: [
|
|
{
|
|
id: 'race-1',
|
|
track: 'Spa',
|
|
car: 'Porsche 911 GT3',
|
|
scheduledAt: pastDate.toISOString(),
|
|
status: 'completed',
|
|
leagueId: 'league-1',
|
|
leagueName: 'Pro League',
|
|
strengthOfField: 1500,
|
|
isUpcoming: false,
|
|
isLive: false,
|
|
isPast: true,
|
|
},
|
|
{
|
|
id: 'race-2',
|
|
track: 'Monza',
|
|
car: 'Ferrari 488 GT3',
|
|
scheduledAt: futureDate.toISOString(),
|
|
status: 'scheduled',
|
|
leagueId: 'league-1',
|
|
leagueName: 'Pro League',
|
|
strengthOfField: 1600,
|
|
isUpcoming: true,
|
|
isLive: false,
|
|
isPast: false,
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = RacesViewDataBuilder.build(apiDto);
|
|
|
|
expect(result.races).toHaveLength(2);
|
|
expect(result.totalCount).toBe(2);
|
|
expect(result.completedCount).toBe(1);
|
|
expect(result.scheduledCount).toBe(1);
|
|
expect(result.leagues).toHaveLength(1);
|
|
expect(result.leagues[0]).toEqual({ id: 'league-1', name: 'Pro League' });
|
|
expect(result.upcomingRaces).toHaveLength(1);
|
|
expect(result.upcomingRaces[0].id).toBe('race-2');
|
|
expect(result.recentResults).toHaveLength(1);
|
|
expect(result.recentResults[0].id).toBe('race-1');
|
|
expect(result.racesByDate).toHaveLength(2);
|
|
});
|
|
|
|
it('should handle empty races list', () => {
|
|
const apiDto: RacesPageDataDTO = {
|
|
races: [],
|
|
};
|
|
|
|
const result = RacesViewDataBuilder.build(apiDto);
|
|
|
|
expect(result.races).toHaveLength(0);
|
|
expect(result.totalCount).toBe(0);
|
|
expect(result.leagues).toHaveLength(0);
|
|
expect(result.racesByDate).toHaveLength(0);
|
|
});
|
|
});
|
|
|
|
describe('data transformation', () => {
|
|
it('should preserve all DTO fields in the output', () => {
|
|
const now = new Date();
|
|
const apiDto: RacesPageDataDTO = {
|
|
races: [
|
|
{
|
|
id: 'race-1',
|
|
track: 'Spa',
|
|
car: 'Porsche 911 GT3',
|
|
scheduledAt: now.toISOString(),
|
|
status: 'scheduled',
|
|
leagueId: 'league-1',
|
|
leagueName: 'Pro League',
|
|
strengthOfField: 1500,
|
|
isUpcoming: true,
|
|
isLive: false,
|
|
isPast: false,
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = RacesViewDataBuilder.build(apiDto);
|
|
|
|
expect(result.races[0].id).toBe(apiDto.races[0].id);
|
|
expect(result.races[0].track).toBe(apiDto.races[0].track);
|
|
expect(result.races[0].car).toBe(apiDto.races[0].car);
|
|
expect(result.races[0].scheduledAt).toBe(apiDto.races[0].scheduledAt);
|
|
expect(result.races[0].status).toBe(apiDto.races[0].status);
|
|
expect(result.races[0].leagueId).toBe(apiDto.races[0].leagueId);
|
|
expect(result.races[0].leagueName).toBe(apiDto.races[0].leagueName);
|
|
expect(result.races[0].strengthOfField).toBe(apiDto.races[0].strengthOfField);
|
|
});
|
|
|
|
it('should not modify the input DTO', () => {
|
|
const now = new Date();
|
|
const apiDto: RacesPageDataDTO = {
|
|
races: [
|
|
{
|
|
id: 'race-1',
|
|
track: 'Spa',
|
|
car: 'Porsche 911 GT3',
|
|
scheduledAt: now.toISOString(),
|
|
status: 'scheduled',
|
|
isUpcoming: true,
|
|
isLive: false,
|
|
isPast: false,
|
|
},
|
|
],
|
|
};
|
|
|
|
const originalDto = JSON.parse(JSON.stringify(apiDto));
|
|
RacesViewDataBuilder.build(apiDto);
|
|
|
|
expect(apiDto).toEqual(originalDto);
|
|
});
|
|
});
|
|
|
|
describe('edge cases', () => {
|
|
it('should handle races with missing optional fields', () => {
|
|
const now = new Date();
|
|
const apiDto: RacesPageDataDTO = {
|
|
races: [
|
|
{
|
|
id: 'race-1',
|
|
track: 'Spa',
|
|
car: 'Porsche 911 GT3',
|
|
scheduledAt: now.toISOString(),
|
|
status: 'scheduled',
|
|
isUpcoming: true,
|
|
isLive: false,
|
|
isPast: false,
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = RacesViewDataBuilder.build(apiDto);
|
|
|
|
expect(result.races[0].leagueId).toBeUndefined();
|
|
expect(result.races[0].leagueName).toBeUndefined();
|
|
expect(result.races[0].strengthOfField).toBeNull();
|
|
});
|
|
|
|
it('should handle multiple races on the same date', () => {
|
|
const date = '2024-01-15T14:00:00.000Z';
|
|
const apiDto: RacesPageDataDTO = {
|
|
races: [
|
|
{
|
|
id: 'race-1',
|
|
track: 'Spa',
|
|
car: 'Porsche',
|
|
scheduledAt: date,
|
|
status: 'scheduled',
|
|
isUpcoming: true,
|
|
isLive: false,
|
|
isPast: false,
|
|
},
|
|
{
|
|
id: 'race-2',
|
|
track: 'Monza',
|
|
car: 'Ferrari',
|
|
scheduledAt: date,
|
|
status: 'scheduled',
|
|
isUpcoming: true,
|
|
isLive: false,
|
|
isPast: false,
|
|
},
|
|
],
|
|
};
|
|
|
|
const result = RacesViewDataBuilder.build(apiDto);
|
|
|
|
expect(result.racesByDate).toHaveLength(1);
|
|
expect(result.racesByDate[0].races).toHaveLength(2);
|
|
});
|
|
});
|
|
});
|