import { describe, it, expect, beforeEach, vi, Mock } from 'vitest'; import { CreateTeamUseCase, type CreateTeamInput, type CreateTeamResult, } from './CreateTeamUseCase'; import type { ITeamRepository } from '../../domain/repositories/ITeamRepository'; import type { ITeamMembershipRepository } from '../../domain/repositories/ITeamMembershipRepository'; import type { Logger } from '@core/shared/application'; import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort'; describe('CreateTeamUseCase', () => { let useCase: CreateTeamUseCase; let teamRepository: { create: Mock; }; let membershipRepository: { getActiveMembershipForDriver: Mock; saveMembership: Mock; }; let logger: { debug: Mock; info: Mock; warn: Mock; error: Mock; }; let output: { present: Mock }; beforeEach(() => { teamRepository = { create: vi.fn(), }; membershipRepository = { getActiveMembershipForDriver: vi.fn(), saveMembership: vi.fn(), }; logger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), }; output = { present: vi.fn() }; useCase = new CreateTeamUseCase( teamRepository as unknown as ITeamRepository, membershipRepository as unknown as ITeamMembershipRepository, logger as unknown as Logger, output as unknown as UseCaseOutputPort, ); }); it('should create team successfully', async () => { const command: CreateTeamInput = { name: 'Test Team', tag: 'TT', description: 'A test team', ownerId: 'owner-123', leagues: ['league-1'], }; membershipRepository.getActiveMembershipForDriver.mockResolvedValue(null); const mockTeam = { id: 'team-uuid', name: 'Test Team', tag: 'TT', description: 'A test team', ownerId: 'owner-123', leagues: ['league-1'], createdAt: new Date(), }; teamRepository.create.mockResolvedValue(mockTeam); membershipRepository.saveMembership.mockResolvedValue(undefined); const result = await useCase.execute(command); expect(result.isOk()).toBe(true); expect(result.unwrap()).toBeUndefined(); expect(teamRepository.create).toHaveBeenCalledTimes(1); expect(membershipRepository.saveMembership).toHaveBeenCalledTimes(1); expect(output.present).toHaveBeenCalledTimes(1); expect(output.present).toHaveBeenCalledWith({ team: mockTeam }); }); it('should return error when driver already belongs to a team', async () => { const command: CreateTeamInput = { name: 'Test Team', tag: 'TT', description: 'A test team', ownerId: 'owner-123', leagues: ['league-1'], }; membershipRepository.getActiveMembershipForDriver.mockResolvedValue({ teamId: 'existing-team', driverId: 'owner-123', role: 'member', status: 'active', joinedAt: new Date(), }); const result = await useCase.execute(command); expect(result.isErr()).toBe(true); expect(result.unwrapErr().code).toBe('VALIDATION_ERROR'); expect(result.unwrapErr().details?.message).toBe( 'Driver already belongs to a team', ); expect(teamRepository.create).not.toHaveBeenCalled(); expect(membershipRepository.saveMembership).not.toHaveBeenCalled(); expect(output.present).not.toHaveBeenCalled(); }); it('should return error when repository throws', async () => { const command: CreateTeamInput = { name: 'Test Team', tag: 'TT', description: 'A test team', ownerId: 'owner-123', leagues: ['league-1'], }; membershipRepository.getActiveMembershipForDriver.mockResolvedValue(null); teamRepository.create.mockRejectedValue(new Error('DB error')); const result = await useCase.execute(command); expect(result.isErr()).toBe(true); expect(result.unwrapErr().code).toBe('REPOSITORY_ERROR'); expect(result.unwrapErr().details?.message).toBe('DB error'); expect(output.present).not.toHaveBeenCalled(); }); });