/** * Integration Test: Sponsor Signup Use Case Orchestration * * Tests the orchestration logic of sponsor signup-related Use Cases: * - CreateSponsorUseCase: Creates a new sponsor account * - SponsorLoginUseCase: Authenticates a sponsor * - SponsorLogoutUseCase: Logs out a sponsor * - Validates that Use Cases correctly interact with their Ports (Repositories, Event Publishers) * - Uses In-Memory adapters for fast, deterministic testing * * Focus: Business logic orchestration, NOT UI rendering */ import { describe, it, expect, beforeAll, afterAll, beforeEach } from 'vitest'; import { InMemorySponsorRepository } from '../../../adapters/sponsors/persistence/inmemory/InMemorySponsorRepository'; import { InMemoryEventPublisher } from '../../../adapters/events/InMemoryEventPublisher'; import { CreateSponsorUseCase } from '../../../core/sponsors/use-cases/CreateSponsorUseCase'; import { SponsorLoginUseCase } from '../../../core/sponsors/use-cases/SponsorLoginUseCase'; import { SponsorLogoutUseCase } from '../../../core/sponsors/use-cases/SponsorLogoutUseCase'; import { CreateSponsorCommand } from '../../../core/sponsors/ports/CreateSponsorCommand'; import { SponsorLoginCommand } from '../../../core/sponsors/ports/SponsorLoginCommand'; import { SponsorLogoutCommand } from '../../../core/sponsors/ports/SponsorLogoutCommand'; describe('Sponsor Signup Use Case Orchestration', () => { let sponsorRepository: InMemorySponsorRepository; let eventPublisher: InMemoryEventPublisher; let createSponsorUseCase: CreateSponsorUseCase; let sponsorLoginUseCase: SponsorLoginUseCase; let sponsorLogoutUseCase: SponsorLogoutUseCase; beforeAll(() => { // TODO: Initialize In-Memory repositories and event publisher // sponsorRepository = new InMemorySponsorRepository(); // eventPublisher = new InMemoryEventPublisher(); // createSponsorUseCase = new CreateSponsorUseCase({ // sponsorRepository, // eventPublisher, // }); // sponsorLoginUseCase = new SponsorLoginUseCase({ // sponsorRepository, // eventPublisher, // }); // sponsorLogoutUseCase = new SponsorLogoutUseCase({ // sponsorRepository, // eventPublisher, // }); }); beforeEach(() => { // TODO: Clear all In-Memory repositories before each test // sponsorRepository.clear(); // eventPublisher.clear(); }); describe('CreateSponsorUseCase - Success Path', () => { it('should create a new sponsor account with valid information', async () => { // TODO: Implement test // Scenario: Sponsor creates account // Given: No sponsor exists with the given email // When: CreateSponsorUseCase.execute() is called with valid sponsor data // Then: The sponsor should be created in the repository // And: The sponsor should have a unique ID // And: The sponsor should have the provided company name // And: The sponsor should have the provided contact email // And: The sponsor should have the provided website URL // And: The sponsor should have the provided sponsorship interests // And: The sponsor should have a created timestamp // And: EventPublisher should emit SponsorCreatedEvent }); it('should create a sponsor with multiple sponsorship interests', async () => { // TODO: Implement test // Scenario: Sponsor creates account with multiple interests // Given: No sponsor exists with the given email // When: CreateSponsorUseCase.execute() is called with multiple sponsorship interests // Then: The sponsor should be created with all selected interests // And: Each interest should be stored correctly // And: EventPublisher should emit SponsorCreatedEvent }); it('should create a sponsor with optional company logo', async () => { // TODO: Implement test // Scenario: Sponsor creates account with logo // Given: No sponsor exists with the given email // When: CreateSponsorUseCase.execute() is called with a company logo // Then: The sponsor should be created with the logo reference // And: The logo should be stored in the media repository // And: EventPublisher should emit SponsorCreatedEvent }); it('should create a sponsor with default settings', async () => { // TODO: Implement test // Scenario: Sponsor creates account with default settings // Given: No sponsor exists with the given email // When: CreateSponsorUseCase.execute() is called // Then: The sponsor should be created with default notification preferences // And: The sponsor should be created with default privacy settings // And: EventPublisher should emit SponsorCreatedEvent }); }); describe('CreateSponsorUseCase - Validation', () => { it('should reject sponsor creation with duplicate email', async () => { // TODO: Implement test // Scenario: Duplicate email // Given: A sponsor exists with email "sponsor@example.com" // When: CreateSponsorUseCase.execute() is called with the same email // Then: Should throw DuplicateEmailError // And: EventPublisher should NOT emit any events }); it('should reject sponsor creation with invalid email format', async () => { // TODO: Implement test // Scenario: Invalid email format // Given: No sponsor exists // When: CreateSponsorUseCase.execute() is called with invalid email // Then: Should throw ValidationError // And: EventPublisher should NOT emit any events }); it('should reject sponsor creation with missing required fields', async () => { // TODO: Implement test // Scenario: Missing required fields // Given: No sponsor exists // When: CreateSponsorUseCase.execute() is called without company name // Then: Should throw ValidationError // And: EventPublisher should NOT emit any events }); it('should reject sponsor creation with invalid website URL', async () => { // TODO: Implement test // Scenario: Invalid website URL // Given: No sponsor exists // When: CreateSponsorUseCase.execute() is called with invalid URL // Then: Should throw ValidationError // And: EventPublisher should NOT emit any events }); it('should reject sponsor creation with invalid password', async () => { // TODO: Implement test // Scenario: Invalid password // Given: No sponsor exists // When: CreateSponsorUseCase.execute() is called with weak password // Then: Should throw ValidationError // And: EventPublisher should NOT emit any events }); }); describe('SponsorLoginUseCase - Success Path', () => { it('should authenticate sponsor with valid credentials', async () => { // TODO: Implement test // Scenario: Sponsor logs in // Given: A sponsor exists with email "sponsor@example.com" and password "password123" // When: SponsorLoginUseCase.execute() is called with valid credentials // Then: The sponsor should be authenticated // And: The sponsor should receive an authentication token // And: EventPublisher should emit SponsorLoggedInEvent }); it('should authenticate sponsor with correct email and password', async () => { // TODO: Implement test // Scenario: Sponsor logs in with correct credentials // Given: A sponsor exists with specific credentials // When: SponsorLoginUseCase.execute() is called with matching credentials // Then: The sponsor should be authenticated // And: EventPublisher should emit SponsorLoggedInEvent }); }); describe('SponsorLoginUseCase - Error Handling', () => { it('should reject login with non-existent email', async () => { // TODO: Implement test // Scenario: Non-existent sponsor // Given: No sponsor exists with the given email // When: SponsorLoginUseCase.execute() is called // Then: Should throw SponsorNotFoundError // And: EventPublisher should NOT emit any events }); it('should reject login with incorrect password', async () => { // TODO: Implement test // Scenario: Incorrect password // Given: A sponsor exists with email "sponsor@example.com" // When: SponsorLoginUseCase.execute() is called with wrong password // Then: Should throw InvalidCredentialsError // And: EventPublisher should NOT emit any events }); it('should reject login with invalid email format', async () => { // TODO: Implement test // Scenario: Invalid email format // Given: No sponsor exists // When: SponsorLoginUseCase.execute() is called with invalid email // Then: Should throw ValidationError // And: EventPublisher should NOT emit any events }); }); describe('SponsorLogoutUseCase - Success Path', () => { it('should log out authenticated sponsor', async () => { // TODO: Implement test // Scenario: Sponsor logs out // Given: A sponsor is authenticated // When: SponsorLogoutUseCase.execute() is called // Then: The sponsor should be logged out // And: EventPublisher should emit SponsorLoggedOutEvent }); }); describe('Sponsor Data Orchestration', () => { it('should correctly create sponsor with sponsorship interests', async () => { // TODO: Implement test // Scenario: Sponsor with multiple interests // Given: No sponsor exists // When: CreateSponsorUseCase.execute() is called with interests: ["League", "Team", "Driver"] // Then: The sponsor should have all three interests stored // And: Each interest should be retrievable // And: EventPublisher should emit SponsorCreatedEvent }); it('should correctly create sponsor with default notification preferences', async () => { // TODO: Implement test // Scenario: Sponsor with default notifications // Given: No sponsor exists // When: CreateSponsorUseCase.execute() is called // Then: The sponsor should have default notification preferences // And: All notification types should be enabled by default // And: EventPublisher should emit SponsorCreatedEvent }); it('should correctly create sponsor with default privacy settings', async () => { // TODO: Implement test // Scenario: Sponsor with default privacy // Given: No sponsor exists // When: CreateSponsorUseCase.execute() is called // Then: The sponsor should have default privacy settings // And: Public profile should be enabled by default // And: EventPublisher should emit SponsorCreatedEvent }); }); });