import { describe, it, expect, beforeEach, vi, Mock } from 'vitest'; import { CreateSponsorUseCase, type CreateSponsorInput } from './CreateSponsorUseCase'; import type { ISponsorRepository } from '../../domain/repositories/ISponsorRepository'; import type { Logger } from '@core/shared/application'; describe('CreateSponsorUseCase', () => { let useCase: CreateSponsorUseCase; let sponsorRepository: { create: Mock; }; let logger: { debug: Mock; info: Mock; warn: Mock; error: Mock; }; beforeEach(() => { sponsorRepository = { create: vi.fn(), }; logger = { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn(), }; useCase = new CreateSponsorUseCase( sponsorRepository as unknown as ISponsorRepository, logger as unknown as Logger, ); }); it('should create sponsor successfully', async () => { const input: CreateSponsorInput = { name: 'Test Sponsor', contactEmail: 'test@example.com', websiteUrl: 'https://example.com', logoUrl: 'https://example.com/logo.png', }; sponsorRepository.create.mockResolvedValue(undefined); const result = await useCase.execute(input); expect(result.isOk()).toBe(true); const successResult = result.unwrap(); expect(successResult.sponsor.id).toBeDefined(); expect(successResult.sponsor.name.toString()).toBe('Test Sponsor'); expect(successResult.sponsor.contactEmail.toString()).toBe('test@example.com'); expect(successResult.sponsor.websiteUrl?.toString()).toBe('https://example.com'); expect(successResult.sponsor.logoUrl?.toString()).toBe('https://example.com/logo.png'); expect(successResult.sponsor.createdAt.toDate()).toBeInstanceOf(Date); expect(sponsorRepository.create).toHaveBeenCalledTimes(1); }); it('should create sponsor without optional fields', async () => { const input: CreateSponsorInput = { name: 'Test Sponsor', contactEmail: 'test@example.com', }; sponsorRepository.create.mockResolvedValue(undefined); const result = await useCase.execute(input); expect(result.isOk()).toBe(true); const successResult = result.unwrap(); expect(successResult.sponsor.websiteUrl).toBeUndefined(); expect(successResult.sponsor.logoUrl).toBeUndefined(); }); it('should return error when name is empty', async () => { const input: CreateSponsorInput = { name: '', contactEmail: 'test@example.com', }; const result = await useCase.execute(input); expect(result.isErr()).toBe(true); expect(result.unwrapErr().details.message).toBe('Sponsor name is required'); }); it('should return error when contactEmail is empty', async () => { const input: CreateSponsorInput = { name: 'Test Sponsor', contactEmail: '', }; const result = await useCase.execute(input); expect(result.isErr()).toBe(true); expect(result.unwrapErr().details.message).toBe('Sponsor contact email is required'); }); it('should return error when contactEmail is invalid', async () => { const input: CreateSponsorInput = { name: 'Test Sponsor', contactEmail: 'invalid-email', }; const result = await useCase.execute(input); expect(result.isErr()).toBe(true); expect(result.unwrapErr().details.message).toBe('Invalid sponsor contact email format'); }); it('should return error when websiteUrl is invalid', async () => { const input: CreateSponsorInput = { name: 'Test Sponsor', contactEmail: 'test@example.com', websiteUrl: 'invalid-url', }; const result = await useCase.execute(input); expect(result.isErr()).toBe(true); expect(result.unwrapErr().details.message).toBe('Invalid sponsor website URL'); }); it('should return error when repository throws', async () => { const input: CreateSponsorInput = { name: 'Test Sponsor', contactEmail: 'test@example.com', }; sponsorRepository.create.mockRejectedValue(new Error('DB error')); const result = await useCase.execute(input); expect(result.isErr()).toBe(true); expect(result.unwrapErr().details.message).toBe('DB error'); }); });