view data tests
This commit is contained in:
187
apps/website/lib/builders/view-data/RacesViewDataBuilder.test.ts
Normal file
187
apps/website/lib/builders/view-data/RacesViewDataBuilder.test.ts
Normal file
@@ -0,0 +1,187 @@
|
||||
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);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user