import { describe, it, expect, beforeEach } from 'vitest'; import { TeamsTestContext } from '../TeamsTestContext'; import { Driver } from '../../../../core/racing/domain/entities/Driver'; import { Team } from '../../../../core/racing/domain/entities/Team'; describe('Team Membership Use Cases', () => { const context = new TeamsTestContext(); const joinTeamUseCase = context.createJoinTeamUseCase(); const leaveTeamUseCase = context.createLeaveTeamUseCase(); const getTeamMembershipUseCase = context.createGetTeamMembershipUseCase(); const getTeamMembersUseCase = context.createGetTeamMembersUseCase(); const getTeamJoinRequestsUseCase = context.createGetTeamJoinRequestsUseCase(); const approveTeamJoinRequestUseCase = context.createApproveTeamJoinRequestUseCase(); beforeEach(() => { context.clear(); }); describe('JoinTeamUseCase', () => { it('should create a join request for a team', async () => { const driverId = 'd1'; const driver = Driver.create({ id: driverId, iracingId: '1', name: 'Driver 1', country: 'US' }); await context.driverRepository.create(driver); const teamId = 't1'; const team = Team.create({ id: teamId, name: 'Team 1', tag: 'T1', description: 'Test Team', ownerId: 'owner', leagues: [] }); await context.teamRepository.create(team); const result = await joinTeamUseCase.execute({ teamId, driverId }); expect(result.isOk()).toBe(true); const { membership } = result.unwrap(); expect(membership.status).toBe('active'); expect(membership.role).toBe('driver'); const savedMembership = await context.membershipRepository.getMembership(teamId, driverId); expect(savedMembership).toBeDefined(); expect(savedMembership?.status).toBe('active'); }); it('should reject join request when driver is already a member', async () => { const driverId = 'd3'; const teamId = 't3'; const team = Team.create({ id: teamId, name: 'Team 3', tag: 'T3', description: 'Test Team', ownerId: 'owner', leagues: [] }); await context.teamRepository.create(team); await context.membershipRepository.saveMembership({ teamId, driverId, role: 'driver', status: 'active', joinedAt: new Date() }); const result = await joinTeamUseCase.execute({ teamId, driverId }); expect(result.isErr()).toBe(true); // JoinTeamUseCase returns ALREADY_IN_TEAM if driver is in ANY team, // and ALREADY_MEMBER if they are already in THIS team. // In this case, they are already in this team. expect(result.unwrapErr().code).toBe('ALREADY_IN_TEAM'); }); }); describe('LeaveTeamUseCase', () => { it('should allow driver to leave team', async () => { const driverId = 'd7'; const teamId = 't7'; const team = Team.create({ id: teamId, name: 'Team 7', tag: 'T7', description: 'Test Team', ownerId: 'owner', leagues: [] }); await context.teamRepository.create(team); await context.membershipRepository.saveMembership({ teamId, driverId, role: 'driver', status: 'active', joinedAt: new Date() }); const result = await leaveTeamUseCase.execute({ teamId, driverId }); expect(result.isOk()).toBe(true); const savedMembership = await context.membershipRepository.getMembership(teamId, driverId); expect(savedMembership).toBeNull(); }); it('should reject leave when driver is team owner', async () => { const driverId = 'd9'; const teamId = 't9'; const team = Team.create({ id: teamId, name: 'Team 9', tag: 'T9', description: 'Test Team', ownerId: driverId, leagues: [] }); await context.teamRepository.create(team); await context.membershipRepository.saveMembership({ teamId, driverId, role: 'owner', status: 'active', joinedAt: new Date() }); const result = await leaveTeamUseCase.execute({ teamId, driverId }); expect(result.isErr()).toBe(true); expect(result.unwrapErr().code).toBe('OWNER_CANNOT_LEAVE'); }); }); describe('GetTeamMembershipUseCase', () => { it('should retrieve driver membership in team', async () => { const driverId = 'd10'; const teamId = 't10'; const team = Team.create({ id: teamId, name: 'Team 10', tag: 'T10', description: 'Test Team', ownerId: 'owner', leagues: [] }); await context.teamRepository.create(team); await context.membershipRepository.saveMembership({ teamId, driverId, role: 'driver', status: 'active', joinedAt: new Date() }); const result = await getTeamMembershipUseCase.execute({ teamId, driverId }); expect(result.isOk()).toBe(true); const { membership } = result.unwrap(); expect(membership?.role).toBe('member'); }); }); describe('GetTeamMembersUseCase', () => { it('should retrieve all team members', async () => { const teamId = 't12'; const team = Team.create({ id: teamId, name: 'Team 12', tag: 'T12', description: 'Test Team', ownerId: 'owner', leagues: [] }); await context.teamRepository.create(team); const driver1 = Driver.create({ id: 'd12', iracingId: '12', name: 'Driver 12', country: 'US' }); const driver2 = Driver.create({ id: 'd13', iracingId: '13', name: 'Driver 13', country: 'UK' }); await context.driverRepository.create(driver1); await context.driverRepository.create(driver2); await context.membershipRepository.saveMembership({ teamId, driverId: 'd12', role: 'owner', status: 'active', joinedAt: new Date() }); await context.membershipRepository.saveMembership({ teamId, driverId: 'd13', role: 'driver', status: 'active', joinedAt: new Date() }); const result = await getTeamMembersUseCase.execute({ teamId }); expect(result.isOk()).toBe(true); const { members } = result.unwrap(); expect(members).toHaveLength(2); }); }); describe('GetTeamJoinRequestsUseCase', () => { it('should retrieve pending join requests', async () => { const teamId = 't14'; const team = Team.create({ id: teamId, name: 'Team 14', tag: 'T14', description: 'Test Team', ownerId: 'owner', leagues: [] }); await context.teamRepository.create(team); const driver1 = Driver.create({ id: 'd14', iracingId: '14', name: 'Driver 14', country: 'US' }); await context.driverRepository.create(driver1); await context.membershipRepository.saveJoinRequest({ id: 'jr2', teamId, driverId: 'd14', requestedAt: new Date() }); const result = await getTeamJoinRequestsUseCase.execute({ teamId }); expect(result.isOk()).toBe(true); const { joinRequests } = result.unwrap(); expect(joinRequests).toHaveLength(1); }); }); describe('ApproveTeamJoinRequestUseCase', () => { it('should approve a pending join request', async () => { const teamId = 't16'; const team = Team.create({ id: teamId, name: 'Team 16', tag: 'T16', description: 'Test Team', ownerId: 'owner', leagues: [] }); await context.teamRepository.create(team); const driverId = 'd16'; const driver = Driver.create({ id: driverId, iracingId: '16', name: 'Driver 16', country: 'US' }); await context.driverRepository.create(driver); await context.membershipRepository.saveJoinRequest({ id: 'jr4', teamId, driverId, requestedAt: new Date() }); const result = await approveTeamJoinRequestUseCase.execute({ teamId, requestId: 'jr4' }); expect(result.isOk()).toBe(true); const savedMembership = await context.membershipRepository.getMembership(teamId, driverId); expect(savedMembership?.status).toBe('active'); }); }); });