262 lines
7.9 KiB
TypeScript
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%');
|
|
});
|
|
});
|
|
});
|