152 lines
4.7 KiB
TypeScript
152 lines
4.7 KiB
TypeScript
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';
|
|
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
|
|
|
|
describe('CreateSponsorUseCase', () => {
|
|
let useCase: CreateSponsorUseCase;
|
|
let sponsorRepository: {
|
|
create: Mock;
|
|
};
|
|
let logger: {
|
|
debug: Mock;
|
|
info: Mock;
|
|
warn: Mock;
|
|
error: Mock;
|
|
};
|
|
let output: {
|
|
present: Mock;
|
|
};
|
|
|
|
beforeEach(() => {
|
|
sponsorRepository = {
|
|
create: vi.fn(),
|
|
};
|
|
logger = {
|
|
debug: vi.fn(),
|
|
info: vi.fn(),
|
|
warn: vi.fn(),
|
|
error: vi.fn(),
|
|
};
|
|
output = {
|
|
present: vi.fn(),
|
|
};
|
|
useCase = new CreateSponsorUseCase(
|
|
sponsorRepository as unknown as ISponsorRepository,
|
|
logger as unknown as Logger,
|
|
output as unknown as UseCaseOutputPort<any>,
|
|
);
|
|
});
|
|
|
|
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);
|
|
expect(result.unwrap()).toBeUndefined();
|
|
expect(output.present).toHaveBeenCalledTimes(1);
|
|
const presented = output.present.mock.calls[0][0];
|
|
expect(presented.sponsor.id).toBeDefined();
|
|
expect(presented.sponsor.name).toBe('Test Sponsor');
|
|
expect(presented.sponsor.contactEmail).toBe('test@example.com');
|
|
expect(presented.sponsor.websiteUrl).toBe('https://example.com');
|
|
expect(presented.sponsor.logoUrl).toBe('https://example.com/logo.png');
|
|
expect(presented.sponsor.createdAt).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);
|
|
expect(result.unwrap()).toBeUndefined();
|
|
expect(output.present).toHaveBeenCalledTimes(1);
|
|
const presented = output.present.mock.calls[0][0];
|
|
expect(presented.sponsor.websiteUrl).toBeUndefined();
|
|
expect(presented.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');
|
|
expect(output.present).not.toHaveBeenCalled();
|
|
});
|
|
|
|
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');
|
|
expect(output.present).not.toHaveBeenCalled();
|
|
});
|
|
|
|
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');
|
|
expect(output.present).not.toHaveBeenCalled();
|
|
});
|
|
|
|
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');
|
|
expect(output.present).not.toHaveBeenCalled();
|
|
});
|
|
|
|
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');
|
|
expect(output.present).not.toHaveBeenCalled();
|
|
});
|
|
}); |