/** * View Data Layer Tests - Leaderboards Functionality * * This test file covers the view data layer for leaderboards functionality. * * The view data layer is responsible for: * - DTO → UI model mapping * - Formatting, sorting, and grouping * - Derived fields and defaults * - UI-specific semantics * * This layer isolates the UI from API churn by providing a stable interface * between the API layer and the presentation layer. * * Test coverage includes: * - Leaderboard data transformation and ranking calculations * - Driver leaderboard view models (overall, per-race, per-season) * - Team leaderboard view models (constructor standings, team performance) * - Leaderboard statistics and metrics formatting * - Derived leaderboard fields (points, positions, gaps, intervals, etc.) * - Default values and fallbacks for leaderboard views * - Leaderboard-specific formatting (lap times, gaps, points, positions, etc.) * - Data grouping and categorization for leaderboard components * - Leaderboard sorting and filtering view models * - Real-time leaderboard updates and state management * - Historical leaderboard data transformation * - Leaderboard comparison and trend analysis view models */ import { LeaderboardsViewDataBuilder } from '@/lib/builders/view-data/LeaderboardsViewDataBuilder'; import { DriverRankingsViewDataBuilder } from '@/lib/builders/view-data/DriverRankingsViewDataBuilder'; import { TeamRankingsViewDataBuilder } from '@/lib/builders/view-data/TeamRankingsViewDataBuilder'; import { WinRateDisplay } from '@/lib/display-objects/WinRateDisplay'; import { MedalDisplay } from '@/lib/display-objects/MedalDisplay'; import type { DriverLeaderboardItemDTO } from '@/lib/types/generated/DriverLeaderboardItemDTO'; import type { GetTeamsLeaderboardOutputDTO } from '@/lib/types/generated/GetTeamsLeaderboardOutputDTO'; import type { TeamLeaderboardItemDTO } from '@/lib/types/generated/TeamLeaderboardItemDTO'; import type { DriversLeaderboardDTO } from '@/lib/types/generated/DriversLeaderboardDTO'; describe('LeaderboardsViewDataBuilder', () => { describe('happy paths', () => { it('should transform Leaderboards DTO to LeaderboardsViewData correctly', () => { const leaderboardsDTO = { drivers: { drivers: [ { id: 'driver-1', name: 'John Doe', rating: 1234.56, skillLevel: 'pro', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, avatarUrl: 'https://example.com/avatar1.jpg', }, { id: 'driver-2', name: 'Jane Smith', rating: 1100.0, skillLevel: 'advanced', nationality: 'Canada', racesCompleted: 100, wins: 15, podiums: 40, isActive: true, rank: 2, avatarUrl: 'https://example.com/avatar2.jpg', }, ], totalRaces: 250, totalWins: 40, activeCount: 2, }, teams: { teams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo1.jpg', memberCount: 15, rating: 1500, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, { id: 'team-2', name: 'Speed Demons', tag: 'SD', logoUrl: 'https://example.com/logo2.jpg', memberCount: 8, rating: 1200, totalWins: 20, totalRaces: 150, performanceLevel: 'advanced', isRecruiting: true, createdAt: '2023-06-01', }, ], recruitingCount: 5, groupsBySkillLevel: 'pro,advanced,intermediate', topTeams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo1.jpg', memberCount: 15, rating: 1500, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, { id: 'team-2', name: 'Speed Demons', tag: 'SD', logoUrl: 'https://example.com/logo2.jpg', memberCount: 8, rating: 1200, totalWins: 20, totalRaces: 150, performanceLevel: 'advanced', isRecruiting: true, createdAt: '2023-06-01', }, ], }, }; const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO); // Verify drivers expect(result.drivers).toHaveLength(2); expect(result.drivers[0].id).toBe('driver-1'); expect(result.drivers[0].name).toBe('John Doe'); expect(result.drivers[0].rating).toBe(1234.56); expect(result.drivers[0].skillLevel).toBe('pro'); expect(result.drivers[0].nationality).toBe('USA'); expect(result.drivers[0].wins).toBe(25); expect(result.drivers[0].podiums).toBe(60); expect(result.drivers[0].racesCompleted).toBe(150); expect(result.drivers[0].rank).toBe(1); expect(result.drivers[0].avatarUrl).toBe('https://example.com/avatar1.jpg'); expect(result.drivers[0].position).toBe(1); // Verify teams expect(result.teams).toHaveLength(2); expect(result.teams[0].id).toBe('team-1'); expect(result.teams[0].name).toBe('Racing Team Alpha'); expect(result.teams[0].tag).toBe('RTA'); expect(result.teams[0].memberCount).toBe(15); expect(result.teams[0].totalWins).toBe(50); expect(result.teams[0].totalRaces).toBe(200); expect(result.teams[0].logoUrl).toBe('https://example.com/logo1.jpg'); expect(result.teams[0].position).toBe(1); expect(result.teams[0].isRecruiting).toBe(false); expect(result.teams[0].performanceLevel).toBe('elite'); expect(result.teams[0].rating).toBe(1500); expect(result.teams[0].category).toBeUndefined(); }); it('should handle empty driver and team arrays', () => { const leaderboardsDTO = { drivers: { drivers: [], totalRaces: 0, totalWins: 0, activeCount: 0, }, teams: { teams: [], recruitingCount: 0, groupsBySkillLevel: '', topTeams: [], }, }; const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO); expect(result.drivers).toEqual([]); expect(result.teams).toEqual([]); }); it('should handle missing avatar URLs with empty string fallback', () => { const leaderboardsDTO = { drivers: { drivers: [ { id: 'driver-1', name: 'John Doe', rating: 1234.56, skillLevel: 'pro', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, }, ], totalRaces: 150, totalWins: 25, activeCount: 1, }, teams: { teams: [], recruitingCount: 0, groupsBySkillLevel: '', topTeams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', memberCount: 15, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, ], }, }; const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO); expect(result.drivers[0].avatarUrl).toBe(''); expect(result.teams[0].logoUrl).toBe(''); }); it('should handle missing optional team fields with defaults', () => { const leaderboardsDTO = { drivers: { drivers: [], totalRaces: 0, totalWins: 0, activeCount: 0, }, teams: { teams: [], recruitingCount: 0, groupsBySkillLevel: '', topTeams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', memberCount: 15, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, ], }, }; const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO); expect(result.teams[0].rating).toBe(0); expect(result.teams[0].logoUrl).toBe(''); }); it('should calculate position based on index', () => { const leaderboardsDTO = { drivers: { drivers: [ { id: 'driver-1', name: 'Driver 1', rating: 1000, skillLevel: 'pro', nationality: 'USA', racesCompleted: 100, wins: 10, podiums: 30, isActive: true, rank: 1 }, { id: 'driver-2', name: 'Driver 2', rating: 900, skillLevel: 'advanced', nationality: 'Canada', racesCompleted: 80, wins: 8, podiums: 25, isActive: true, rank: 2 }, { id: 'driver-3', name: 'Driver 3', rating: 800, skillLevel: 'intermediate', nationality: 'UK', racesCompleted: 60, wins: 5, podiums: 15, isActive: true, rank: 3 }, ], totalRaces: 240, totalWins: 23, activeCount: 3, }, teams: { teams: [], recruitingCount: 1, groupsBySkillLevel: 'elite,advanced,intermediate', topTeams: [ { id: 'team-1', name: 'Team 1', tag: 'T1', memberCount: 10, totalWins: 30, totalRaces: 150, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01' }, { id: 'team-2', name: 'Team 2', tag: 'T2', memberCount: 8, totalWins: 20, totalRaces: 120, performanceLevel: 'advanced', isRecruiting: true, createdAt: '2023-02-01' }, { id: 'team-3', name: 'Team 3', tag: 'T3', memberCount: 6, totalWins: 10, totalRaces: 80, performanceLevel: 'intermediate', isRecruiting: false, createdAt: '2023-03-01' }, ], }, }; const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO); expect(result.drivers[0].position).toBe(1); expect(result.drivers[1].position).toBe(2); expect(result.drivers[2].position).toBe(3); expect(result.teams[0].position).toBe(1); expect(result.teams[1].position).toBe(2); expect(result.teams[2].position).toBe(3); }); }); describe('data transformation', () => { it('should preserve all DTO fields in the output', () => { const leaderboardsDTO = { drivers: { drivers: [ { id: 'driver-123', name: 'John Doe', rating: 1234.56, skillLevel: 'pro', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, avatarUrl: 'https://example.com/avatar.jpg', }, ], totalRaces: 150, totalWins: 25, activeCount: 1, }, teams: { teams: [], recruitingCount: 5, groupsBySkillLevel: 'pro,advanced', topTeams: [ { id: 'team-123', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo.jpg', memberCount: 15, rating: 1500, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, ], }, }; const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO); expect(result.drivers[0].name).toBe(leaderboardsDTO.drivers.drivers[0].name); expect(result.drivers[0].nationality).toBe(leaderboardsDTO.drivers.drivers[0].nationality); expect(result.drivers[0].avatarUrl).toBe(leaderboardsDTO.drivers.drivers[0].avatarUrl); expect(result.teams[0].name).toBe(leaderboardsDTO.teams.topTeams[0].name); expect(result.teams[0].tag).toBe(leaderboardsDTO.teams.topTeams[0].tag); expect(result.teams[0].logoUrl).toBe(leaderboardsDTO.teams.topTeams[0].logoUrl); }); it('should not modify the input DTO', () => { const leaderboardsDTO = { drivers: { drivers: [ { id: 'driver-123', name: 'John Doe', rating: 1234.56, skillLevel: 'pro', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, avatarUrl: 'https://example.com/avatar.jpg', }, ], totalRaces: 150, totalWins: 25, activeCount: 1, }, teams: { teams: [], recruitingCount: 5, groupsBySkillLevel: 'pro,advanced', topTeams: [ { id: 'team-123', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo.jpg', memberCount: 15, rating: 1500, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, ], }, }; const originalDTO = JSON.parse(JSON.stringify(leaderboardsDTO)); LeaderboardsViewDataBuilder.build(leaderboardsDTO); expect(leaderboardsDTO).toEqual(originalDTO); }); it('should handle large numbers correctly', () => { const leaderboardsDTO = { drivers: { drivers: [ { id: 'driver-1', name: 'John Doe', rating: 999999.99, skillLevel: 'pro', nationality: 'USA', racesCompleted: 10000, wins: 2500, podiums: 5000, isActive: true, rank: 1, avatarUrl: 'https://example.com/avatar.jpg', }, ], totalRaces: 10000, totalWins: 2500, activeCount: 1, }, teams: { teams: [], recruitingCount: 0, groupsBySkillLevel: '', topTeams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo.jpg', memberCount: 100, rating: 999999, totalWins: 5000, totalRaces: 10000, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, ], }, }; const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO); expect(result.drivers[0].rating).toBe(999999.99); expect(result.drivers[0].wins).toBe(2500); expect(result.drivers[0].podiums).toBe(5000); expect(result.drivers[0].racesCompleted).toBe(10000); expect(result.teams[0].rating).toBe(999999); expect(result.teams[0].totalWins).toBe(5000); expect(result.teams[0].totalRaces).toBe(10000); }); }); describe('edge cases', () => { it('should handle null/undefined avatar URLs', () => { const leaderboardsDTO = { drivers: { drivers: [ { id: 'driver-1', name: 'John Doe', rating: 1234.56, skillLevel: 'pro', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, avatarUrl: null as any, }, ], totalRaces: 150, totalWins: 25, activeCount: 1, }, teams: { teams: [], recruitingCount: 0, groupsBySkillLevel: '', topTeams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: undefined as any, memberCount: 15, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, ], }, }; const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO); expect(result.drivers[0].avatarUrl).toBe(''); expect(result.teams[0].logoUrl).toBe(''); }); it('should handle null/undefined rating', () => { const leaderboardsDTO = { drivers: { drivers: [ { id: 'driver-1', name: 'John Doe', rating: null as any, skillLevel: 'pro', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, }, ], totalRaces: 150, totalWins: 25, activeCount: 1, }, teams: { teams: [], recruitingCount: 0, groupsBySkillLevel: '', topTeams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', memberCount: 15, rating: null as any, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, ], }, }; const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO); expect(result.drivers[0].rating).toBeNull(); expect(result.teams[0].rating).toBe(0); }); it('should handle null/undefined totalWins and totalRaces', () => { const leaderboardsDTO = { drivers: { drivers: [], totalRaces: 0, totalWins: 0, activeCount: 0, }, teams: { teams: [], recruitingCount: 0, groupsBySkillLevel: '', topTeams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', memberCount: 15, totalWins: null as any, totalRaces: null as any, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, ], }, }; const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO); expect(result.teams[0].totalWins).toBe(0); expect(result.teams[0].totalRaces).toBe(0); }); it('should handle empty performance level', () => { const leaderboardsDTO = { drivers: { drivers: [], totalRaces: 0, totalWins: 0, activeCount: 0, }, teams: { teams: [], recruitingCount: 0, groupsBySkillLevel: '', topTeams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', memberCount: 15, totalWins: 50, totalRaces: 200, performanceLevel: '', isRecruiting: false, createdAt: '2023-01-01', }, ], }, }; const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO); expect(result.teams[0].performanceLevel).toBe('N/A'); }); }); }); describe('DriverRankingsViewDataBuilder', () => { describe('happy paths', () => { it('should transform DriverLeaderboardItemDTO array to DriverRankingsViewData correctly', () => { const driverDTOs: DriverLeaderboardItemDTO[] = [ { id: 'driver-1', name: 'John Doe', rating: 1234.56, skillLevel: 'pro', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, avatarUrl: 'https://example.com/avatar1.jpg', }, { id: 'driver-2', name: 'Jane Smith', rating: 1100.0, skillLevel: 'advanced', nationality: 'Canada', racesCompleted: 100, wins: 15, podiums: 40, isActive: true, rank: 2, avatarUrl: 'https://example.com/avatar2.jpg', }, { id: 'driver-3', name: 'Bob Johnson', rating: 950.0, skillLevel: 'intermediate', nationality: 'UK', racesCompleted: 80, wins: 10, podiums: 30, isActive: true, rank: 3, avatarUrl: 'https://example.com/avatar3.jpg', }, ]; const result = DriverRankingsViewDataBuilder.build(driverDTOs); // Verify drivers expect(result.drivers).toHaveLength(3); expect(result.drivers[0].id).toBe('driver-1'); expect(result.drivers[0].name).toBe('John Doe'); expect(result.drivers[0].rating).toBe(1234.56); expect(result.drivers[0].skillLevel).toBe('pro'); expect(result.drivers[0].nationality).toBe('USA'); expect(result.drivers[0].racesCompleted).toBe(150); expect(result.drivers[0].wins).toBe(25); expect(result.drivers[0].podiums).toBe(60); expect(result.drivers[0].rank).toBe(1); expect(result.drivers[0].avatarUrl).toBe('https://example.com/avatar1.jpg'); expect(result.drivers[0].winRate).toBe('16.7'); expect(result.drivers[0].medalBg).toBe('bg-warning-amber'); expect(result.drivers[0].medalColor).toBe('text-warning-amber'); // Verify podium (top 3 with special ordering: 2nd, 1st, 3rd) expect(result.podium).toHaveLength(3); expect(result.podium[0].id).toBe('driver-1'); expect(result.podium[0].name).toBe('John Doe'); expect(result.podium[0].rating).toBe(1234.56); expect(result.podium[0].wins).toBe(25); expect(result.podium[0].podiums).toBe(60); expect(result.podium[0].avatarUrl).toBe('https://example.com/avatar1.jpg'); expect(result.podium[0].position).toBe(2); // 2nd place expect(result.podium[1].id).toBe('driver-2'); expect(result.podium[1].position).toBe(1); // 1st place expect(result.podium[2].id).toBe('driver-3'); expect(result.podium[2].position).toBe(3); // 3rd place // Verify default values expect(result.searchQuery).toBe(''); expect(result.selectedSkill).toBe('all'); expect(result.sortBy).toBe('rank'); expect(result.showFilters).toBe(false); }); it('should handle empty driver array', () => { const driverDTOs: DriverLeaderboardItemDTO[] = []; const result = DriverRankingsViewDataBuilder.build(driverDTOs); expect(result.drivers).toEqual([]); expect(result.podium).toEqual([]); expect(result.searchQuery).toBe(''); expect(result.selectedSkill).toBe('all'); expect(result.sortBy).toBe('rank'); expect(result.showFilters).toBe(false); }); it('should handle less than 3 drivers for podium', () => { const driverDTOs: DriverLeaderboardItemDTO[] = [ { id: 'driver-1', name: 'John Doe', rating: 1234.56, skillLevel: 'pro', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, avatarUrl: 'https://example.com/avatar1.jpg', }, { id: 'driver-2', name: 'Jane Smith', rating: 1100.0, skillLevel: 'advanced', nationality: 'Canada', racesCompleted: 100, wins: 15, podiums: 40, isActive: true, rank: 2, avatarUrl: 'https://example.com/avatar2.jpg', }, ]; const result = DriverRankingsViewDataBuilder.build(driverDTOs); expect(result.drivers).toHaveLength(2); expect(result.podium).toHaveLength(2); expect(result.podium[0].position).toBe(2); // 2nd place expect(result.podium[1].position).toBe(1); // 1st place }); it('should handle missing avatar URLs with empty string fallback', () => { const driverDTOs: DriverLeaderboardItemDTO[] = [ { id: 'driver-1', name: 'John Doe', rating: 1234.56, skillLevel: 'pro', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, }, ]; const result = DriverRankingsViewDataBuilder.build(driverDTOs); expect(result.drivers[0].avatarUrl).toBe(''); expect(result.podium[0].avatarUrl).toBe(''); }); it('should calculate win rate correctly', () => { const driverDTOs: DriverLeaderboardItemDTO[] = [ { id: 'driver-1', name: 'John Doe', rating: 1234.56, skillLevel: 'pro', nationality: 'USA', racesCompleted: 100, wins: 25, podiums: 60, isActive: true, rank: 1, }, { id: 'driver-2', name: 'Jane Smith', rating: 1100.0, skillLevel: 'advanced', nationality: 'Canada', racesCompleted: 50, wins: 10, podiums: 25, isActive: true, rank: 2, }, { id: 'driver-3', name: 'Bob Johnson', rating: 950.0, skillLevel: 'intermediate', nationality: 'UK', racesCompleted: 0, wins: 0, podiums: 0, isActive: true, rank: 3, }, ]; const result = DriverRankingsViewDataBuilder.build(driverDTOs); expect(result.drivers[0].winRate).toBe('25.0'); expect(result.drivers[1].winRate).toBe('20.0'); expect(result.drivers[2].winRate).toBe('0.0'); }); it('should assign correct medal colors based on position', () => { const driverDTOs: DriverLeaderboardItemDTO[] = [ { id: 'driver-1', name: 'John Doe', rating: 1234.56, skillLevel: 'pro', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, }, { id: 'driver-2', name: 'Jane Smith', rating: 1100.0, skillLevel: 'advanced', nationality: 'Canada', racesCompleted: 100, wins: 15, podiums: 40, isActive: true, rank: 2, }, { id: 'driver-3', name: 'Bob Johnson', rating: 950.0, skillLevel: 'intermediate', nationality: 'UK', racesCompleted: 80, wins: 10, podiums: 30, isActive: true, rank: 3, }, { id: 'driver-4', name: 'Alice Brown', rating: 800.0, skillLevel: 'beginner', nationality: 'Germany', racesCompleted: 60, wins: 5, podiums: 15, isActive: true, rank: 4, }, ]; const result = DriverRankingsViewDataBuilder.build(driverDTOs); expect(result.drivers[0].medalBg).toBe('bg-warning-amber'); expect(result.drivers[0].medalColor).toBe('text-warning-amber'); expect(result.drivers[1].medalBg).toBe('bg-gray-300'); expect(result.drivers[1].medalColor).toBe('text-gray-300'); expect(result.drivers[2].medalBg).toBe('bg-orange-700'); expect(result.drivers[2].medalColor).toBe('text-orange-700'); expect(result.drivers[3].medalBg).toBe('bg-gray-800'); expect(result.drivers[3].medalColor).toBe('text-gray-400'); }); }); describe('data transformation', () => { it('should preserve all DTO fields in the output', () => { const driverDTOs: DriverLeaderboardItemDTO[] = [ { id: 'driver-123', name: 'John Doe', rating: 1234.56, skillLevel: 'pro', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, avatarUrl: 'https://example.com/avatar.jpg', }, ]; const result = DriverRankingsViewDataBuilder.build(driverDTOs); expect(result.drivers[0].name).toBe(driverDTOs[0].name); expect(result.drivers[0].nationality).toBe(driverDTOs[0].nationality); expect(result.drivers[0].avatarUrl).toBe(driverDTOs[0].avatarUrl); expect(result.drivers[0].skillLevel).toBe(driverDTOs[0].skillLevel); }); it('should not modify the input DTO', () => { const driverDTOs: DriverLeaderboardItemDTO[] = [ { id: 'driver-123', name: 'John Doe', rating: 1234.56, skillLevel: 'pro', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, avatarUrl: 'https://example.com/avatar.jpg', }, ]; const originalDTO = JSON.parse(JSON.stringify(driverDTOs)); DriverRankingsViewDataBuilder.build(driverDTOs); expect(driverDTOs).toEqual(originalDTO); }); it('should handle large numbers correctly', () => { const driverDTOs: DriverLeaderboardItemDTO[] = [ { id: 'driver-1', name: 'John Doe', rating: 999999.99, skillLevel: 'pro', nationality: 'USA', racesCompleted: 10000, wins: 2500, podiums: 5000, isActive: true, rank: 1, }, ]; const result = DriverRankingsViewDataBuilder.build(driverDTOs); expect(result.drivers[0].rating).toBe(999999.99); expect(result.drivers[0].wins).toBe(2500); expect(result.drivers[0].podiums).toBe(5000); expect(result.drivers[0].racesCompleted).toBe(10000); expect(result.drivers[0].winRate).toBe('25.0'); }); }); describe('edge cases', () => { it('should handle null/undefined avatar URLs', () => { const driverDTOs: DriverLeaderboardItemDTO[] = [ { id: 'driver-1', name: 'John Doe', rating: 1234.56, skillLevel: 'pro', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, avatarUrl: null as any, }, ]; const result = DriverRankingsViewDataBuilder.build(driverDTOs); expect(result.drivers[0].avatarUrl).toBe(''); expect(result.podium[0].avatarUrl).toBe(''); }); it('should handle null/undefined rating', () => { const driverDTOs: DriverLeaderboardItemDTO[] = [ { id: 'driver-1', name: 'John Doe', rating: null as any, skillLevel: 'pro', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, }, ]; const result = DriverRankingsViewDataBuilder.build(driverDTOs); expect(result.drivers[0].rating).toBeNull(); expect(result.podium[0].rating).toBeNull(); }); it('should handle zero races completed for win rate calculation', () => { const driverDTOs: DriverLeaderboardItemDTO[] = [ { id: 'driver-1', name: 'John Doe', rating: 1234.56, skillLevel: 'pro', nationality: 'USA', racesCompleted: 0, wins: 0, podiums: 0, isActive: true, rank: 1, }, ]; const result = DriverRankingsViewDataBuilder.build(driverDTOs); expect(result.drivers[0].winRate).toBe('0.0'); }); it('should handle rank 0', () => { const driverDTOs: DriverLeaderboardItemDTO[] = [ { id: 'driver-1', name: 'John Doe', rating: 1234.56, skillLevel: 'pro', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 0, }, ]; const result = DriverRankingsViewDataBuilder.build(driverDTOs); expect(result.drivers[0].rank).toBe(0); expect(result.drivers[0].medalBg).toBe('bg-gray-800'); expect(result.drivers[0].medalColor).toBe('text-gray-400'); }); }); }); describe('TeamRankingsViewDataBuilder', () => { describe('happy paths', () => { it('should transform GetTeamsLeaderboardOutputDTO to TeamRankingsViewData correctly', () => { const teamDTO: GetTeamsLeaderboardOutputDTO = { teams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo1.jpg', memberCount: 15, rating: 1500, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, { id: 'team-2', name: 'Speed Demons', tag: 'SD', logoUrl: 'https://example.com/logo2.jpg', memberCount: 8, rating: 1200, totalWins: 20, totalRaces: 150, performanceLevel: 'advanced', isRecruiting: true, createdAt: '2023-06-01', }, { id: 'team-3', name: 'Rookie Racers', tag: 'RR', logoUrl: 'https://example.com/logo3.jpg', memberCount: 5, rating: 800, totalWins: 5, totalRaces: 50, performanceLevel: 'intermediate', isRecruiting: false, createdAt: '2023-09-01', }, ], recruitingCount: 5, groupsBySkillLevel: 'elite,advanced,intermediate', topTeams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo1.jpg', memberCount: 15, rating: 1500, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, { id: 'team-2', name: 'Speed Demons', tag: 'SD', logoUrl: 'https://example.com/logo2.jpg', memberCount: 8, rating: 1200, totalWins: 20, totalRaces: 150, performanceLevel: 'advanced', isRecruiting: true, createdAt: '2023-06-01', }, ], }; const result = TeamRankingsViewDataBuilder.build(teamDTO); // Verify teams expect(result.teams).toHaveLength(3); expect(result.teams[0].id).toBe('team-1'); expect(result.teams[0].name).toBe('Racing Team Alpha'); expect(result.teams[0].tag).toBe('RTA'); expect(result.teams[0].memberCount).toBe(15); expect(result.teams[0].totalWins).toBe(50); expect(result.teams[0].totalRaces).toBe(200); expect(result.teams[0].logoUrl).toBe('https://example.com/logo1.jpg'); expect(result.teams[0].position).toBe(1); expect(result.teams[0].isRecruiting).toBe(false); expect(result.teams[0].performanceLevel).toBe('elite'); expect(result.teams[0].rating).toBe(1500); expect(result.teams[0].category).toBeUndefined(); // Verify podium (top 3) expect(result.podium).toHaveLength(3); expect(result.podium[0].id).toBe('team-1'); expect(result.podium[0].position).toBe(1); expect(result.podium[1].id).toBe('team-2'); expect(result.podium[1].position).toBe(2); expect(result.podium[2].id).toBe('team-3'); expect(result.podium[2].position).toBe(3); // Verify recruiting count expect(result.recruitingCount).toBe(5); }); it('should handle empty team array', () => { const teamDTO: GetTeamsLeaderboardOutputDTO = { teams: [], recruitingCount: 0, groupsBySkillLevel: '', topTeams: [], }; const result = TeamRankingsViewDataBuilder.build(teamDTO); expect(result.teams).toEqual([]); expect(result.podium).toEqual([]); expect(result.recruitingCount).toBe(0); }); it('should handle less than 3 teams for podium', () => { const teamDTO: GetTeamsLeaderboardOutputDTO = { teams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo1.jpg', memberCount: 15, rating: 1500, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, { id: 'team-2', name: 'Speed Demons', tag: 'SD', logoUrl: 'https://example.com/logo2.jpg', memberCount: 8, rating: 1200, totalWins: 20, totalRaces: 150, performanceLevel: 'advanced', isRecruiting: true, createdAt: '2023-06-01', }, ], recruitingCount: 2, groupsBySkillLevel: 'elite,advanced', topTeams: [], }; const result = TeamRankingsViewDataBuilder.build(teamDTO); expect(result.teams).toHaveLength(2); expect(result.podium).toHaveLength(2); expect(result.podium[0].position).toBe(1); expect(result.podium[1].position).toBe(2); }); it('should handle missing avatar URLs with empty string fallback', () => { const teamDTO: GetTeamsLeaderboardOutputDTO = { teams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', memberCount: 15, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, ], recruitingCount: 0, groupsBySkillLevel: '', topTeams: [], }; const result = TeamRankingsViewDataBuilder.build(teamDTO); expect(result.teams[0].logoUrl).toBe(''); }); it('should calculate position based on index', () => { const teamDTO: GetTeamsLeaderboardOutputDTO = { teams: [ { id: 'team-1', name: 'Team 1', tag: 'T1', memberCount: 10, totalWins: 30, totalRaces: 150, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01' }, { id: 'team-2', name: 'Team 2', tag: 'T2', memberCount: 8, totalWins: 20, totalRaces: 120, performanceLevel: 'advanced', isRecruiting: true, createdAt: '2023-02-01' }, { id: 'team-3', name: 'Team 3', tag: 'T3', memberCount: 6, totalWins: 10, totalRaces: 80, performanceLevel: 'intermediate', isRecruiting: false, createdAt: '2023-03-01' }, { id: 'team-4', name: 'Team 4', tag: 'T4', memberCount: 4, totalWins: 5, totalRaces: 40, performanceLevel: 'beginner', isRecruiting: true, createdAt: '2023-04-01' }, ], recruitingCount: 2, groupsBySkillLevel: 'elite,advanced,intermediate,beginner', topTeams: [], }; const result = TeamRankingsViewDataBuilder.build(teamDTO); expect(result.teams[0].position).toBe(1); expect(result.teams[1].position).toBe(2); expect(result.teams[2].position).toBe(3); expect(result.teams[3].position).toBe(4); }); }); describe('data transformation', () => { it('should preserve all DTO fields in the output', () => { const teamDTO: GetTeamsLeaderboardOutputDTO = { teams: [ { id: 'team-123', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo.jpg', memberCount: 15, rating: 1500, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, ], recruitingCount: 5, groupsBySkillLevel: 'elite,advanced', topTeams: [], }; const result = TeamRankingsViewDataBuilder.build(teamDTO); expect(result.teams[0].name).toBe(teamDTO.teams[0].name); expect(result.teams[0].tag).toBe(teamDTO.teams[0].tag); expect(result.teams[0].logoUrl).toBe(teamDTO.teams[0].logoUrl); expect(result.teams[0].memberCount).toBe(teamDTO.teams[0].memberCount); expect(result.teams[0].rating).toBe(teamDTO.teams[0].rating); expect(result.teams[0].totalWins).toBe(teamDTO.teams[0].totalWins); expect(result.teams[0].totalRaces).toBe(teamDTO.teams[0].totalRaces); expect(result.teams[0].performanceLevel).toBe(teamDTO.teams[0].performanceLevel); expect(result.teams[0].isRecruiting).toBe(teamDTO.teams[0].isRecruiting); }); it('should not modify the input DTO', () => { const teamDTO: GetTeamsLeaderboardOutputDTO = { teams: [ { id: 'team-123', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo.jpg', memberCount: 15, rating: 1500, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, ], recruitingCount: 5, groupsBySkillLevel: 'elite,advanced', topTeams: [], }; const originalDTO = JSON.parse(JSON.stringify(teamDTO)); TeamRankingsViewDataBuilder.build(teamDTO); expect(teamDTO).toEqual(originalDTO); }); it('should handle large numbers correctly', () => { const teamDTO: GetTeamsLeaderboardOutputDTO = { teams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo.jpg', memberCount: 100, rating: 999999, totalWins: 5000, totalRaces: 10000, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, ], recruitingCount: 0, groupsBySkillLevel: '', topTeams: [], }; const result = TeamRankingsViewDataBuilder.build(teamDTO); expect(result.teams[0].rating).toBe(999999); expect(result.teams[0].totalWins).toBe(5000); expect(result.teams[0].totalRaces).toBe(10000); }); }); describe('edge cases', () => { it('should handle null/undefined logo URLs', () => { const teamDTO: GetTeamsLeaderboardOutputDTO = { teams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: null as any, memberCount: 15, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, ], recruitingCount: 0, groupsBySkillLevel: '', topTeams: [], }; const result = TeamRankingsViewDataBuilder.build(teamDTO); expect(result.teams[0].logoUrl).toBe(''); }); it('should handle null/undefined rating', () => { const teamDTO: GetTeamsLeaderboardOutputDTO = { teams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', memberCount: 15, rating: null as any, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, ], recruitingCount: 0, groupsBySkillLevel: '', topTeams: [], }; const result = TeamRankingsViewDataBuilder.build(teamDTO); expect(result.teams[0].rating).toBe(0); }); it('should handle null/undefined totalWins and totalRaces', () => { const teamDTO: GetTeamsLeaderboardOutputDTO = { teams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', memberCount: 15, totalWins: null as any, totalRaces: null as any, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, ], recruitingCount: 0, groupsBySkillLevel: '', topTeams: [], }; const result = TeamRankingsViewDataBuilder.build(teamDTO); expect(result.teams[0].totalWins).toBe(0); expect(result.teams[0].totalRaces).toBe(0); }); it('should handle empty performance level', () => { const teamDTO: GetTeamsLeaderboardOutputDTO = { teams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', memberCount: 15, totalWins: 50, totalRaces: 200, performanceLevel: '', isRecruiting: false, createdAt: '2023-01-01', }, ], recruitingCount: 0, groupsBySkillLevel: '', topTeams: [], }; const result = TeamRankingsViewDataBuilder.build(teamDTO); expect(result.teams[0].performanceLevel).toBe('N/A'); }); it('should handle position 0', () => { const teamDTO: GetTeamsLeaderboardOutputDTO = { teams: [ { id: 'team-1', name: 'Team 1', tag: 'T1', memberCount: 10, totalWins: 30, totalRaces: 150, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01' }, ], recruitingCount: 0, groupsBySkillLevel: '', topTeams: [], }; const result = TeamRankingsViewDataBuilder.build(teamDTO); expect(result.teams[0].position).toBe(1); }); }); }); describe('WinRateDisplay', () => { describe('happy paths', () => { it('should calculate win rate correctly', () => { expect(WinRateDisplay.calculate(100, 25)).toBe('25.0'); expect(WinRateDisplay.calculate(50, 10)).toBe('20.0'); expect(WinRateDisplay.calculate(200, 50)).toBe('25.0'); }); it('should handle zero races completed', () => { expect(WinRateDisplay.calculate(0, 0)).toBe('0.0'); expect(WinRateDisplay.calculate(0, 10)).toBe('0.0'); }); it('should handle zero wins', () => { expect(WinRateDisplay.calculate(100, 0)).toBe('0.0'); }); it('should format rate correctly', () => { expect(WinRateDisplay.format(25.0)).toBe('25.0%'); expect(WinRateDisplay.format(0)).toBe('0.0%'); expect(WinRateDisplay.format(100)).toBe('100.0%'); }); }); describe('edge cases', () => { it('should handle null rate in format', () => { expect(WinRateDisplay.format(null)).toBe('0.0%'); }); it('should handle undefined rate in format', () => { expect(WinRateDisplay.format(undefined)).toBe('0.0%'); }); it('should handle decimal win rates', () => { expect(WinRateDisplay.calculate(100, 25)).toBe('25.0'); expect(WinRateDisplay.calculate(100, 33)).toBe('33.0'); expect(WinRateDisplay.calculate(100, 66)).toBe('66.0'); }); it('should handle large numbers', () => { expect(WinRateDisplay.calculate(10000, 2500)).toBe('25.0'); expect(WinRateDisplay.calculate(10000, 5000)).toBe('50.0'); }); }); }); describe('MedalDisplay', () => { describe('happy paths', () => { it('should return correct variant for positions', () => { expect(MedalDisplay.getVariant(1)).toBe('warning'); expect(MedalDisplay.getVariant(2)).toBe('high'); expect(MedalDisplay.getVariant(3)).toBe('warning'); expect(MedalDisplay.getVariant(4)).toBe('low'); expect(MedalDisplay.getVariant(10)).toBe('low'); }); it('should return correct medal icon for top 3 positions', () => { expect(MedalDisplay.getMedalIcon(1)).toBe('🏆'); expect(MedalDisplay.getMedalIcon(2)).toBe('🏆'); expect(MedalDisplay.getMedalIcon(3)).toBe('🏆'); }); it('should return null for positions outside top 3', () => { expect(MedalDisplay.getMedalIcon(4)).toBeNull(); expect(MedalDisplay.getMedalIcon(10)).toBeNull(); expect(MedalDisplay.getMedalIcon(100)).toBeNull(); }); it('should return correct background color for positions', () => { expect(MedalDisplay.getBg(1)).toBe('bg-warning-amber'); expect(MedalDisplay.getBg(2)).toBe('bg-gray-300'); expect(MedalDisplay.getBg(3)).toBe('bg-orange-700'); expect(MedalDisplay.getBg(4)).toBe('bg-gray-800'); expect(MedalDisplay.getBg(10)).toBe('bg-gray-800'); }); it('should return correct text color for positions', () => { expect(MedalDisplay.getColor(1)).toBe('text-warning-amber'); expect(MedalDisplay.getColor(2)).toBe('text-gray-300'); expect(MedalDisplay.getColor(3)).toBe('text-orange-700'); expect(MedalDisplay.getColor(4)).toBe('text-gray-400'); expect(MedalDisplay.getColor(10)).toBe('text-gray-400'); }); }); describe('edge cases', () => { it('should handle position 0', () => { expect(MedalDisplay.getVariant(0)).toBe('low'); expect(MedalDisplay.getMedalIcon(0)).toBe('🏆'); expect(MedalDisplay.getBg(0)).toBe('bg-gray-800'); expect(MedalDisplay.getColor(0)).toBe('text-gray-400'); }); it('should handle large positions', () => { expect(MedalDisplay.getVariant(999)).toBe('low'); expect(MedalDisplay.getMedalIcon(999)).toBeNull(); expect(MedalDisplay.getBg(999)).toBe('bg-gray-800'); expect(MedalDisplay.getColor(999)).toBe('text-gray-400'); }); it('should handle negative positions', () => { expect(MedalDisplay.getVariant(-1)).toBe('low'); expect(MedalDisplay.getMedalIcon(-1)).toBe('🏆'); expect(MedalDisplay.getBg(-1)).toBe('bg-gray-800'); expect(MedalDisplay.getColor(-1)).toBe('text-gray-400'); }); }); }); describe('Leaderboards View Data - Cross-Component Consistency', () => { describe('common patterns', () => { it('should all use consistent formatting for numeric values', () => { const leaderboardsDTO = { drivers: { drivers: [ { id: 'driver-1', name: 'John Doe', rating: 1234.56, skillLevel: 'pro', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, avatarUrl: 'https://example.com/avatar.jpg', }, ], totalRaces: 150, totalWins: 25, activeCount: 1, }, teams: { teams: [], recruitingCount: 5, groupsBySkillLevel: 'elite,advanced', topTeams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo.jpg', memberCount: 15, rating: 1500, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, ], }, }; const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO); // All numeric values should be preserved as numbers (not formatted as strings) expect(typeof result.drivers[0].rating).toBe('number'); expect(typeof result.drivers[0].wins).toBe('number'); expect(typeof result.drivers[0].podiums).toBe('number'); expect(typeof result.drivers[0].racesCompleted).toBe('number'); expect(typeof result.drivers[0].rank).toBe('number'); expect(typeof result.teams[0].rating).toBe('number'); expect(typeof result.teams[0].totalWins).toBe('number'); expect(typeof result.teams[0].totalRaces).toBe('number'); }); it('should all handle missing data gracefully', () => { const leaderboardsDTO = { drivers: { drivers: [], totalRaces: 0, totalWins: 0, activeCount: 0, }, teams: { teams: [], recruitingCount: 0, groupsBySkillLevel: '', topTeams: [], }, }; const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO); // All fields should have safe defaults expect(result.drivers).toEqual([]); expect(result.teams).toEqual([]); }); it('should all preserve ISO timestamps for serialization', () => { const leaderboardsDTO = { drivers: { drivers: [], totalRaces: 0, totalWins: 0, activeCount: 0, }, teams: { teams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo.jpg', memberCount: 15, rating: 1500, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01T00:00:00Z', }, ], recruitingCount: 0, groupsBySkillLevel: '', topTeams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo.jpg', memberCount: 15, rating: 1500, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01T00:00:00Z', }, ], }, }; const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO); // Verify that the view data model is correctly built expect(result.teams).toHaveLength(1); expect(result.teams[0].id).toBe('team-1'); expect(result.teams[0].name).toBe('Racing Team Alpha'); expect(result.teams[0].tag).toBe('RTA'); expect(result.teams[0].logoUrl).toBe('https://example.com/logo.jpg'); expect(result.teams[0].memberCount).toBe(15); expect(result.teams[0].rating).toBe(1500); expect(result.teams[0].totalWins).toBe(50); expect(result.teams[0].totalRaces).toBe(200); expect(result.teams[0].performanceLevel).toBe('elite'); expect(result.teams[0].isRecruiting).toBe(false); expect(result.teams[0].position).toBe(1); }); it('should all handle boolean flags correctly', () => { const leaderboardsDTO = { drivers: { drivers: [], totalRaces: 0, totalWins: 0, activeCount: 0, }, teams: { teams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo.jpg', memberCount: 15, rating: 1500, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: true, createdAt: '2023-01-01', }, { id: 'team-2', name: 'Speed Demons', tag: 'SD', logoUrl: 'https://example.com/logo2.jpg', memberCount: 8, rating: 1200, totalWins: 20, totalRaces: 150, performanceLevel: 'advanced', isRecruiting: false, createdAt: '2023-06-01', }, ], recruitingCount: 1, groupsBySkillLevel: 'elite,advanced', topTeams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo.jpg', memberCount: 15, rating: 1500, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: true, createdAt: '2023-01-01', }, { id: 'team-2', name: 'Speed Demons', tag: 'SD', logoUrl: 'https://example.com/logo2.jpg', memberCount: 8, rating: 1200, totalWins: 20, totalRaces: 150, performanceLevel: 'advanced', isRecruiting: false, createdAt: '2023-06-01', }, ], }, }; const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO); expect(result.teams[0].isRecruiting).toBe(true); expect(result.teams[1].isRecruiting).toBe(false); }); }); describe('data integrity', () => { it('should maintain data consistency across transformations', () => { const leaderboardsDTO = { drivers: { drivers: [ { id: 'driver-1', name: 'John Doe', rating: 1234.56, skillLevel: 'pro', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, avatarUrl: 'https://example.com/avatar.jpg', }, ], totalRaces: 150, totalWins: 25, activeCount: 1, }, teams: { teams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo.jpg', memberCount: 15, rating: 1500, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, ], recruitingCount: 5, groupsBySkillLevel: 'elite,advanced', topTeams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo.jpg', memberCount: 15, rating: 1500, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, ], }, }; const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO); // Verify derived fields match their source data expect(result.drivers[0].position).toBe(result.drivers[0].rank); expect(result.teams[0].position).toBe(1); }); it('should handle complex real-world scenarios', () => { const leaderboardsDTO = { drivers: { drivers: [ { id: 'driver-1', name: 'John Doe', rating: 2456.78, skillLevel: 'pro', nationality: 'USA', racesCompleted: 250, wins: 45, podiums: 120, isActive: true, rank: 1, avatarUrl: 'https://example.com/avatar1.jpg', }, { id: 'driver-2', name: 'Jane Smith', rating: 2100.0, skillLevel: 'pro', nationality: 'Canada', racesCompleted: 200, wins: 35, podiums: 100, isActive: true, rank: 2, avatarUrl: 'https://example.com/avatar2.jpg', }, { id: 'driver-3', name: 'Bob Johnson', rating: 1800.0, skillLevel: 'advanced', nationality: 'UK', racesCompleted: 180, wins: 25, podiums: 80, isActive: true, rank: 3, avatarUrl: 'https://example.com/avatar3.jpg', }, ], totalRaces: 630, totalWins: 105, activeCount: 3, }, teams: { teams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo1.jpg', memberCount: 15, rating: 1500, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, { id: 'team-2', name: 'Speed Demons', tag: 'SD', logoUrl: 'https://example.com/logo2.jpg', memberCount: 8, rating: 1200, totalWins: 20, totalRaces: 150, performanceLevel: 'advanced', isRecruiting: true, createdAt: '2023-06-01', }, { id: 'team-3', name: 'Rookie Racers', tag: 'RR', logoUrl: 'https://example.com/logo3.jpg', memberCount: 5, rating: 800, totalWins: 5, totalRaces: 50, performanceLevel: 'intermediate', isRecruiting: false, createdAt: '2023-09-01', }, ], recruitingCount: 1, groupsBySkillLevel: 'elite,advanced,intermediate', topTeams: [ { id: 'team-1', name: 'Racing Team Alpha', tag: 'RTA', logoUrl: 'https://example.com/logo1.jpg', memberCount: 15, rating: 1500, totalWins: 50, totalRaces: 200, performanceLevel: 'elite', isRecruiting: false, createdAt: '2023-01-01', }, { id: 'team-2', name: 'Speed Demons', tag: 'SD', logoUrl: 'https://example.com/logo2.jpg', memberCount: 8, rating: 1200, totalWins: 20, totalRaces: 150, performanceLevel: 'advanced', isRecruiting: true, createdAt: '2023-06-01', }, { id: 'team-3', name: 'Rookie Racers', tag: 'RR', logoUrl: 'https://example.com/logo3.jpg', memberCount: 5, rating: 800, totalWins: 5, totalRaces: 50, performanceLevel: 'intermediate', isRecruiting: false, createdAt: '2023-09-01', }, ], }, }; const result = LeaderboardsViewDataBuilder.build(leaderboardsDTO); // Verify all transformations expect(result.drivers).toHaveLength(3); expect(result.drivers[0].name).toBe('John Doe'); expect(result.drivers[0].rating).toBe(2456.78); expect(result.drivers[0].rank).toBe(1); expect(result.drivers[0].position).toBe(1); expect(result.teams).toHaveLength(3); expect(result.teams[0].name).toBe('Racing Team Alpha'); expect(result.teams[0].rating).toBe(1500); expect(result.teams[0].position).toBe(1); expect(result.teams[0].isRecruiting).toBe(false); expect(result.teams[1].isRecruiting).toBe(true); expect(result.teams[2].isRecruiting).toBe(false); }); }); });