613 lines
18 KiB
TypeScript
613 lines
18 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { LeagueSummaryViewModelBuilder } from './LeagueSummaryViewModelBuilder';
|
|
import type { LeaguesViewData } from '@/lib/view-data/LeaguesViewData';
|
|
|
|
describe('LeagueSummaryViewModelBuilder', () => {
|
|
describe('happy paths', () => {
|
|
it('should transform LeaguesViewData to LeagueSummaryViewModel correctly', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-123',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 16,
|
|
usedTeamSlots: 10,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'driver',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result).toEqual({
|
|
id: 'league-123',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 16,
|
|
usedTeamSlots: 10,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'driver',
|
|
pointsSystem: 'standard',
|
|
},
|
|
});
|
|
});
|
|
|
|
it('should handle league without description', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-456',
|
|
name: 'Test League',
|
|
description: null,
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 16,
|
|
usedTeamSlots: 10,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'driver',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.description).toBe('');
|
|
});
|
|
|
|
it('should handle league without category', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-789',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 16,
|
|
usedTeamSlots: 10,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: null,
|
|
scoring: {
|
|
primaryChampionshipType: 'driver',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.category).toBeUndefined();
|
|
});
|
|
|
|
it('should handle league without scoring', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-101',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 16,
|
|
usedTeamSlots: 10,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: null,
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.scoring).toBeUndefined();
|
|
});
|
|
|
|
it('should handle league without maxTeams', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-102',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: null,
|
|
usedTeamSlots: 10,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'driver',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.maxTeams).toBe(0);
|
|
});
|
|
|
|
it('should handle league without usedTeamSlots', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-103',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 16,
|
|
usedTeamSlots: null,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'driver',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.usedTeamSlots).toBe(0);
|
|
});
|
|
});
|
|
|
|
describe('data transformation', () => {
|
|
it('should preserve all DTO fields in the output', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-104',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 16,
|
|
usedTeamSlots: 10,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'driver',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.id).toBe(league.id);
|
|
expect(result.name).toBe(league.name);
|
|
expect(result.description).toBe(league.description);
|
|
expect(result.logoUrl).toBe(league.logoUrl);
|
|
expect(result.ownerId).toBe(league.ownerId);
|
|
expect(result.createdAt).toBe(league.createdAt);
|
|
expect(result.maxDrivers).toBe(league.maxDrivers);
|
|
expect(result.usedDriverSlots).toBe(league.usedDriverSlots);
|
|
expect(result.maxTeams).toBe(league.maxTeams);
|
|
expect(result.usedTeamSlots).toBe(league.usedTeamSlots);
|
|
expect(result.structureSummary).toBe(league.structureSummary);
|
|
expect(result.timingSummary).toBe(league.timingSummary);
|
|
expect(result.category).toBe(league.category);
|
|
expect(result.scoring).toEqual(league.scoring);
|
|
});
|
|
|
|
it('should not modify the input DTO', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-105',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 16,
|
|
usedTeamSlots: 10,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'driver',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const originalLeague = { ...league };
|
|
LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(league).toEqual(originalLeague);
|
|
});
|
|
});
|
|
|
|
describe('edge cases', () => {
|
|
it('should handle league with empty description', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-106',
|
|
name: 'Test League',
|
|
description: '',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 16,
|
|
usedTeamSlots: 10,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'driver',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.description).toBe('');
|
|
});
|
|
|
|
it('should handle league with different categories', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-107',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 16,
|
|
usedTeamSlots: 10,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Amateur',
|
|
scoring: {
|
|
primaryChampionshipType: 'driver',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.category).toBe('Amateur');
|
|
});
|
|
|
|
it('should handle league with different scoring types', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-108',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 16,
|
|
usedTeamSlots: 10,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'team',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.scoring?.primaryChampionshipType).toBe('team');
|
|
});
|
|
|
|
it('should handle league with different scoring systems', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-109',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 16,
|
|
usedTeamSlots: 10,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'driver',
|
|
pointsSystem: 'custom',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.scoring?.pointsSystem).toBe('custom');
|
|
});
|
|
|
|
it('should handle league with different structure summaries', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-110',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 16,
|
|
usedTeamSlots: 10,
|
|
structureSummary: 'Multiple championships',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'driver',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.structureSummary).toBe('Multiple championships');
|
|
});
|
|
|
|
it('should handle league with different timing summaries', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-111',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 16,
|
|
usedTeamSlots: 10,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Bi-weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'driver',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.timingSummary).toBe('Bi-weekly races');
|
|
});
|
|
|
|
it('should handle league with different maxDrivers', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-112',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 64,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 16,
|
|
usedTeamSlots: 10,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'driver',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.maxDrivers).toBe(64);
|
|
});
|
|
|
|
it('should handle league with different usedDriverSlots', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-113',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 15,
|
|
maxTeams: 16,
|
|
usedTeamSlots: 10,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'driver',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.usedDriverSlots).toBe(15);
|
|
});
|
|
|
|
it('should handle league with different maxTeams', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-114',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 32,
|
|
usedTeamSlots: 10,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'driver',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.maxTeams).toBe(32);
|
|
});
|
|
|
|
it('should handle league with different usedTeamSlots', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-115',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 16,
|
|
usedTeamSlots: 5,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'driver',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.usedTeamSlots).toBe(5);
|
|
});
|
|
|
|
it('should handle league with zero maxTeams', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-116',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 0,
|
|
usedTeamSlots: 0,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'driver',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.maxTeams).toBe(0);
|
|
});
|
|
|
|
it('should handle league with zero usedTeamSlots', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-117',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 16,
|
|
usedTeamSlots: 0,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'driver',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.usedTeamSlots).toBe(0);
|
|
});
|
|
|
|
it('should handle league with different primary championship types', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-118',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 16,
|
|
usedTeamSlots: 10,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'nations',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.scoring?.primaryChampionshipType).toBe('nations');
|
|
});
|
|
|
|
it('should handle league with different primary championship types (trophy)', () => {
|
|
const league: LeaguesViewData['leagues'][number] = {
|
|
id: 'league-119',
|
|
name: 'Test League',
|
|
description: 'Test Description',
|
|
logoUrl: 'logo-url',
|
|
ownerId: 'owner-1',
|
|
createdAt: '2024-01-01',
|
|
maxDrivers: 32,
|
|
usedDriverSlots: 20,
|
|
maxTeams: 16,
|
|
usedTeamSlots: 10,
|
|
structureSummary: 'Single championship',
|
|
timingSummary: 'Weekly races',
|
|
category: 'Professional',
|
|
scoring: {
|
|
primaryChampionshipType: 'trophy',
|
|
pointsSystem: 'standard',
|
|
},
|
|
};
|
|
|
|
const result = LeagueSummaryViewModelBuilder.build(league);
|
|
|
|
expect(result.scoring?.primaryChampionshipType).toBe('trophy');
|
|
});
|
|
});
|
|
});
|