Files
gridpilot.gg/apps/website/lib/view-models/DriverProfileDriverSummaryViewModel.test.ts
2026-01-24 01:25:46 +01:00

262 lines
7.9 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { ProfileViewData } from '../view-data/ProfileViewData';
import { DriverProfileDriverSummaryViewModel } from './DriverProfileDriverSummaryViewModel';
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%');
});
});
});