279 lines
8.5 KiB
TypeScript
279 lines
8.5 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import type { RaceDetailLeagueDTO } from '../types/generated/RaceDetailLeagueDTO';
|
|
import type { RaceDetailRaceDTO } from '../types/generated/RaceDetailRaceDTO';
|
|
import type { RaceDetailRegistrationDTO } from '../types/generated/RaceDetailRegistrationDTO';
|
|
import type { RaceDetailUserResultDTO } from '../types/generated/RaceDetailUserResultDTO';
|
|
import type { RaceDetailEntryDTO } from '../types/RaceDetailEntryDTO';
|
|
import { RaceDetailViewModel } from './RaceDetailViewModel';
|
|
|
|
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');
|
|
});
|
|
}); |