102 lines
3.2 KiB
TypeScript
102 lines
3.2 KiB
TypeScript
import type { LeagueConfigFormModel } from '@/lib/types/LeagueConfigFormModel';
|
|
import type { LeagueScoringPresetDTO } from '@/lib/types/generated/LeagueScoringPresetDTO';
|
|
import { describe, expect, it } from 'vitest';
|
|
import { DriverSummaryViewModel } from './DriverSummaryViewModel';
|
|
import { LeagueSettingsViewModel } from './LeagueSettingsViewModel';
|
|
|
|
const createConfig = (overrides: Partial<LeagueConfigFormModel> = {}): LeagueConfigFormModel => ({
|
|
basics: {
|
|
name: 'Pro League',
|
|
description: 'Top tier competition',
|
|
visibility: 'public',
|
|
gameId: 'iracing',
|
|
},
|
|
structure: {
|
|
mode: 'solo',
|
|
maxDrivers: 40,
|
|
},
|
|
championships: {
|
|
enableDriverChampionship: true,
|
|
enableTeamChampionship: false,
|
|
enableNationsChampionship: false,
|
|
enableTrophyChampionship: false,
|
|
},
|
|
scoring: {
|
|
patternId: 'sprint-main-driver',
|
|
customScoringEnabled: false,
|
|
},
|
|
dropPolicy: {
|
|
strategy: 'bestNResults',
|
|
n: 6,
|
|
},
|
|
timings: {
|
|
qualifyingMinutes: 30,
|
|
mainRaceMinutes: 40,
|
|
roundsPlanned: 8,
|
|
},
|
|
stewarding: {
|
|
decisionMode: 'admin_vote',
|
|
requireDefense: false,
|
|
defenseTimeLimit: 24,
|
|
voteTimeLimit: 48,
|
|
protestDeadlineHours: 24,
|
|
stewardingClosesHours: 168,
|
|
notifyAccusedOnProtest: true,
|
|
notifyOnVoteRequired: true,
|
|
},
|
|
...overrides,
|
|
} as LeagueConfigFormModel);
|
|
|
|
const createPreset = (overrides: Partial<LeagueScoringPresetDTO> = {}): LeagueScoringPresetDTO => ({
|
|
id: 'preset-1',
|
|
name: 'Standard scoring',
|
|
description: 'Top 15 get points',
|
|
primaryChampionshipType: 'driver',
|
|
sessionSummary: 'Sprint + Main',
|
|
bonusSummary: 'None',
|
|
dropPolicySummary: 'Best 6',
|
|
...overrides,
|
|
} as LeagueScoringPresetDTO);
|
|
|
|
const createDriverSummary = (id: string, name: string): DriverSummaryViewModel =>
|
|
new DriverSummaryViewModel({
|
|
driver: {
|
|
id,
|
|
iracingId: `ir-${id}`,
|
|
name,
|
|
country: 'DE',
|
|
joinedAt: '2024-01-01T00:00:00Z',
|
|
},
|
|
});
|
|
|
|
describe('LeagueSettingsViewModel', () => {
|
|
it('maps league, config, presets, owner and members from DTO', () => {
|
|
const league = { id: 'league-1', name: 'Pro League', ownerId: 'owner-1' };
|
|
const config = createConfig();
|
|
const presets = [createPreset(), createPreset({ id: 'preset-2', name: 'Alt scoring' })];
|
|
const owner = createDriverSummary('driver-1', 'Owner Driver');
|
|
const members = [createDriverSummary('driver-2', 'Member One'), createDriverSummary('driver-3', 'Member Two')];
|
|
|
|
const vm = new LeagueSettingsViewModel({ league, config, presets, owner, members });
|
|
|
|
expect(vm.league).toBe(league);
|
|
expect(vm.config).toBe(config);
|
|
expect(vm.presets).toBe(presets);
|
|
expect(vm.owner).toBe(owner);
|
|
expect(vm.members).toBe(members);
|
|
});
|
|
|
|
it('allows null owner while keeping members and presets', () => {
|
|
const league = { id: 'league-1', name: 'Pro League', ownerId: 'owner-1' };
|
|
const config = createConfig();
|
|
const presets = [createPreset()];
|
|
const members = [createDriverSummary('driver-2', 'Member One')];
|
|
|
|
const vm = new LeagueSettingsViewModel({ league, config, presets, owner: null, members });
|
|
|
|
expect(vm.owner).toBeNull();
|
|
expect(vm.members).toHaveLength(1);
|
|
expect(vm.presets).toHaveLength(1);
|
|
});
|
|
});
|