import { describe, it, expect } from 'vitest'; import { DriversViewDataBuilder } from './DriversViewDataBuilder'; import type { DriversLeaderboardDTO } from '@/lib/types/generated/DriversLeaderboardDTO'; describe('DriversViewDataBuilder', () => { describe('happy paths', () => { it('should transform DriversLeaderboardDTO to DriversViewData correctly', () => { const driversDTO: DriversLeaderboardDTO = { drivers: [ { id: 'driver-1', name: 'John Doe', rating: 1234.56, skillLevel: 'Pro', category: 'Elite', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, avatarUrl: 'https://example.com/john.jpg', }, { id: 'driver-2', name: 'Jane Smith', rating: 1100.75, skillLevel: 'Advanced', category: 'Pro', nationality: 'Canada', racesCompleted: 120, wins: 15, podiums: 45, isActive: true, rank: 2, avatarUrl: 'https://example.com/jane.jpg', }, ], totalRaces: 270, totalWins: 40, activeCount: 2, }; const result = DriversViewDataBuilder.build(driversDTO); 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].ratingLabel).toBe('1,235'); expect(result.drivers[0].skillLevel).toBe('Pro'); expect(result.drivers[0].category).toBe('Elite'); 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].isActive).toBe(true); expect(result.drivers[0].rank).toBe(1); expect(result.drivers[0].avatarUrl).toBe('https://example.com/john.jpg'); expect(result.drivers[1].id).toBe('driver-2'); expect(result.drivers[1].name).toBe('Jane Smith'); expect(result.drivers[1].rating).toBe(1100.75); expect(result.drivers[1].ratingLabel).toBe('1,101'); expect(result.drivers[1].skillLevel).toBe('Advanced'); expect(result.drivers[1].category).toBe('Pro'); expect(result.drivers[1].nationality).toBe('Canada'); expect(result.drivers[1].racesCompleted).toBe(120); expect(result.drivers[1].wins).toBe(15); expect(result.drivers[1].podiums).toBe(45); expect(result.drivers[1].isActive).toBe(true); expect(result.drivers[1].rank).toBe(2); expect(result.drivers[1].avatarUrl).toBe('https://example.com/jane.jpg'); expect(result.totalRaces).toBe(270); expect(result.totalRacesLabel).toBe('270'); expect(result.totalWins).toBe(40); expect(result.totalWinsLabel).toBe('40'); expect(result.activeCount).toBe(2); expect(result.activeCountLabel).toBe('2'); expect(result.totalDriversLabel).toBe('2'); }); it('should handle drivers with missing optional fields', () => { const driversDTO: DriversLeaderboardDTO = { 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, }; const result = DriversViewDataBuilder.build(driversDTO); expect(result.drivers[0].category).toBeUndefined(); expect(result.drivers[0].avatarUrl).toBeUndefined(); }); it('should handle empty drivers array', () => { const driversDTO: DriversLeaderboardDTO = { drivers: [], totalRaces: 0, totalWins: 0, activeCount: 0, }; const result = DriversViewDataBuilder.build(driversDTO); expect(result.drivers).toEqual([]); expect(result.totalRaces).toBe(0); expect(result.totalRacesLabel).toBe('0'); expect(result.totalWins).toBe(0); expect(result.totalWinsLabel).toBe('0'); expect(result.activeCount).toBe(0); expect(result.activeCountLabel).toBe('0'); expect(result.totalDriversLabel).toBe('0'); }); }); describe('data transformation', () => { it('should preserve all DTO fields in the output', () => { const driversDTO: DriversLeaderboardDTO = { drivers: [ { id: 'driver-1', name: 'John Doe', rating: 1234.56, skillLevel: 'Pro', category: 'Elite', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, avatarUrl: 'https://example.com/john.jpg', }, ], totalRaces: 150, totalWins: 25, activeCount: 1, }; const result = DriversViewDataBuilder.build(driversDTO); expect(result.drivers[0].name).toBe(driversDTO.drivers[0].name); expect(result.drivers[0].nationality).toBe(driversDTO.drivers[0].nationality); expect(result.drivers[0].skillLevel).toBe(driversDTO.drivers[0].skillLevel); expect(result.totalRaces).toBe(driversDTO.totalRaces); expect(result.totalWins).toBe(driversDTO.totalWins); expect(result.activeCount).toBe(driversDTO.activeCount); }); it('should not modify the input DTO', () => { const driversDTO: DriversLeaderboardDTO = { drivers: [ { id: 'driver-1', name: 'John Doe', rating: 1234.56, skillLevel: 'Pro', category: 'Elite', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, avatarUrl: 'https://example.com/john.jpg', }, ], totalRaces: 150, totalWins: 25, activeCount: 1, }; const originalDTO = JSON.parse(JSON.stringify(driversDTO)); DriversViewDataBuilder.build(driversDTO); expect(driversDTO).toEqual(originalDTO); }); it('should transform all numeric fields to formatted strings where appropriate', () => { const driversDTO: DriversLeaderboardDTO = { 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, }; const result = DriversViewDataBuilder.build(driversDTO); // Rating label should be a formatted string expect(typeof result.drivers[0].ratingLabel).toBe('string'); expect(result.drivers[0].ratingLabel).toBe('1,235'); // Total counts should be formatted strings expect(typeof result.totalRacesLabel).toBe('string'); expect(result.totalRacesLabel).toBe('150'); expect(typeof result.totalWinsLabel).toBe('string'); expect(result.totalWinsLabel).toBe('25'); expect(typeof result.activeCountLabel).toBe('string'); expect(result.activeCountLabel).toBe('1'); expect(typeof result.totalDriversLabel).toBe('string'); expect(result.totalDriversLabel).toBe('1'); }); it('should handle large numbers correctly', () => { const driversDTO: DriversLeaderboardDTO = { drivers: [ { id: 'driver-1', name: 'John Doe', rating: 999999.99, skillLevel: 'Pro', nationality: 'USA', racesCompleted: 10000, wins: 2500, podiums: 5000, isActive: true, rank: 1, }, ], totalRaces: 10000, totalWins: 2500, activeCount: 1, }; const result = DriversViewDataBuilder.build(driversDTO); expect(result.drivers[0].ratingLabel).toBe('1,000,000'); expect(result.totalRacesLabel).toBe('10,000'); expect(result.totalWinsLabel).toBe('2,500'); expect(result.activeCountLabel).toBe('1'); expect(result.totalDriversLabel).toBe('1'); }); }); describe('edge cases', () => { it('should handle null/undefined rating', () => { const driversDTO: DriversLeaderboardDTO = { drivers: [ { id: 'driver-1', name: 'John Doe', rating: 0, skillLevel: 'Pro', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: true, rank: 1, }, ], totalRaces: 150, totalWins: 25, activeCount: 1, }; const result = DriversViewDataBuilder.build(driversDTO); expect(result.drivers[0].ratingLabel).toBe('0'); }); it('should handle drivers with no category', () => { const driversDTO: DriversLeaderboardDTO = { 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, }; const result = DriversViewDataBuilder.build(driversDTO); expect(result.drivers[0].category).toBeUndefined(); }); it('should handle inactive drivers', () => { const driversDTO: DriversLeaderboardDTO = { drivers: [ { id: 'driver-1', name: 'John Doe', rating: 1234.56, skillLevel: 'Pro', nationality: 'USA', racesCompleted: 150, wins: 25, podiums: 60, isActive: false, rank: 1, }, ], totalRaces: 150, totalWins: 25, activeCount: 0, }; const result = DriversViewDataBuilder.build(driversDTO); expect(result.drivers[0].isActive).toBe(false); expect(result.activeCount).toBe(0); expect(result.activeCountLabel).toBe('0'); }); }); describe('derived fields', () => { it('should correctly calculate total drivers label', () => { const driversDTO: DriversLeaderboardDTO = { drivers: [ { 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.75, skillLevel: 'Advanced', nationality: 'Canada', racesCompleted: 120, wins: 15, podiums: 45, isActive: true, rank: 2 }, { id: 'driver-3', name: 'Bob Wilson', rating: 950.25, skillLevel: 'Intermediate', nationality: 'UK', racesCompleted: 80, wins: 5, podiums: 20, isActive: false, rank: 3 }, ], totalRaces: 350, totalWins: 45, activeCount: 2, }; const result = DriversViewDataBuilder.build(driversDTO); expect(result.totalDriversLabel).toBe('3'); }); it('should correctly calculate active count', () => { const driversDTO: DriversLeaderboardDTO = { drivers: [ { 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.75, skillLevel: 'Advanced', nationality: 'Canada', racesCompleted: 120, wins: 15, podiums: 45, isActive: true, rank: 2 }, { id: 'driver-3', name: 'Bob Wilson', rating: 950.25, skillLevel: 'Intermediate', nationality: 'UK', racesCompleted: 80, wins: 5, podiums: 20, isActive: false, rank: 3 }, ], totalRaces: 350, totalWins: 45, activeCount: 2, }; const result = DriversViewDataBuilder.build(driversDTO); expect(result.activeCount).toBe(2); expect(result.activeCountLabel).toBe('2'); }); }); });