view models
This commit is contained in:
279
apps/website/lib/view-models/RaceDetailViewModel.test.ts
Normal file
279
apps/website/lib/view-models/RaceDetailViewModel.test.ts
Normal file
@@ -0,0 +1,279 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { RaceDetailViewModel } from './RaceDetailViewModel';
|
||||
import type { RaceDetailRaceDTO } from '../types/generated/RaceDetailRaceDTO';
|
||||
import type { RaceDetailLeagueDTO } from '../types/generated/RaceDetailLeagueDTO';
|
||||
import type { RaceDetailEntryDTO } from '../types/generated/RaceDetailEntryDTO';
|
||||
import type { RaceDetailRegistrationDTO } from '../types/generated/RaceDetailRegistrationDTO';
|
||||
import type { RaceDetailUserResultDTO } from '../types/generated/RaceDetailUserResultDTO';
|
||||
|
||||
describe('RaceDetailViewModel', () => {
|
||||
const createMockRace = (overrides?: Partial<RaceDetailRaceDTO>): RaceDetailRaceDTO => ({
|
||||
id: 'race-123',
|
||||
title: 'Test Race',
|
||||
scheduledAt: '2023-12-31T20:00:00Z',
|
||||
status: 'upcoming',
|
||||
...overrides,
|
||||
});
|
||||
|
||||
const createMockLeague = (): RaceDetailLeagueDTO => ({
|
||||
id: 'league-123',
|
||||
name: 'Test League',
|
||||
});
|
||||
|
||||
const createMockRegistration = (
|
||||
overrides?: Partial<RaceDetailRegistrationDTO>
|
||||
): RaceDetailRegistrationDTO => ({
|
||||
isRegistered: false,
|
||||
canRegister: true,
|
||||
...overrides,
|
||||
});
|
||||
|
||||
it('should create instance with all properties', () => {
|
||||
const race = createMockRace();
|
||||
const league = createMockLeague();
|
||||
const entries: RaceDetailEntryDTO[] = [];
|
||||
const registration = createMockRegistration();
|
||||
const userResult: RaceDetailUserResultDTO | null = null;
|
||||
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race,
|
||||
league,
|
||||
entryList: entries,
|
||||
registration,
|
||||
userResult,
|
||||
});
|
||||
|
||||
expect(viewModel.race).toBe(race);
|
||||
expect(viewModel.league).toBe(league);
|
||||
expect(viewModel.entryList).toBe(entries);
|
||||
expect(viewModel.registration).toBe(registration);
|
||||
expect(viewModel.userResult).toBe(userResult);
|
||||
});
|
||||
|
||||
it('should handle null race and league', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: null,
|
||||
league: null,
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(viewModel.race).toBeNull();
|
||||
expect(viewModel.league).toBeNull();
|
||||
});
|
||||
|
||||
it('should return correct isRegistered value', () => {
|
||||
const registeredVm = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration({ isRegistered: true }),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
const notRegisteredVm = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration({ isRegistered: false }),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(registeredVm.isRegistered).toBe(true);
|
||||
expect(notRegisteredVm.isRegistered).toBe(false);
|
||||
});
|
||||
|
||||
it('should return correct canRegister value', () => {
|
||||
const canRegisterVm = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration({ canRegister: true }),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
const cannotRegisterVm = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration({ canRegister: false }),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(canRegisterVm.canRegister).toBe(true);
|
||||
expect(cannotRegisterVm.canRegister).toBe(false);
|
||||
});
|
||||
|
||||
it('should format race status correctly', () => {
|
||||
const upcomingVm = new RaceDetailViewModel({
|
||||
race: createMockRace({ status: 'upcoming' }),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
const liveVm = new RaceDetailViewModel({
|
||||
race: createMockRace({ status: 'live' }),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
const finishedVm = new RaceDetailViewModel({
|
||||
race: createMockRace({ status: 'finished' }),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(upcomingVm.raceStatusDisplay).toBe('Upcoming');
|
||||
expect(liveVm.raceStatusDisplay).toBe('Live');
|
||||
expect(finishedVm.raceStatusDisplay).toBe('Finished');
|
||||
});
|
||||
|
||||
it('should return Unknown for status when race is null', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: null,
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(viewModel.raceStatusDisplay).toBe('Unknown');
|
||||
});
|
||||
|
||||
it('should format scheduled time correctly', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: createMockRace({ scheduledAt: '2023-12-31T20:00:00Z' }),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
const formatted = viewModel.formattedScheduledTime;
|
||||
|
||||
expect(formatted).toContain('2023');
|
||||
expect(formatted).toContain('12/31');
|
||||
});
|
||||
|
||||
it('should return empty string for formatted time when race is null', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: null,
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(viewModel.formattedScheduledTime).toBe('');
|
||||
});
|
||||
|
||||
it('should return correct entry count', () => {
|
||||
const entries: RaceDetailEntryDTO[] = [
|
||||
{ driverId: 'driver-1', carId: 'car-1' },
|
||||
{ driverId: 'driver-2', carId: 'car-2' },
|
||||
{ driverId: 'driver-3', carId: 'car-3' },
|
||||
] as RaceDetailEntryDTO[];
|
||||
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: entries,
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(viewModel.entryCount).toBe(3);
|
||||
});
|
||||
|
||||
it('should return true for hasResults when userResult exists', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: { position: 1, lapTime: 90.5 } as RaceDetailUserResultDTO,
|
||||
});
|
||||
|
||||
expect(viewModel.hasResults).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false for hasResults when userResult is null', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(viewModel.hasResults).toBe(false);
|
||||
});
|
||||
|
||||
it('should return correct registration status message when registered', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration({ isRegistered: true }),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(viewModel.registrationStatusMessage).toBe('You are registered for this race');
|
||||
});
|
||||
|
||||
it('should return correct registration status message when can register', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration({ isRegistered: false, canRegister: true }),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(viewModel.registrationStatusMessage).toBe('You can register for this race');
|
||||
});
|
||||
|
||||
it('should return correct registration status message when cannot register', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration({ isRegistered: false, canRegister: false }),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(viewModel.registrationStatusMessage).toBe('Registration not available');
|
||||
});
|
||||
|
||||
it('should handle error property', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: createMockRace(),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
error: 'Failed to load race details',
|
||||
});
|
||||
|
||||
expect(viewModel.error).toBe('Failed to load race details');
|
||||
});
|
||||
|
||||
it('should handle custom race status', () => {
|
||||
const viewModel = new RaceDetailViewModel({
|
||||
race: createMockRace({ status: 'cancelled' }),
|
||||
league: createMockLeague(),
|
||||
entryList: [],
|
||||
registration: createMockRegistration(),
|
||||
userResult: null,
|
||||
});
|
||||
|
||||
expect(viewModel.raceStatusDisplay).toBe('cancelled');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user