import { describe, it, expect } from 'vitest'; import { DriverProfileDriverSummaryViewModel } from './DriverProfileDriverSummaryViewModel'; import { ProfileViewData } from '../view-data/ProfileViewData'; describe('DriverProfileDriverSummaryViewModel', () => { describe('happy paths', () => { it('should transform ViewData with all fields correctly', () => { const viewData: ProfileViewData = { driver: { id: 'driver-123', name: 'John Doe', countryCode: 'US', countryFlag: 'πŸ‡ΊπŸ‡Έ', avatarUrl: 'https://example.com/avatar.jpg', bio: 'Professional racing driver', iracingId: '12345', joinedAtLabel: '2023-01-15', }, stats: { ratingLabel: '1234.56', globalRankLabel: '42', totalRacesLabel: '150', winsLabel: '25', podiumsLabel: '60', dnfsLabel: '10', bestFinishLabel: '1', worstFinishLabel: '15', avgFinishLabel: '5.2', consistencyLabel: '85', percentileLabel: '95', }, teamMemberships: [], extendedProfile: null, }; const viewModel = new DriverProfileDriverSummaryViewModel(viewData); expect(viewModel.id).toBe('driver-123'); expect(viewModel.name).toBe('John Doe'); expect(viewModel.country).toBe('US'); expect(viewModel.avatarUrl).toBe('https://example.com/avatar.jpg'); expect(viewModel.iracingId).toBe('12345'); expect(viewModel.joinedAt).toBe('2023-01-15'); expect(viewModel.rating).toBe(1234.56); expect(viewModel.ratingLabel).toBe('1,235'); expect(viewModel.globalRank).toBe(42); expect(viewModel.globalRankLabel).toBe('42'); expect(viewModel.consistency).toBe(85); expect(viewModel.consistencyLabel).toBe('85%'); expect(viewModel.bio).toBe('Professional racing driver'); expect(viewModel.totalDrivers).toBe(150); expect(viewModel.totalDriversLabel).toBe('150'); }); it('should handle null stats gracefully', () => { const viewData: ProfileViewData = { driver: { id: 'driver-123', name: 'John Doe', countryCode: 'US', countryFlag: 'πŸ‡ΊπŸ‡Έ', avatarUrl: 'https://example.com/avatar.jpg', bio: null, iracingId: null, joinedAtLabel: '2023-01-15', }, stats: null, teamMemberships: [], extendedProfile: null, }; const viewModel = new DriverProfileDriverSummaryViewModel(viewData); expect(viewModel.rating).toBe(null); expect(viewModel.ratingLabel).toBe('β€”'); expect(viewModel.globalRank).toBe(null); expect(viewModel.globalRankLabel).toBe('β€”'); expect(viewModel.consistency).toBe(null); expect(viewModel.consistencyLabel).toBe('β€”'); expect(viewModel.totalDrivers).toBe(null); expect(viewModel.totalDriversLabel).toBe('β€”'); }); it('should handle null bio', () => { const viewData: ProfileViewData = { driver: { id: 'driver-123', name: 'John Doe', countryCode: 'US', countryFlag: 'πŸ‡ΊπŸ‡Έ', avatarUrl: 'https://example.com/avatar.jpg', bio: null, iracingId: '12345', joinedAtLabel: '2023-01-15', }, stats: { ratingLabel: '1234.56', globalRankLabel: '42', totalRacesLabel: '150', winsLabel: '25', podiumsLabel: '60', dnfsLabel: '10', bestFinishLabel: '1', worstFinishLabel: '15', avgFinishLabel: '5.2', consistencyLabel: '85', percentileLabel: '95', }, teamMemberships: [], extendedProfile: null, }; const viewModel = new DriverProfileDriverSummaryViewModel(viewData); expect(viewModel.bio).toBe(null); }); it('should handle null iracingId', () => { const viewData: ProfileViewData = { driver: { id: 'driver-123', name: 'John Doe', countryCode: 'US', countryFlag: 'πŸ‡ΊπŸ‡Έ', avatarUrl: 'https://example.com/avatar.jpg', bio: 'Professional racing driver', iracingId: null, joinedAtLabel: '2023-01-15', }, stats: { ratingLabel: '1234.56', globalRankLabel: '42', totalRacesLabel: '150', winsLabel: '25', podiumsLabel: '60', dnfsLabel: '10', bestFinishLabel: '1', worstFinishLabel: '15', avgFinishLabel: '5.2', consistencyLabel: '85', percentileLabel: '95', }, teamMemberships: [], extendedProfile: null, }; const viewModel = new DriverProfileDriverSummaryViewModel(viewData); expect(viewModel.iracingId).toBe(null); }); }); describe('edge cases', () => { it('should handle zero rating', () => { const viewData: ProfileViewData = { driver: { id: 'driver-123', name: 'John Doe', countryCode: 'US', countryFlag: 'πŸ‡ΊπŸ‡Έ', avatarUrl: 'https://example.com/avatar.jpg', bio: null, iracingId: null, joinedAtLabel: '2023-01-15', }, stats: { ratingLabel: '0', globalRankLabel: '1000', totalRacesLabel: '10', winsLabel: '0', podiumsLabel: '0', dnfsLabel: '10', bestFinishLabel: '20', worstFinishLabel: '20', avgFinishLabel: '20', consistencyLabel: '0', percentileLabel: '0', }, teamMemberships: [], extendedProfile: null, }; const viewModel = new DriverProfileDriverSummaryViewModel(viewData); expect(viewModel.rating).toBe(0); expect(viewModel.ratingLabel).toBe('0'); }); it('should handle large numbers', () => { const viewData: ProfileViewData = { driver: { id: 'driver-123', name: 'John Doe', countryCode: 'US', countryFlag: 'πŸ‡ΊπŸ‡Έ', avatarUrl: 'https://example.com/avatar.jpg', bio: null, iracingId: null, joinedAtLabel: '2023-01-15', }, stats: { ratingLabel: '999999.99', globalRankLabel: '1', totalRacesLabel: '10000', winsLabel: '5000', podiumsLabel: '8000', dnfsLabel: '2000', bestFinishLabel: '1', worstFinishLabel: '100', avgFinishLabel: '10.5', consistencyLabel: '99.9', percentileLabel: '99.99', }, teamMemberships: [], extendedProfile: null, }; const viewModel = new DriverProfileDriverSummaryViewModel(viewData); expect(viewModel.rating).toBe(999999.99); expect(viewModel.ratingLabel).toBe('1,000,000'); expect(viewModel.totalDrivers).toBe(10000); expect(viewModel.totalDriversLabel).toBe('10,000'); }); it('should handle decimal consistency', () => { const viewData: ProfileViewData = { driver: { id: 'driver-123', name: 'John Doe', countryCode: 'US', countryFlag: 'πŸ‡ΊπŸ‡Έ', avatarUrl: 'https://example.com/avatar.jpg', bio: null, iracingId: null, joinedAtLabel: '2023-01-15', }, stats: { ratingLabel: '1000', globalRankLabel: '50', totalRacesLabel: '100', winsLabel: '20', podiumsLabel: '50', dnfsLabel: '10', bestFinishLabel: '1', worstFinishLabel: '10', avgFinishLabel: '5.5', consistencyLabel: '85.5', percentileLabel: '90', }, teamMemberships: [], extendedProfile: null, }; const viewModel = new DriverProfileDriverSummaryViewModel(viewData); expect(viewModel.consistency).toBe(85.5); expect(viewModel.consistencyLabel).toBe('85.5%'); }); }); });