/** * Integration Test: Sponsor Settings Use Case Orchestration * * Tests the orchestration logic of sponsor settings-related Use Cases: * - GetSponsorProfileUseCase: Retrieves sponsor profile information * - UpdateSponsorProfileUseCase: Updates sponsor profile information * - GetNotificationPreferencesUseCase: Retrieves notification preferences * - UpdateNotificationPreferencesUseCase: Updates notification preferences * - GetPrivacySettingsUseCase: Retrieves privacy settings * - UpdatePrivacySettingsUseCase: Updates privacy settings * - DeleteSponsorAccountUseCase: Deletes sponsor account * - 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 { GetSponsorProfileUseCase } from '../../../core/sponsors/use-cases/GetSponsorProfileUseCase'; import { UpdateSponsorProfileUseCase } from '../../../core/sponsors/use-cases/UpdateSponsorProfileUseCase'; import { GetNotificationPreferencesUseCase } from '../../../core/sponsors/use-cases/GetNotificationPreferencesUseCase'; import { UpdateNotificationPreferencesUseCase } from '../../../core/sponsors/use-cases/UpdateNotificationPreferencesUseCase'; import { GetPrivacySettingsUseCase } from '../../../core/sponsors/use-cases/GetPrivacySettingsUseCase'; import { UpdatePrivacySettingsUseCase } from '../../../core/sponsors/use-cases/UpdatePrivacySettingsUseCase'; import { DeleteSponsorAccountUseCase } from '../../../core/sponsors/use-cases/DeleteSponsorAccountUseCase'; import { GetSponsorProfileQuery } from '../../../core/sponsors/ports/GetSponsorProfileQuery'; import { UpdateSponsorProfileCommand } from '../../../core/sponsors/ports/UpdateSponsorProfileCommand'; import { GetNotificationPreferencesQuery } from '../../../core/sponsors/ports/GetNotificationPreferencesQuery'; import { UpdateNotificationPreferencesCommand } from '../../../core/sponsors/ports/UpdateNotificationPreferencesCommand'; import { GetPrivacySettingsQuery } from '../../../core/sponsors/ports/GetPrivacySettingsQuery'; import { UpdatePrivacySettingsCommand } from '../../../core/sponsors/ports/UpdatePrivacySettingsCommand'; import { DeleteSponsorAccountCommand } from '../../../core/sponsors/ports/DeleteSponsorAccountCommand'; describe('Sponsor Settings Use Case Orchestration', () => { let sponsorRepository: InMemorySponsorRepository; let eventPublisher: InMemoryEventPublisher; let getSponsorProfileUseCase: GetSponsorProfileUseCase; let updateSponsorProfileUseCase: UpdateSponsorProfileUseCase; let getNotificationPreferencesUseCase: GetNotificationPreferencesUseCase; let updateNotificationPreferencesUseCase: UpdateNotificationPreferencesUseCase; let getPrivacySettingsUseCase: GetPrivacySettingsUseCase; let updatePrivacySettingsUseCase: UpdatePrivacySettingsUseCase; let deleteSponsorAccountUseCase: DeleteSponsorAccountUseCase; beforeAll(() => { // TODO: Initialize In-Memory repositories and event publisher // sponsorRepository = new InMemorySponsorRepository(); // eventPublisher = new InMemoryEventPublisher(); // getSponsorProfileUseCase = new GetSponsorProfileUseCase({ // sponsorRepository, // eventPublisher, // }); // updateSponsorProfileUseCase = new UpdateSponsorProfileUseCase({ // sponsorRepository, // eventPublisher, // }); // getNotificationPreferencesUseCase = new GetNotificationPreferencesUseCase({ // sponsorRepository, // eventPublisher, // }); // updateNotificationPreferencesUseCase = new UpdateNotificationPreferencesUseCase({ // sponsorRepository, // eventPublisher, // }); // getPrivacySettingsUseCase = new GetPrivacySettingsUseCase({ // sponsorRepository, // eventPublisher, // }); // updatePrivacySettingsUseCase = new UpdatePrivacySettingsUseCase({ // sponsorRepository, // eventPublisher, // }); // deleteSponsorAccountUseCase = new DeleteSponsorAccountUseCase({ // sponsorRepository, // eventPublisher, // }); }); beforeEach(() => { // TODO: Clear all In-Memory repositories before each test // sponsorRepository.clear(); // eventPublisher.clear(); }); describe('GetSponsorProfileUseCase - Success Path', () => { it('should retrieve sponsor profile information', async () => { // TODO: Implement test // Scenario: Sponsor with complete profile // Given: A sponsor exists with ID "sponsor-123" // And: The sponsor has company name "Test Company" // And: The sponsor has contact name "John Doe" // And: The sponsor has contact email "john@example.com" // And: The sponsor has contact phone "+1234567890" // And: The sponsor has website URL "https://testcompany.com" // And: The sponsor has company description "Test description" // And: The sponsor has industry "Technology" // And: The sponsor has address "123 Test St" // And: The sponsor has tax ID "TAX123" // When: GetSponsorProfileUseCase.execute() is called with sponsor ID // Then: The result should show all profile information // And: EventPublisher should emit SponsorProfileAccessedEvent }); it('should retrieve profile with minimal data', async () => { // TODO: Implement test // Scenario: Sponsor with minimal profile // Given: A sponsor exists with ID "sponsor-123" // And: The sponsor has company name "Test Company" // And: The sponsor has contact email "john@example.com" // When: GetSponsorProfileUseCase.execute() is called with sponsor ID // Then: The result should show available profile information // And: EventPublisher should emit SponsorProfileAccessedEvent }); }); describe('GetSponsorProfileUseCase - Error Handling', () => { it('should throw error when sponsor does not exist', async () => { // TODO: Implement test // Scenario: Non-existent sponsor // Given: No sponsor exists with the given ID // When: GetSponsorProfileUseCase.execute() is called with non-existent sponsor ID // Then: Should throw SponsorNotFoundError // And: EventPublisher should NOT emit any events }); }); describe('UpdateSponsorProfileUseCase - Success Path', () => { it('should update sponsor profile information', async () => { // TODO: Implement test // Scenario: Update sponsor profile // Given: A sponsor exists with ID "sponsor-123" // When: UpdateSponsorProfileUseCase.execute() is called with updated profile data // Then: The sponsor profile should be updated // And: The updated data should be retrievable // And: EventPublisher should emit SponsorProfileUpdatedEvent }); it('should update sponsor profile with partial data', async () => { // TODO: Implement test // Scenario: Update partial profile // Given: A sponsor exists with ID "sponsor-123" // When: UpdateSponsorProfileUseCase.execute() is called with partial profile data // Then: Only the provided fields should be updated // And: Other fields should remain unchanged // And: EventPublisher should emit SponsorProfileUpdatedEvent }); }); describe('UpdateSponsorProfileUseCase - Validation', () => { it('should reject update with invalid email', async () => { // TODO: Implement test // Scenario: Invalid email format // Given: A sponsor exists with ID "sponsor-123" // When: UpdateSponsorProfileUseCase.execute() is called with invalid email // Then: Should throw ValidationError // And: EventPublisher should NOT emit any events }); it('should reject update with invalid phone', async () => { // TODO: Implement test // Scenario: Invalid phone format // Given: A sponsor exists with ID "sponsor-123" // When: UpdateSponsorProfileUseCase.execute() is called with invalid phone // Then: Should throw ValidationError // And: EventPublisher should NOT emit any events }); it('should reject update with invalid URL', async () => { // TODO: Implement test // Scenario: Invalid URL format // Given: A sponsor exists with ID "sponsor-123" // When: UpdateSponsorProfileUseCase.execute() is called with invalid URL // Then: Should throw ValidationError // And: EventPublisher should NOT emit any events }); }); describe('UpdateSponsorProfileUseCase - Error Handling', () => { it('should throw error when sponsor does not exist', async () => { // TODO: Implement test // Scenario: Non-existent sponsor // Given: No sponsor exists with the given ID // When: UpdateSponsorProfileUseCase.execute() is called with non-existent sponsor ID // Then: Should throw SponsorNotFoundError // And: EventPublisher should NOT emit any events }); }); describe('GetNotificationPreferencesUseCase - Success Path', () => { it('should retrieve notification preferences', async () => { // TODO: Implement test // Scenario: Sponsor with notification preferences // Given: A sponsor exists with ID "sponsor-123" // And: The sponsor has notification preferences configured // When: GetNotificationPreferencesUseCase.execute() is called with sponsor ID // Then: The result should show all notification options // And: Each option should show its enabled/disabled status // And: EventPublisher should emit NotificationPreferencesAccessedEvent }); it('should retrieve default notification preferences', async () => { // TODO: Implement test // Scenario: Sponsor with default preferences // Given: A sponsor exists with ID "sponsor-123" // And: The sponsor has default notification preferences // When: GetNotificationPreferencesUseCase.execute() is called with sponsor ID // Then: The result should show default preferences // And: EventPublisher should emit NotificationPreferencesAccessedEvent }); }); describe('GetNotificationPreferencesUseCase - Error Handling', () => { it('should throw error when sponsor does not exist', async () => { // TODO: Implement test // Scenario: Non-existent sponsor // Given: No sponsor exists with the given ID // When: GetNotificationPreferencesUseCase.execute() is called with non-existent sponsor ID // Then: Should throw SponsorNotFoundError // And: EventPublisher should NOT emit any events }); }); describe('UpdateNotificationPreferencesUseCase - Success Path', () => { it('should update notification preferences', async () => { // TODO: Implement test // Scenario: Update notification preferences // Given: A sponsor exists with ID "sponsor-123" // When: UpdateNotificationPreferencesUseCase.execute() is called with updated preferences // Then: The notification preferences should be updated // And: The updated preferences should be retrievable // And: EventPublisher should emit NotificationPreferencesUpdatedEvent }); it('should toggle individual notification preferences', async () => { // TODO: Implement test // Scenario: Toggle notification preference // Given: A sponsor exists with ID "sponsor-123" // When: UpdateNotificationPreferencesUseCase.execute() is called to toggle a preference // Then: Only the toggled preference should change // And: Other preferences should remain unchanged // And: EventPublisher should emit NotificationPreferencesUpdatedEvent }); }); describe('UpdateNotificationPreferencesUseCase - Error Handling', () => { it('should throw error when sponsor does not exist', async () => { // TODO: Implement test // Scenario: Non-existent sponsor // Given: No sponsor exists with the given ID // When: UpdateNotificationPreferencesUseCase.execute() is called with non-existent sponsor ID // Then: Should throw SponsorNotFoundError // And: EventPublisher should NOT emit any events }); }); describe('GetPrivacySettingsUseCase - Success Path', () => { it('should retrieve privacy settings', async () => { // TODO: Implement test // Scenario: Sponsor with privacy settings // Given: A sponsor exists with ID "sponsor-123" // And: The sponsor has privacy settings configured // When: GetPrivacySettingsUseCase.execute() is called with sponsor ID // Then: The result should show all privacy options // And: Each option should show its enabled/disabled status // And: EventPublisher should emit PrivacySettingsAccessedEvent }); it('should retrieve default privacy settings', async () => { // TODO: Implement test // Scenario: Sponsor with default privacy settings // Given: A sponsor exists with ID "sponsor-123" // And: The sponsor has default privacy settings // When: GetPrivacySettingsUseCase.execute() is called with sponsor ID // Then: The result should show default privacy settings // And: EventPublisher should emit PrivacySettingsAccessedEvent }); }); describe('GetPrivacySettingsUseCase - Error Handling', () => { it('should throw error when sponsor does not exist', async () => { // TODO: Implement test // Scenario: Non-existent sponsor // Given: No sponsor exists with the given ID // When: GetPrivacySettingsUseCase.execute() is called with non-existent sponsor ID // Then: Should throw SponsorNotFoundError // And: EventPublisher should NOT emit any events }); }); describe('UpdatePrivacySettingsUseCase - Success Path', () => { it('should update privacy settings', async () => { // TODO: Implement test // Scenario: Update privacy settings // Given: A sponsor exists with ID "sponsor-123" // When: UpdatePrivacySettingsUseCase.execute() is called with updated settings // Then: The privacy settings should be updated // And: The updated settings should be retrievable // And: EventPublisher should emit PrivacySettingsUpdatedEvent }); it('should toggle individual privacy settings', async () => { // TODO: Implement test // Scenario: Toggle privacy setting // Given: A sponsor exists with ID "sponsor-123" // When: UpdatePrivacySettingsUseCase.execute() is called to toggle a setting // Then: Only the toggled setting should change // And: Other settings should remain unchanged // And: EventPublisher should emit PrivacySettingsUpdatedEvent }); }); describe('UpdatePrivacySettingsUseCase - Error Handling', () => { it('should throw error when sponsor does not exist', async () => { // TODO: Implement test // Scenario: Non-existent sponsor // Given: No sponsor exists with the given ID // When: UpdatePrivacySettingsUseCase.execute() is called with non-existent sponsor ID // Then: Should throw SponsorNotFoundError // And: EventPublisher should NOT emit any events }); }); describe('DeleteSponsorAccountUseCase - Success Path', () => { it('should delete sponsor account', async () => { // TODO: Implement test // Scenario: Delete sponsor account // Given: A sponsor exists with ID "sponsor-123" // When: DeleteSponsorAccountUseCase.execute() is called with sponsor ID // Then: The sponsor account should be deleted // And: The sponsor should no longer be retrievable // And: EventPublisher should emit SponsorAccountDeletedEvent }); }); describe('DeleteSponsorAccountUseCase - Error Handling', () => { it('should throw error when sponsor does not exist', async () => { // TODO: Implement test // Scenario: Non-existent sponsor // Given: No sponsor exists with the given ID // When: DeleteSponsorAccountUseCase.execute() is called with non-existent sponsor ID // Then: Should throw SponsorNotFoundError // And: EventPublisher should NOT emit any events }); }); describe('Sponsor Settings Data Orchestration', () => { it('should correctly update sponsor profile', async () => { // TODO: Implement test // Scenario: Profile update orchestration // Given: A sponsor exists with ID "sponsor-123" // And: The sponsor has initial profile data // When: UpdateSponsorProfileUseCase.execute() is called with new data // Then: The profile should be updated in the repository // And: The updated data should be retrievable // And: EventPublisher should emit SponsorProfileUpdatedEvent }); it('should correctly update notification preferences', async () => { // TODO: Implement test // Scenario: Notification preferences update orchestration // Given: A sponsor exists with ID "sponsor-123" // And: The sponsor has initial notification preferences // When: UpdateNotificationPreferencesUseCase.execute() is called with new preferences // Then: The preferences should be updated in the repository // And: The updated preferences should be retrievable // And: EventPublisher should emit NotificationPreferencesUpdatedEvent }); it('should correctly update privacy settings', async () => { // TODO: Implement test // Scenario: Privacy settings update orchestration // Given: A sponsor exists with ID "sponsor-123" // And: The sponsor has initial privacy settings // When: UpdatePrivacySettingsUseCase.execute() is called with new settings // Then: The settings should be updated in the repository // And: The updated settings should be retrievable // And: EventPublisher should emit PrivacySettingsUpdatedEvent }); it('should correctly delete sponsor account', async () => { // TODO: Implement test // Scenario: Account deletion orchestration // Given: A sponsor exists with ID "sponsor-123" // When: DeleteSponsorAccountUseCase.execute() is called // Then: The sponsor should be deleted from the repository // And: The sponsor should no longer be retrievable // And: EventPublisher should emit SponsorAccountDeletedEvent }); }); });