import { describe, it, expect } from 'vitest'; import { RaceCardViewModel, RacesPageViewModel } from './RacesPageViewModel'; describe('RaceCardViewModel', () => { it('should create instance with all properties', () => { const dto = { id: 'race-123', title: 'Season Finale', scheduledTime: '2023-12-31T20:00:00Z', status: 'upcoming', }; const viewModel = new RaceCardViewModel(dto); expect(viewModel.id).toBe('race-123'); expect(viewModel.title).toBe('Season Finale'); expect(viewModel.scheduledTime).toBe('2023-12-31T20:00:00Z'); expect(viewModel.status).toBe('upcoming'); }); it('should format scheduled time as locale string', () => { const dto = { id: 'race-123', title: 'Test Race', scheduledTime: '2023-12-31T20:00:00Z', status: 'upcoming', }; const viewModel = new RaceCardViewModel(dto); const formatted = viewModel.formattedScheduledTime; expect(formatted).toContain('2023'); expect(formatted).toContain('12/31'); }); it('should handle different race statuses', () => { const statuses = ['upcoming', 'live', 'finished', 'cancelled']; statuses.forEach(status => { const dto = { id: 'race-123', title: 'Test Race', scheduledTime: '2023-12-31T20:00:00Z', status, }; const viewModel = new RaceCardViewModel(dto); expect(viewModel.status).toBe(status); }); }); }); describe('RacesPageViewModel', () => { it('should create instance with upcoming and completed races', () => { const dto = { upcomingRaces: [ { id: 'race-1', title: 'Race 1', scheduledTime: '2023-12-31T20:00:00Z', status: 'upcoming', }, { id: 'race-2', title: 'Race 2', scheduledTime: '2024-01-01T20:00:00Z', status: 'upcoming', }, ], completedRaces: [ { id: 'race-3', title: 'Race 3', scheduledTime: '2023-12-20T20:00:00Z', status: 'finished', }, ], totalCount: 3, }; const viewModel = new RacesPageViewModel(dto); expect(viewModel.upcomingRaces).toHaveLength(2); expect(viewModel.completedRaces).toHaveLength(1); expect(viewModel.totalCount).toBe(3); }); it('should convert DTOs to view models', () => { const dto = { upcomingRaces: [ { id: 'race-1', title: 'Race 1', scheduledTime: '2023-12-31T20:00:00Z', status: 'upcoming', }, ], completedRaces: [], totalCount: 1, }; const viewModel = new RacesPageViewModel(dto); expect(viewModel.upcomingRaces[0]).toBeInstanceOf(RaceCardViewModel); expect(viewModel.upcomingRaces[0].id).toBe('race-1'); }); it('should return correct upcoming count', () => { const dto = { upcomingRaces: [ { id: 'race-1', title: 'Race 1', scheduledTime: '2023-12-31T20:00:00Z', status: 'upcoming', }, { id: 'race-2', title: 'Race 2', scheduledTime: '2024-01-01T20:00:00Z', status: 'upcoming', }, { id: 'race-3', title: 'Race 3', scheduledTime: '2024-01-02T20:00:00Z', status: 'upcoming', }, ], completedRaces: [], totalCount: 3, }; const viewModel = new RacesPageViewModel(dto); expect(viewModel.upcomingCount).toBe(3); }); it('should return correct completed count', () => { const dto = { upcomingRaces: [], completedRaces: [ { id: 'race-1', title: 'Race 1', scheduledTime: '2023-12-20T20:00:00Z', status: 'finished', }, { id: 'race-2', title: 'Race 2', scheduledTime: '2023-12-21T20:00:00Z', status: 'finished', }, ], totalCount: 2, }; const viewModel = new RacesPageViewModel(dto); expect(viewModel.completedCount).toBe(2); }); it('should handle empty race lists', () => { const dto = { upcomingRaces: [], completedRaces: [], totalCount: 0, }; const viewModel = new RacesPageViewModel(dto); expect(viewModel.upcomingCount).toBe(0); expect(viewModel.completedCount).toBe(0); expect(viewModel.totalCount).toBe(0); }); it('should handle mixed race lists', () => { const dto = { upcomingRaces: [ { id: 'race-1', title: 'Upcoming', scheduledTime: '2024-01-01T20:00:00Z', status: 'upcoming', }, ], completedRaces: [ { id: 'race-2', title: 'Completed 1', scheduledTime: '2023-12-20T20:00:00Z', status: 'finished', }, { id: 'race-3', title: 'Completed 2', scheduledTime: '2023-12-21T20:00:00Z', status: 'finished', }, ], totalCount: 3, }; const viewModel = new RacesPageViewModel(dto); expect(viewModel.upcomingCount).toBe(1); expect(viewModel.completedCount).toBe(2); expect(viewModel.totalCount).toBe(3); }); });