import { describe, expect, it } from 'vitest'; import { AvailableLeaguesViewModel, AvailableLeagueViewModel } from './AvailableLeaguesViewModel'; import { AvailableLeaguesViewData, AvailableLeagueViewData } from '../view-data/AvailableLeaguesViewData'; describe('AvailableLeaguesViewModel', () => { const baseLeague: AvailableLeagueViewData = { id: 'league-1', name: 'Pro Series', game: 'iRacing', description: 'Competitive league for serious drivers', drivers: 24, avgViewsPerRace: 12_500, formattedAvgViews: '12.5k', mainSponsorSlot: { available: true, price: 5_000 }, secondarySlots: { available: 2, total: 3, price: 1_500 }, cpm: 400, formattedCpm: '$400', hasAvailableSlots: true, rating: 4.7, tier: 'premium' as const, tierConfig: { color: '#FFD700', bgColor: '#FFF8DC', border: '2px solid #FFD700', icon: '⭐', }, nextRace: 'Next Sunday', seasonStatus: 'active' as const, statusConfig: { color: '#10B981', bg: '#D1FAE5', label: 'Active Season', }, }; const baseViewData: AvailableLeaguesViewData = { leagues: [baseLeague], }; it('maps league array into view models', () => { const vm = new AvailableLeaguesViewModel(baseViewData); expect(vm.leagues).toHaveLength(1); expect(vm.leagues[0]).toBeInstanceOf(AvailableLeagueViewModel); expect(vm.leagues[0]?.id).toBe(baseLeague.id); expect(vm.leagues[0]?.name).toBe(baseLeague.name); expect(vm.leagues[0]?.avgViewsPerRace).toBe(baseLeague.avgViewsPerRace); }); it('exposes formatted average views and CPM for main sponsor slot', () => { const leagueVm = new AvailableLeagueViewModel(baseLeague); expect(leagueVm.formattedAvgViews).toBe('12.5k'); const expectedCpm = Math.round((baseLeague.mainSponsorSlot.price / baseLeague.avgViewsPerRace) * 1000); expect(leagueVm.cpm).toBe(expectedCpm); expect(leagueVm.formattedCpm).toBe('$400'); }); it('detects available sponsor slots from main or secondary slots', () => { const withBothAvailable = new AvailableLeagueViewModel(baseLeague); expect(withBothAvailable.hasAvailableSlots).toBe(true); const onlySecondary = new AvailableLeagueViewModel({ ...baseLeague, mainSponsorSlot: { available: false, price: 5_000 }, secondarySlots: { available: 1, total: 3, price: 1_500 }, }); expect(onlySecondary.hasAvailableSlots).toBe(true); const noneAvailable = new AvailableLeagueViewModel({ ...baseLeague, mainSponsorSlot: { available: false, price: 5_000 }, secondarySlots: { available: 0, total: 3, price: 1_500 }, }); expect(noneAvailable.hasAvailableSlots).toBe(false); }); it('returns tier configuration for badge styling', () => { const premium = new AvailableLeagueViewModel({ ...baseLeague, tier: 'premium' }); const standard = new AvailableLeagueViewModel({ ...baseLeague, tier: 'standard' }); const starter = new AvailableLeagueViewModel({ ...baseLeague, tier: 'starter' }); expect(premium.tierConfig.icon).toBe('⭐'); expect(standard.tierConfig.icon).toBe('🏆'); expect(starter.tierConfig.icon).toBe('🚀'); }); it('returns status configuration for season state', () => { const active = new AvailableLeagueViewModel({ ...baseLeague, seasonStatus: 'active' }); const upcoming = new AvailableLeagueViewModel({ ...baseLeague, seasonStatus: 'upcoming' }); const completed = new AvailableLeagueViewModel({ ...baseLeague, seasonStatus: 'completed' }); expect(active.statusConfig.label).toBe('Active Season'); expect(upcoming.statusConfig.label).toBe('Starting Soon'); expect(completed.statusConfig.label).toBe('Season Ended'); }); });