/** * Integration Test: Team Detail Use Case Orchestration * * Tests the orchestration logic of team detail-related Use Cases: * - GetTeamDetailsUseCase: Retrieves detailed team information including roster and management permissions * - 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 { GetTeamDetailsUseCase } from '../../../core/racing/application/use-cases/GetTeamDetailsUseCase'; import { Team } from '../../../core/racing/domain/entities/Team'; import { Logger } from '../../../core/shared/domain/Logger'; describe('Team Detail Use Case Orchestration', () => { let teamRepository: InMemoryTeamRepository; let membershipRepository: InMemoryTeamMembershipRepository; let getTeamDetailsUseCase: GetTeamDetailsUseCase; let mockLogger: Logger; beforeAll(() => { mockLogger = { info: () => {}, debug: () => {}, warn: () => {}, error: () => {}, } as unknown as Logger; teamRepository = new InMemoryTeamRepository(mockLogger); membershipRepository = new InMemoryTeamMembershipRepository(mockLogger); getTeamDetailsUseCase = new GetTeamDetailsUseCase(teamRepository, membershipRepository); }); beforeEach(() => { teamRepository.clear(); membershipRepository.clear(); }); describe('GetTeamDetailsUseCase - Success Path', () => { it('should retrieve team detail with membership and management permissions for owner', async () => { // Scenario: Team owner views team details // Given: A team exists const teamId = 't1'; const ownerId = 'd1'; const team = Team.create({ id: teamId, name: 'Team 1', tag: 'T1', description: 'Desc', ownerId, leagues: [] }); await teamRepository.create(team); // And: The driver is the owner await membershipRepository.saveMembership({ teamId, driverId: ownerId, role: 'owner', status: 'active', joinedAt: new Date() }); // When: GetTeamDetailsUseCase.execute() is called const result = await getTeamDetailsUseCase.execute({ teamId, driverId: ownerId }); // Then: The result should contain team information and management permissions expect(result.isOk()).toBe(true); const data = result.unwrap(); expect(data.team.id.toString()).toBe(teamId); expect(data.membership?.role).toBe('owner'); expect(data.canManage).toBe(true); }); it('should retrieve team detail for a non-member', async () => { // Scenario: Non-member views team details // Given: A team exists const teamId = 't2'; const team = Team.create({ id: teamId, name: 'Team 2', tag: 'T2', description: 'Desc', ownerId: 'owner', leagues: [] }); await teamRepository.create(team); // When: GetTeamDetailsUseCase.execute() is called with a driver who is not a member const result = await getTeamDetailsUseCase.execute({ teamId, driverId: 'non-member' }); // Then: The result should contain team information but no membership and no management permissions expect(result.isOk()).toBe(true); const data = result.unwrap(); expect(data.team.id.toString()).toBe(teamId); expect(data.membership).toBeNull(); expect(data.canManage).toBe(false); }); it('should retrieve team detail for a regular member', async () => { // Scenario: Regular member views team details // Given: A team exists const teamId = 't3'; const memberId = 'd3'; const team = Team.create({ id: teamId, name: 'Team 3', tag: 'T3', description: 'Desc', ownerId: 'owner', leagues: [] }); await teamRepository.create(team); // And: The driver is a regular member await membershipRepository.saveMembership({ teamId, driverId: memberId, role: 'driver', status: 'active', joinedAt: new Date() }); // When: GetTeamDetailsUseCase.execute() is called const result = await getTeamDetailsUseCase.execute({ teamId, driverId: memberId }); // Then: The result should contain team information and membership but no management permissions expect(result.isOk()).toBe(true); const data = result.unwrap(); expect(data.team.id.toString()).toBe(teamId); expect(data.membership?.role).toBe('driver'); expect(data.canManage).toBe(false); }); }); describe('GetTeamDetailsUseCase - Error Handling', () => { it('should throw error when team does not exist', async () => { // Scenario: Non-existent team // When: GetTeamDetailsUseCase.execute() is called with non-existent team ID const result = await getTeamDetailsUseCase.execute({ teamId: 'nonexistent', driverId: 'any' }); // Then: Should return error expect(result.isErr()).toBe(true); const error = result.unwrapErr(); expect(error.code).toBe('TEAM_NOT_FOUND'); }); }); });