import { describe, it, expect } from 'vitest'; import { LeaguesViewDataBuilder } from '../../../apps/website/lib/builders/view-data/LeaguesViewDataBuilder'; import type { AllLeaguesWithCapacityAndScoringDTO } from '../../../apps/website/lib/types/generated/AllLeaguesWithCapacityAndScoringDTO'; import type { LeagueWithCapacityAndScoringDTO } from '../../../apps/website/lib/types/generated/LeagueWithCapacityAndScoringDTO'; describe('LeaguesViewDataBuilder', () => { const mockLeagues: LeagueWithCapacityAndScoringDTO[] = [ { id: 'league-1', name: 'Test League 1', description: 'A test league description', ownerId: 'owner-1', createdAt: '2024-01-01T00:00:00Z', settings: { maxDrivers: 32, qualifyingFormat: 'Solo', }, usedSlots: 15, category: 'Road', socialLinks: { discordUrl: 'https://discord.gg/test1', youtubeUrl: 'https://youtube.com/test1', websiteUrl: 'https://test1.com', }, scoring: { gameId: 'game-1', gameName: 'Test Game 1', primaryChampionshipType: 'Solo', scoringPresetId: 'preset-1', scoringPresetName: 'Standard', dropPolicySummary: 'Drop 2 worst races', scoringPatternSummary: 'Points based on finish position', }, timingSummary: 'Every Sunday at 8 PM', logoUrl: 'https://logo.com/test1.png', pendingJoinRequestsCount: 3, pendingProtestsCount: 1, walletBalance: 1000, }, { id: 'league-2', name: 'Test League 2', description: 'Another test league', ownerId: 'owner-2', createdAt: '2024-01-02T00:00:00Z', settings: { maxDrivers: 16, qualifyingFormat: 'Team', }, usedSlots: 8, category: 'Oval', socialLinks: { discordUrl: 'https://discord.gg/test2', }, scoring: { gameId: 'game-2', gameName: 'Test Game 2', primaryChampionshipType: 'Team', scoringPresetId: 'preset-2', scoringPresetName: 'Advanced', dropPolicySummary: 'Drop 1 worst race', scoringPatternSummary: 'Points based on finish position with bonuses', }, timingSummary: 'Every Saturday at 7 PM', logoUrl: 'https://logo.com/test2.png', }, { id: 'league-3', name: 'Test League 3', description: 'A third test league', ownerId: 'owner-3', createdAt: '2024-01-03T00:00:00Z', settings: { maxDrivers: 24, qualifyingFormat: 'Solo', }, usedSlots: 24, category: 'Road', scoring: { gameId: 'game-3', gameName: 'Test Game 3', primaryChampionshipType: 'Solo', scoringPresetId: 'preset-3', scoringPresetName: 'Custom', dropPolicySummary: 'No drops', scoringPatternSummary: 'Fixed points per position', }, timingSummary: 'Every Friday at 9 PM', }, ]; describe('build()', () => { it('should transform all leagues correctly', () => { const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: mockLeagues, totalCount: 3, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues).toHaveLength(3); // Check first league expect(result.leagues[0].id).toBe('league-1'); expect(result.leagues[0].name).toBe('Test League 1'); expect(result.leagues[0].description).toBe('A test league description'); expect(result.leagues[0].logoUrl).toBe('https://logo.com/test1.png'); expect(result.leagues[0].ownerId).toBe('owner-1'); expect(result.leagues[0].createdAt).toBe('2024-01-01T00:00:00Z'); expect(result.leagues[0].maxDrivers).toBe(32); expect(result.leagues[0].usedDriverSlots).toBe(15); expect(result.leagues[0].structureSummary).toBe('Solo'); expect(result.leagues[0].timingSummary).toBe('Every Sunday at 8 PM'); expect(result.leagues[0].category).toBe('Road'); // Check scoring expect(result.leagues[0].scoring).toBeDefined(); expect(result.leagues[0].scoring?.gameId).toBe('game-1'); expect(result.leagues[0].scoring?.gameName).toBe('Test Game 1'); expect(result.leagues[0].scoring?.primaryChampionshipType).toBe('Solo'); expect(result.leagues[0].scoring?.scoringPresetId).toBe('preset-1'); expect(result.leagues[0].scoring?.scoringPresetName).toBe('Standard'); expect(result.leagues[0].scoring?.dropPolicySummary).toBe('Drop 2 worst races'); expect(result.leagues[0].scoring?.scoringPatternSummary).toBe('Points based on finish position'); }); it('should handle leagues with missing description', () => { const leaguesWithoutDescription: LeagueWithCapacityAndScoringDTO[] = [ { id: 'league-1', name: 'Test League', description: '', ownerId: 'owner-1', createdAt: '2024-01-01T00:00:00Z', settings: { maxDrivers: 32, qualifyingFormat: 'Solo', }, usedSlots: 15, category: 'Road', scoring: { gameId: 'game-1', gameName: 'Test Game', primaryChampionshipType: 'Solo', scoringPresetId: 'preset-1', scoringPresetName: 'Standard', dropPolicySummary: 'Drop 2 worst races', scoringPatternSummary: 'Points based on finish position', }, timingSummary: 'Every Sunday at 8 PM', }, ]; const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: leaguesWithoutDescription, totalCount: 1, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].description).toBe(null); }); it('should handle leagues with missing logoUrl', () => { const leaguesWithoutLogo: LeagueWithCapacityAndScoringDTO[] = [ { id: 'league-1', name: 'Test League', description: 'A test league', ownerId: 'owner-1', createdAt: '2024-01-01T00:00:00Z', settings: { maxDrivers: 32, qualifyingFormat: 'Solo', }, usedSlots: 15, category: 'Road', scoring: { gameId: 'game-1', gameName: 'Test Game', primaryChampionshipType: 'Solo', scoringPresetId: 'preset-1', scoringPresetName: 'Standard', dropPolicySummary: 'Drop 2 worst races', scoringPatternSummary: 'Points based on finish position', }, timingSummary: 'Every Sunday at 8 PM', }, ]; const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: leaguesWithoutLogo, totalCount: 1, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].logoUrl).toBe(null); }); it('should handle leagues with missing category', () => { const leaguesWithoutCategory: LeagueWithCapacityAndScoringDTO[] = [ { id: 'league-1', name: 'Test League', description: 'A test league', ownerId: 'owner-1', createdAt: '2024-01-01T00:00:00Z', settings: { maxDrivers: 32, qualifyingFormat: 'Solo', }, usedSlots: 15, scoring: { gameId: 'game-1', gameName: 'Test Game', primaryChampionshipType: 'Solo', scoringPresetId: 'preset-1', scoringPresetName: 'Standard', dropPolicySummary: 'Drop 2 worst races', scoringPatternSummary: 'Points based on finish position', }, timingSummary: 'Every Sunday at 8 PM', }, ]; const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: leaguesWithoutCategory, totalCount: 1, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].category).toBe(null); }); it('should handle leagues with missing scoring', () => { const leaguesWithoutScoring: LeagueWithCapacityAndScoringDTO[] = [ { id: 'league-1', name: 'Test League', description: 'A test league', ownerId: 'owner-1', createdAt: '2024-01-01T00:00:00Z', settings: { maxDrivers: 32, qualifyingFormat: 'Solo', }, usedSlots: 15, category: 'Road', timingSummary: 'Every Sunday at 8 PM', }, ]; const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: leaguesWithoutScoring, totalCount: 1, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].scoring).toBeUndefined(); }); it('should handle leagues with missing social links', () => { const leaguesWithoutSocialLinks: LeagueWithCapacityAndScoringDTO[] = [ { id: 'league-1', name: 'Test League', description: 'A test league', ownerId: 'owner-1', createdAt: '2024-01-01T00:00:00Z', settings: { maxDrivers: 32, qualifyingFormat: 'Solo', }, usedSlots: 15, category: 'Road', scoring: { gameId: 'game-1', gameName: 'Test Game', primaryChampionshipType: 'Solo', scoringPresetId: 'preset-1', scoringPresetName: 'Standard', dropPolicySummary: 'Drop 2 worst races', scoringPatternSummary: 'Points based on finish position', }, timingSummary: 'Every Sunday at 8 PM', }, ]; const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: leaguesWithoutSocialLinks, totalCount: 1, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0]).toBeDefined(); }); it('should handle leagues with missing timingSummary', () => { const leaguesWithoutTimingSummary: LeagueWithCapacityAndScoringDTO[] = [ { id: 'league-1', name: 'Test League', description: 'A test league', ownerId: 'owner-1', createdAt: '2024-01-01T00:00:00Z', settings: { maxDrivers: 32, qualifyingFormat: 'Solo', }, usedSlots: 15, category: 'Road', scoring: { gameId: 'game-1', gameName: 'Test Game', primaryChampionshipType: 'Solo', scoringPresetId: 'preset-1', scoringPresetName: 'Standard', dropPolicySummary: 'Drop 2 worst races', scoringPatternSummary: 'Points based on finish position', }, }, ]; const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: leaguesWithoutTimingSummary, totalCount: 1, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].timingSummary).toBe(''); }); it('should handle empty leagues array', () => { const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: [], totalCount: 0, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues).toHaveLength(0); }); it('should handle leagues with different categories', () => { const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: mockLeagues, totalCount: 3, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].category).toBe('Road'); expect(result.leagues[1].category).toBe('Oval'); expect(result.leagues[2].category).toBe('Road'); }); it('should handle leagues with different structures', () => { const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: mockLeagues, totalCount: 3, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].structureSummary).toBe('Solo'); expect(result.leagues[1].structureSummary).toBe('Team'); expect(result.leagues[2].structureSummary).toBe('Solo'); }); it('should handle leagues with different scoring presets', () => { const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: mockLeagues, totalCount: 3, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].scoring?.scoringPresetName).toBe('Standard'); expect(result.leagues[1].scoring?.scoringPresetName).toBe('Advanced'); expect(result.leagues[2].scoring?.scoringPresetName).toBe('Custom'); }); it('should handle leagues with different drop policies', () => { const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: mockLeagues, totalCount: 3, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].scoring?.dropPolicySummary).toBe('Drop 2 worst races'); expect(result.leagues[1].scoring?.dropPolicySummary).toBe('Drop 1 worst race'); expect(result.leagues[2].scoring?.dropPolicySummary).toBe('No drops'); }); it('should handle leagues with different scoring patterns', () => { const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: mockLeagues, totalCount: 3, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].scoring?.scoringPatternSummary).toBe('Points based on finish position'); expect(result.leagues[1].scoring?.scoringPatternSummary).toBe('Points based on finish position with bonuses'); expect(result.leagues[2].scoring?.scoringPatternSummary).toBe('Fixed points per position'); }); it('should handle leagues with different primary championship types', () => { const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: mockLeagues, totalCount: 3, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].scoring?.primaryChampionshipType).toBe('Solo'); expect(result.leagues[1].scoring?.primaryChampionshipType).toBe('Team'); expect(result.leagues[2].scoring?.primaryChampionshipType).toBe('Solo'); }); it('should handle leagues with different game names', () => { const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: mockLeagues, totalCount: 3, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].scoring?.gameName).toBe('Test Game 1'); expect(result.leagues[1].scoring?.gameName).toBe('Test Game 2'); expect(result.leagues[2].scoring?.gameName).toBe('Test Game 3'); }); it('should handle leagues with different game IDs', () => { const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: mockLeagues, totalCount: 3, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].scoring?.gameId).toBe('game-1'); expect(result.leagues[1].scoring?.gameId).toBe('game-2'); expect(result.leagues[2].scoring?.gameId).toBe('game-3'); }); it('should handle leagues with different max drivers', () => { const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: mockLeagues, totalCount: 3, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].maxDrivers).toBe(32); expect(result.leagues[1].maxDrivers).toBe(16); expect(result.leagues[2].maxDrivers).toBe(24); }); it('should handle leagues with different used slots', () => { const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: mockLeagues, totalCount: 3, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].usedDriverSlots).toBe(15); expect(result.leagues[1].usedDriverSlots).toBe(8); expect(result.leagues[2].usedDriverSlots).toBe(24); }); it('should handle leagues with different owners', () => { const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: mockLeagues, totalCount: 3, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].ownerId).toBe('owner-1'); expect(result.leagues[1].ownerId).toBe('owner-2'); expect(result.leagues[2].ownerId).toBe('owner-3'); }); it('should handle leagues with different creation dates', () => { const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: mockLeagues, totalCount: 3, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].createdAt).toBe('2024-01-01T00:00:00Z'); expect(result.leagues[1].createdAt).toBe('2024-01-02T00:00:00Z'); expect(result.leagues[2].createdAt).toBe('2024-01-03T00:00:00Z'); }); it('should handle leagues with different timing summaries', () => { const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: mockLeagues, totalCount: 3, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].timingSummary).toBe('Every Sunday at 8 PM'); expect(result.leagues[1].timingSummary).toBe('Every Saturday at 7 PM'); expect(result.leagues[2].timingSummary).toBe('Every Friday at 9 PM'); }); it('should handle leagues with different names', () => { const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: mockLeagues, totalCount: 3, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].name).toBe('Test League 1'); expect(result.leagues[1].name).toBe('Test League 2'); expect(result.leagues[2].name).toBe('Test League 3'); }); it('should handle leagues with different descriptions', () => { const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: mockLeagues, totalCount: 3, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].description).toBe('A test league description'); expect(result.leagues[1].description).toBe('Another test league'); expect(result.leagues[2].description).toBe('A third test league'); }); it('should handle leagues with different logo URLs', () => { const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: mockLeagues, totalCount: 3, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].logoUrl).toBe('https://logo.com/test1.png'); expect(result.leagues[1].logoUrl).toBe('https://logo.com/test2.png'); expect(result.leagues[2].logoUrl).toBeNull(); }); it('should handle leagues with activeDriversCount', () => { const leaguesWithActiveDrivers: LeagueWithCapacityAndScoringDTO[] = [ { id: 'league-1', name: 'Test League', description: 'A test league', ownerId: 'owner-1', createdAt: '2024-01-01T00:00:00Z', settings: { maxDrivers: 32, qualifyingFormat: 'Solo', }, usedSlots: 15, category: 'Road', scoring: { gameId: 'game-1', gameName: 'Test Game', primaryChampionshipType: 'Solo', scoringPresetId: 'preset-1', scoringPresetName: 'Standard', dropPolicySummary: 'Drop 2 worst races', scoringPatternSummary: 'Points based on finish position', }, timingSummary: 'Every Sunday at 8 PM', }, ]; // Add activeDriversCount to the league (leaguesWithActiveDrivers[0] as any).activeDriversCount = 12; const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: leaguesWithActiveDrivers, totalCount: 1, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].activeDriversCount).toBe(12); }); it('should handle leagues with nextRaceAt', () => { const leaguesWithNextRace: LeagueWithCapacityAndScoringDTO[] = [ { id: 'league-1', name: 'Test League', description: 'A test league', ownerId: 'owner-1', createdAt: '2024-01-01T00:00:00Z', settings: { maxDrivers: 32, qualifyingFormat: 'Solo', }, usedSlots: 15, category: 'Road', scoring: { gameId: 'game-1', gameName: 'Test Game', primaryChampionshipType: 'Solo', scoringPresetId: 'preset-1', scoringPresetName: 'Standard', dropPolicySummary: 'Drop 2 worst races', scoringPatternSummary: 'Points based on finish position', }, timingSummary: 'Every Sunday at 8 PM', }, ]; // Add nextRaceAt to the league (leaguesWithNextRace[0] as any).nextRaceAt = '2024-02-01T18:00:00Z'; const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: leaguesWithNextRace, totalCount: 1, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].nextRaceAt).toBe('2024-02-01T18:00:00Z'); }); it('should handle leagues without activeDriversCount and nextRaceAt', () => { const leaguesWithoutMetadata: LeagueWithCapacityAndScoringDTO[] = [ { id: 'league-1', name: 'Test League', description: 'A test league', ownerId: 'owner-1', createdAt: '2024-01-01T00:00:00Z', settings: { maxDrivers: 32, qualifyingFormat: 'Solo', }, usedSlots: 15, category: 'Road', scoring: { gameId: 'game-1', gameName: 'Test Game', primaryChampionshipType: 'Solo', scoringPresetId: 'preset-1', scoringPresetName: 'Standard', dropPolicySummary: 'Drop 2 worst races', scoringPatternSummary: 'Points based on finish position', }, timingSummary: 'Every Sunday at 8 PM', }, ]; const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: leaguesWithoutMetadata, totalCount: 1, }; const result = LeaguesViewDataBuilder.build(apiDto); expect(result.leagues[0].activeDriversCount).toBeUndefined(); expect(result.leagues[0].nextRaceAt).toBeUndefined(); }); it('should handle leagues with different usedDriverSlots for featured leagues', () => { const leaguesWithDifferentSlots: LeagueWithCapacityAndScoringDTO[] = [ { id: 'league-1', name: 'Small League', description: 'A small league', ownerId: 'owner-1', createdAt: '2024-01-01T00:00:00Z', settings: { maxDrivers: 16, qualifyingFormat: 'Solo', }, usedSlots: 8, category: 'Road', scoring: { gameId: 'game-1', gameName: 'Test Game', primaryChampionshipType: 'Solo', scoringPresetId: 'preset-1', scoringPresetName: 'Standard', dropPolicySummary: 'Drop 2 worst races', scoringPatternSummary: 'Points based on finish position', }, timingSummary: 'Every Sunday at 8 PM', }, { id: 'league-2', name: 'Large League', description: 'A large league', ownerId: 'owner-2', createdAt: '2024-01-02T00:00:00Z', settings: { maxDrivers: 32, qualifyingFormat: 'Solo', }, usedSlots: 25, category: 'Road', scoring: { gameId: 'game-2', gameName: 'Test Game 2', primaryChampionshipType: 'Solo', scoringPresetId: 'preset-2', scoringPresetName: 'Advanced', dropPolicySummary: 'Drop 1 worst race', scoringPatternSummary: 'Points based on finish position with bonuses', }, timingSummary: 'Every Saturday at 7 PM', }, { id: 'league-3', name: 'Medium League', description: 'A medium league', ownerId: 'owner-3', createdAt: '2024-01-03T00:00:00Z', settings: { maxDrivers: 24, qualifyingFormat: 'Team', }, usedSlots: 20, category: 'Oval', scoring: { gameId: 'game-3', gameName: 'Test Game 3', primaryChampionshipType: 'Team', scoringPresetId: 'preset-3', scoringPresetName: 'Custom', dropPolicySummary: 'No drops', scoringPatternSummary: 'Fixed points per position', }, timingSummary: 'Every Friday at 9 PM', }, ]; const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: leaguesWithDifferentSlots, totalCount: 3, }; const result = LeaguesViewDataBuilder.build(apiDto); // Verify that usedDriverSlots is correctly mapped expect(result.leagues[0].usedDriverSlots).toBe(8); expect(result.leagues[1].usedDriverSlots).toBe(25); expect(result.leagues[2].usedDriverSlots).toBe(20); // Verify that leagues can be filtered for featured leagues (usedDriverSlots > 20) const featuredLeagues = result.leagues.filter(l => (l.usedDriverSlots ?? 0) > 20); expect(featuredLeagues).toHaveLength(1); expect(featuredLeagues[0].id).toBe('league-2'); }); it('should handle leagues with different categories for filtering', () => { const leaguesWithDifferentCategories: LeagueWithCapacityAndScoringDTO[] = [ { id: 'league-1', name: 'Road League 1', description: 'A road league', ownerId: 'owner-1', createdAt: '2024-01-01T00:00:00Z', settings: { maxDrivers: 32, qualifyingFormat: 'Solo', }, usedSlots: 15, category: 'Road', scoring: { gameId: 'game-1', gameName: 'Test Game', primaryChampionshipType: 'Solo', scoringPresetId: 'preset-1', scoringPresetName: 'Standard', dropPolicySummary: 'Drop 2 worst races', scoringPatternSummary: 'Points based on finish position', }, timingSummary: 'Every Sunday at 8 PM', }, { id: 'league-2', name: 'Oval League 1', description: 'An oval league', ownerId: 'owner-2', createdAt: '2024-01-02T00:00:00Z', settings: { maxDrivers: 16, qualifyingFormat: 'Solo', }, usedSlots: 8, category: 'Oval', scoring: { gameId: 'game-2', gameName: 'Test Game 2', primaryChampionshipType: 'Solo', scoringPresetId: 'preset-2', scoringPresetName: 'Advanced', dropPolicySummary: 'Drop 1 worst race', scoringPatternSummary: 'Points based on finish position with bonuses', }, timingSummary: 'Every Saturday at 7 PM', }, { id: 'league-3', name: 'Road League 2', description: 'Another road league', ownerId: 'owner-3', createdAt: '2024-01-03T00:00:00Z', settings: { maxDrivers: 24, qualifyingFormat: 'Team', }, usedSlots: 20, category: 'Road', scoring: { gameId: 'game-3', gameName: 'Test Game 3', primaryChampionshipType: 'Team', scoringPresetId: 'preset-3', scoringPresetName: 'Custom', dropPolicySummary: 'No drops', scoringPatternSummary: 'Fixed points per position', }, timingSummary: 'Every Friday at 9 PM', }, ]; const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: leaguesWithDifferentCategories, totalCount: 3, }; const result = LeaguesViewDataBuilder.build(apiDto); // Verify that category is correctly mapped expect(result.leagues[0].category).toBe('Road'); expect(result.leagues[1].category).toBe('Oval'); expect(result.leagues[2].category).toBe('Road'); // Verify that leagues can be filtered by category const roadLeagues = result.leagues.filter(l => l.category === 'Road'); expect(roadLeagues).toHaveLength(2); expect(roadLeagues[0].id).toBe('league-1'); expect(roadLeagues[1].id).toBe('league-3'); const ovalLeagues = result.leagues.filter(l => l.category === 'Oval'); expect(ovalLeagues).toHaveLength(1); expect(ovalLeagues[0].id).toBe('league-2'); }); it('should handle leagues with null category for filtering', () => { const leaguesWithNullCategory: LeagueWithCapacityAndScoringDTO[] = [ { id: 'league-1', name: 'League with Category', description: 'A league with category', ownerId: 'owner-1', createdAt: '2024-01-01T00:00:00Z', settings: { maxDrivers: 32, qualifyingFormat: 'Solo', }, usedSlots: 15, category: 'Road', scoring: { gameId: 'game-1', gameName: 'Test Game', primaryChampionshipType: 'Solo', scoringPresetId: 'preset-1', scoringPresetName: 'Standard', dropPolicySummary: 'Drop 2 worst races', scoringPatternSummary: 'Points based on finish position', }, timingSummary: 'Every Sunday at 8 PM', }, { id: 'league-2', name: 'League without Category', description: 'A league without category', ownerId: 'owner-2', createdAt: '2024-01-02T00:00:00Z', settings: { maxDrivers: 16, qualifyingFormat: 'Solo', }, usedSlots: 8, scoring: { gameId: 'game-2', gameName: 'Test Game 2', primaryChampionshipType: 'Solo', scoringPresetId: 'preset-2', scoringPresetName: 'Advanced', dropPolicySummary: 'Drop 1 worst race', scoringPatternSummary: 'Points based on finish position with bonuses', }, timingSummary: 'Every Saturday at 7 PM', }, ]; const apiDto: AllLeaguesWithCapacityAndScoringDTO = { leagues: leaguesWithNullCategory, totalCount: 2, }; const result = LeaguesViewDataBuilder.build(apiDto); // Verify that null category is handled correctly expect(result.leagues[0].category).toBe('Road'); expect(result.leagues[1].category).toBe(null); // Verify that leagues can be filtered by category (null category should be filterable) const roadLeagues = result.leagues.filter(l => l.category === 'Road'); expect(roadLeagues).toHaveLength(1); expect(roadLeagues[0].id).toBe('league-1'); const noCategoryLeagues = result.leagues.filter(l => l.category === null); expect(noCategoryLeagues).toHaveLength(1); expect(noCategoryLeagues[0].id).toBe('league-2'); }); }); });