/** * Integration Test: Team Leaderboard Use Case Orchestration * * Tests the orchestration logic of team leaderboard-related Use Cases: * - GetTeamsLeaderboardUseCase: Retrieves ranked list of teams with performance metrics * - Validates that Use Cases correctly interact with their Ports (Repositories) * - Uses In-Memory adapters for fast, deterministic testing * * Focus: Business logic orchestration, NOT UI rendering */ import { describe, it, expect, beforeAll, beforeEach } from 'vitest'; import { InMemoryTeamRepository } from '../../../adapters/racing/persistence/inmemory/InMemoryTeamRepository'; import { InMemoryTeamMembershipRepository } from '../../../adapters/racing/persistence/inmemory/InMemoryTeamMembershipRepository'; import { GetTeamsLeaderboardUseCase } from '../../../core/racing/application/use-cases/GetTeamsLeaderboardUseCase'; import { Team } from '../../../core/racing/domain/entities/Team'; import { Logger } from '../../../core/shared/domain/Logger'; describe('Team Leaderboard Use Case Orchestration', () => { let teamRepository: InMemoryTeamRepository; let membershipRepository: InMemoryTeamMembershipRepository; let getTeamsLeaderboardUseCase: GetTeamsLeaderboardUseCase; let mockLogger: Logger; beforeAll(() => { mockLogger = { info: () => {}, debug: () => {}, warn: () => {}, error: () => {}, } as unknown as Logger; teamRepository = new InMemoryTeamRepository(mockLogger); membershipRepository = new InMemoryTeamMembershipRepository(mockLogger); // Mock driver stats provider const getDriverStats = (driverId: string) => { const statsMap: Record = { 'd1': { rating: 2000, wins: 10, totalRaces: 50 }, 'd2': { rating: 1500, wins: 5, totalRaces: 30 }, 'd3': { rating: 1000, wins: 2, totalRaces: 20 }, }; return statsMap[driverId] || null; }; getTeamsLeaderboardUseCase = new GetTeamsLeaderboardUseCase( teamRepository, membershipRepository, getDriverStats, mockLogger ); }); beforeEach(() => { teamRepository.clear(); membershipRepository.clear(); }); describe('GetTeamsLeaderboardUseCase - Success Path', () => { it('should retrieve ranked team leaderboard with performance metrics', async () => { // Scenario: Leaderboard with multiple teams // Given: Multiple teams exist const team1 = Team.create({ id: 't1', name: 'Pro Team', tag: 'PRO', description: 'Desc', ownerId: 'o1', leagues: [] }); const team2 = Team.create({ id: 't2', name: 'Am Team', tag: 'AM', description: 'Desc', ownerId: 'o2', leagues: [] }); await teamRepository.create(team1); await teamRepository.create(team2); // And: Teams have members with different stats await membershipRepository.saveMembership({ teamId: 't1', driverId: 'd1', role: 'owner', status: 'active', joinedAt: new Date() }); await membershipRepository.saveMembership({ teamId: 't2', driverId: 'd3', role: 'owner', status: 'active', joinedAt: new Date() }); // When: GetTeamsLeaderboardUseCase.execute() is called const result = await getTeamsLeaderboardUseCase.execute({ leagueId: 'any' }); // Then: The result should contain ranked teams expect(result.isOk()).toBe(true); const { items, topItems } = result.unwrap(); expect(items).toHaveLength(2); // And: Teams should be ranked by rating (Pro Team has d1 with 2000, Am Team has d3 with 1000) expect(topItems[0]?.team.id.toString()).toBe('t1'); expect(topItems[0]?.rating).toBe(2000); expect(topItems[1]?.team.id.toString()).toBe('t2'); expect(topItems[1]?.rating).toBe(1000); }); it('should handle empty leaderboard', async () => { // Scenario: No teams exist // When: GetTeamsLeaderboardUseCase.execute() is called const result = await getTeamsLeaderboardUseCase.execute({ leagueId: 'any' }); // Then: The result should be empty expect(result.isOk()).toBe(true); const { items } = result.unwrap(); expect(items).toHaveLength(0); }); }); });