view data tests
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { LeagueScheduleViewDataBuilder } from './LeagueScheduleViewDataBuilder';
|
||||
|
||||
describe('LeagueScheduleViewDataBuilder', () => {
|
||||
describe('happy paths', () => {
|
||||
it('should transform schedule DTO to LeagueScheduleViewData correctly', () => {
|
||||
const now = new Date();
|
||||
const pastDate = new Date(now.getTime() - 24 * 60 * 60 * 1000); // 1 day ago
|
||||
const futureDate = new Date(now.getTime() + 24 * 60 * 60 * 1000); // 1 day from now
|
||||
|
||||
const apiDto = {
|
||||
leagueId: 'league-1',
|
||||
races: [
|
||||
{
|
||||
id: 'race-1',
|
||||
name: 'Past Race',
|
||||
date: pastDate.toISOString(),
|
||||
track: 'Spa',
|
||||
car: 'Porsche 911 GT3',
|
||||
sessionType: 'race',
|
||||
},
|
||||
{
|
||||
id: 'race-2',
|
||||
name: 'Future Race',
|
||||
date: futureDate.toISOString(),
|
||||
track: 'Monza',
|
||||
car: 'Ferrari 488 GT3',
|
||||
sessionType: 'race',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const result = LeagueScheduleViewDataBuilder.build(apiDto, 'driver-1', true);
|
||||
|
||||
expect(result.leagueId).toBe('league-1');
|
||||
expect(result.races).toHaveLength(2);
|
||||
expect(result.races[0].id).toBe('race-1');
|
||||
expect(result.races[0].name).toBe('Past Race');
|
||||
expect(result.races[0].scheduledAt).toBe(pastDate.toISOString());
|
||||
expect(result.races[0].track).toBe('Spa');
|
||||
expect(result.races[0].car).toBe('Porsche 911 GT3');
|
||||
expect(result.races[0].sessionType).toBe('race');
|
||||
expect(result.races[0].isPast).toBe(true);
|
||||
expect(result.races[0].isUpcoming).toBe(false);
|
||||
expect(result.races[0].status).toBe('completed');
|
||||
expect(result.races[0].isUserRegistered).toBe(false);
|
||||
expect(result.races[0].canRegister).toBe(false);
|
||||
expect(result.races[0].canEdit).toBe(true);
|
||||
expect(result.races[0].canReschedule).toBe(true);
|
||||
expect(result.races[1].id).toBe('race-2');
|
||||
expect(result.races[1].name).toBe('Future Race');
|
||||
expect(result.races[1].scheduledAt).toBe(futureDate.toISOString());
|
||||
expect(result.races[1].track).toBe('Monza');
|
||||
expect(result.races[1].car).toBe('Ferrari 488 GT3');
|
||||
expect(result.races[1].sessionType).toBe('race');
|
||||
expect(result.races[1].isPast).toBe(false);
|
||||
expect(result.races[1].isUpcoming).toBe(true);
|
||||
expect(result.races[1].status).toBe('scheduled');
|
||||
expect(result.races[1].isUserRegistered).toBe(false);
|
||||
expect(result.races[1].canRegister).toBe(true);
|
||||
expect(result.races[1].canEdit).toBe(true);
|
||||
expect(result.races[1].canReschedule).toBe(true);
|
||||
expect(result.currentDriverId).toBe('driver-1');
|
||||
expect(result.isAdmin).toBe(true);
|
||||
});
|
||||
|
||||
it('should handle empty races list', () => {
|
||||
const apiDto = {
|
||||
leagueId: 'league-1',
|
||||
races: [],
|
||||
};
|
||||
|
||||
const result = LeagueScheduleViewDataBuilder.build(apiDto);
|
||||
|
||||
expect(result.leagueId).toBe('league-1');
|
||||
expect(result.races).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should handle non-admin user', () => {
|
||||
const now = new Date();
|
||||
const futureDate = new Date(now.getTime() + 24 * 60 * 60 * 1000);
|
||||
|
||||
const apiDto = {
|
||||
leagueId: 'league-1',
|
||||
races: [
|
||||
{
|
||||
id: 'race-1',
|
||||
name: 'Future Race',
|
||||
date: futureDate.toISOString(),
|
||||
track: 'Spa',
|
||||
car: 'Porsche 911 GT3',
|
||||
sessionType: 'race',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const result = LeagueScheduleViewDataBuilder.build(apiDto, 'driver-1', false);
|
||||
|
||||
expect(result.races[0].canEdit).toBe(false);
|
||||
expect(result.races[0].canReschedule).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('data transformation', () => {
|
||||
it('should preserve all DTO fields in the output', () => {
|
||||
const now = new Date();
|
||||
const futureDate = new Date(now.getTime() + 24 * 60 * 60 * 1000);
|
||||
|
||||
const apiDto = {
|
||||
leagueId: 'league-1',
|
||||
races: [
|
||||
{
|
||||
id: 'race-1',
|
||||
name: 'Test Race',
|
||||
date: futureDate.toISOString(),
|
||||
track: 'Spa',
|
||||
car: 'Porsche 911 GT3',
|
||||
sessionType: 'race',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const result = LeagueScheduleViewDataBuilder.build(apiDto);
|
||||
|
||||
expect(result.leagueId).toBe(apiDto.leagueId);
|
||||
expect(result.races[0].id).toBe(apiDto.races[0].id);
|
||||
expect(result.races[0].name).toBe(apiDto.races[0].name);
|
||||
expect(result.races[0].scheduledAt).toBe(apiDto.races[0].date);
|
||||
expect(result.races[0].track).toBe(apiDto.races[0].track);
|
||||
expect(result.races[0].car).toBe(apiDto.races[0].car);
|
||||
expect(result.races[0].sessionType).toBe(apiDto.races[0].sessionType);
|
||||
});
|
||||
|
||||
it('should not modify the input DTO', () => {
|
||||
const now = new Date();
|
||||
const futureDate = new Date(now.getTime() + 24 * 60 * 60 * 1000);
|
||||
|
||||
const apiDto = {
|
||||
leagueId: 'league-1',
|
||||
races: [
|
||||
{
|
||||
id: 'race-1',
|
||||
name: 'Test Race',
|
||||
date: futureDate.toISOString(),
|
||||
track: 'Spa',
|
||||
car: 'Porsche 911 GT3',
|
||||
sessionType: 'race',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const originalDto = JSON.parse(JSON.stringify(apiDto));
|
||||
LeagueScheduleViewDataBuilder.build(apiDto);
|
||||
|
||||
expect(apiDto).toEqual(originalDto);
|
||||
});
|
||||
});
|
||||
|
||||
describe('edge cases', () => {
|
||||
it('should handle races with missing optional fields', () => {
|
||||
const now = new Date();
|
||||
const futureDate = new Date(now.getTime() + 24 * 60 * 60 * 1000);
|
||||
|
||||
const apiDto = {
|
||||
leagueId: 'league-1',
|
||||
races: [
|
||||
{
|
||||
id: 'race-1',
|
||||
name: 'Test Race',
|
||||
date: futureDate.toISOString(),
|
||||
track: 'Spa',
|
||||
car: 'Porsche 911 GT3',
|
||||
sessionType: 'race',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const result = LeagueScheduleViewDataBuilder.build(apiDto);
|
||||
|
||||
expect(result.races[0].track).toBe('Spa');
|
||||
expect(result.races[0].car).toBe('Porsche 911 GT3');
|
||||
expect(result.races[0].sessionType).toBe('race');
|
||||
});
|
||||
|
||||
it('should handle races at exactly the current time', () => {
|
||||
const now = new Date();
|
||||
const currentRaceDate = new Date(now.getTime());
|
||||
|
||||
const apiDto = {
|
||||
leagueId: 'league-1',
|
||||
races: [
|
||||
{
|
||||
id: 'race-1',
|
||||
name: 'Current Race',
|
||||
date: currentRaceDate.toISOString(),
|
||||
track: 'Spa',
|
||||
car: 'Porsche 911 GT3',
|
||||
sessionType: 'race',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const result = LeagueScheduleViewDataBuilder.build(apiDto);
|
||||
|
||||
// Race at current time should be considered past
|
||||
expect(result.races[0].isPast).toBe(true);
|
||||
expect(result.races[0].isUpcoming).toBe(false);
|
||||
expect(result.races[0].status).toBe('completed');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user