/** * Integration Test: GetDriverUseCase Orchestration * * Tests the orchestration logic of GetDriverUseCase: * - GetDriverUseCase: Retrieves a single driver by ID * - Validates that Use Cases correctly interact with their Ports (Repositories) * - Uses In-Memory adapters for fast, deterministic testing * * Focus: Business logic orchestration, NOT UI rendering */ import { describe, it, expect, beforeAll, beforeEach } from 'vitest'; import { InMemoryDriverRepository } from '../../../adapters/racing/persistence/inmemory/InMemoryDriverRepository'; import { GetDriverUseCase } from '../../../core/racing/application/use-cases/GetDriverUseCase'; import { Driver } from '../../../core/racing/domain/entities/Driver'; import { MediaReference } from '../../../core/domain/media/MediaReference'; import { Logger } from '../../../core/shared/domain/Logger'; describe('GetDriverUseCase Orchestration', () => { let driverRepository: InMemoryDriverRepository; let getDriverUseCase: GetDriverUseCase; let mockLogger: Logger; beforeAll(() => { mockLogger = { info: () => {}, debug: () => {}, warn: () => {}, error: () => {}, } as unknown as Logger; driverRepository = new InMemoryDriverRepository(mockLogger); getDriverUseCase = new GetDriverUseCase(driverRepository); }); beforeEach(() => { // Clear all In-Memory repositories before each test driverRepository.clear(); }); describe('GetDriverUseCase - Success Path', () => { it('should retrieve complete driver with all data', async () => { // Scenario: Driver with complete profile data // Given: A driver exists with personal information (name, avatar, bio, country) const driverId = 'driver-123'; const driver = Driver.create({ id: driverId, iracingId: '12345', name: 'John Doe', country: 'US', bio: 'A passionate racer with 10 years of experience', avatarRef: MediaReference.createUploaded('avatar-123'), }); await driverRepository.create(driver); // When: GetDriverUseCase.execute() is called with driver ID const result = await getDriverUseCase.execute({ driverId }); // Then: The result should contain all driver data expect(result.isOk()).toBe(true); const retrievedDriver = result.unwrap(); expect(retrievedDriver).toBeDefined(); expect(retrievedDriver.id).toBe(driverId); expect(retrievedDriver.iracingId.toString()).toBe('12345'); expect(retrievedDriver.name.toString()).toBe('John Doe'); expect(retrievedDriver.country.toString()).toBe('US'); expect(retrievedDriver.bio?.toString()).toBe('A passionate racer with 10 years of experience'); expect(retrievedDriver.avatarRef).toBeDefined(); }); it('should retrieve driver with minimal data', async () => { // Scenario: Driver with minimal profile data // Given: A driver exists with only basic information (name, country) const driverId = 'driver-456'; const driver = Driver.create({ id: driverId, iracingId: '67890', name: 'Jane Smith', country: 'UK', }); await driverRepository.create(driver); // When: GetDriverUseCase.execute() is called with driver ID const result = await getDriverUseCase.execute({ driverId }); // Then: The result should contain basic driver info expect(result.isOk()).toBe(true); const retrievedDriver = result.unwrap(); expect(retrievedDriver).toBeDefined(); expect(retrievedDriver.id).toBe(driverId); expect(retrievedDriver.iracingId.toString()).toBe('67890'); expect(retrievedDriver.name.toString()).toBe('Jane Smith'); expect(retrievedDriver.country.toString()).toBe('UK'); expect(retrievedDriver.bio).toBeUndefined(); expect(retrievedDriver.avatarRef).toBeDefined(); }); it('should retrieve driver with bio but no avatar', async () => { // Scenario: Driver with bio but no avatar // Given: A driver exists with bio but no avatar const driverId = 'driver-789'; const driver = Driver.create({ id: driverId, iracingId: '11111', name: 'Bob Johnson', country: 'CA', bio: 'Canadian racer', }); await driverRepository.create(driver); // When: GetDriverUseCase.execute() is called with driver ID const result = await getDriverUseCase.execute({ driverId }); // Then: The result should contain driver info with bio expect(result.isOk()).toBe(true); const retrievedDriver = result.unwrap(); expect(retrievedDriver).toBeDefined(); expect(retrievedDriver.id).toBe(driverId); expect(retrievedDriver.bio?.toString()).toBe('Canadian racer'); expect(retrievedDriver.avatarRef).toBeDefined(); }); it('should retrieve driver with avatar but no bio', async () => { // Scenario: Driver with avatar but no bio // Given: A driver exists with avatar but no bio const driverId = 'driver-999'; const driver = Driver.create({ id: driverId, iracingId: '22222', name: 'Alice Brown', country: 'DE', avatarRef: MediaReference.createUploaded('avatar-999'), }); await driverRepository.create(driver); // When: GetDriverUseCase.execute() is called with driver ID const result = await getDriverUseCase.execute({ driverId }); // Then: The result should contain driver info with avatar expect(result.isOk()).toBe(true); const retrievedDriver = result.unwrap(); expect(retrievedDriver).toBeDefined(); expect(retrievedDriver.id).toBe(driverId); expect(retrievedDriver.bio).toBeUndefined(); expect(retrievedDriver.avatarRef).toBeDefined(); }); }); describe('GetDriverUseCase - Edge Cases', () => { it('should handle driver with no bio', async () => { // Scenario: Driver with no bio // Given: A driver exists const driverId = 'driver-no-bio'; const driver = Driver.create({ id: driverId, iracingId: '33333', name: 'No Bio Driver', country: 'FR', }); await driverRepository.create(driver); // When: GetDriverUseCase.execute() is called with driver ID const result = await getDriverUseCase.execute({ driverId }); // Then: The result should contain driver profile expect(result.isOk()).toBe(true); const retrievedDriver = result.unwrap(); expect(retrievedDriver).toBeDefined(); expect(retrievedDriver.id).toBe(driverId); expect(retrievedDriver.bio).toBeUndefined(); }); it('should handle driver with no avatar', async () => { // Scenario: Driver with no avatar // Given: A driver exists const driverId = 'driver-no-avatar'; const driver = Driver.create({ id: driverId, iracingId: '44444', name: 'No Avatar Driver', country: 'ES', }); await driverRepository.create(driver); // When: GetDriverUseCase.execute() is called with driver ID const result = await getDriverUseCase.execute({ driverId }); // Then: The result should contain driver profile expect(result.isOk()).toBe(true); const retrievedDriver = result.unwrap(); expect(retrievedDriver).toBeDefined(); expect(retrievedDriver.id).toBe(driverId); expect(retrievedDriver.avatarRef).toBeDefined(); }); it('should handle driver with no data at all', async () => { // Scenario: Driver with absolutely no data // Given: A driver exists with only required fields const driverId = 'driver-minimal'; const driver = Driver.create({ id: driverId, iracingId: '55555', name: 'Minimal Driver', country: 'IT', }); await driverRepository.create(driver); // When: GetDriverUseCase.execute() is called with driver ID const result = await getDriverUseCase.execute({ driverId }); // Then: The result should contain basic driver info expect(result.isOk()).toBe(true); const retrievedDriver = result.unwrap(); expect(retrievedDriver).toBeDefined(); expect(retrievedDriver.id).toBe(driverId); expect(retrievedDriver.iracingId.toString()).toBe('55555'); expect(retrievedDriver.name.toString()).toBe('Minimal Driver'); expect(retrievedDriver.country.toString()).toBe('IT'); expect(retrievedDriver.bio).toBeUndefined(); expect(retrievedDriver.avatarRef).toBeDefined(); }); }); describe('GetDriverUseCase - Error Handling', () => { it('should return null when driver does not exist', async () => { // Scenario: Non-existent driver // Given: No driver exists with the given ID const driverId = 'non-existent-driver'; // When: GetDriverUseCase.execute() is called with non-existent driver ID const result = await getDriverUseCase.execute({ driverId }); // Then: The result should be null expect(result.isOk()).toBe(true); expect(result.unwrap()).toBeNull(); }); it('should handle repository errors gracefully', async () => { // Scenario: Repository throws error // Given: A driver exists const driverId = 'driver-error'; const driver = Driver.create({ id: driverId, iracingId: '66666', name: 'Error Driver', country: 'US', }); await driverRepository.create(driver); // Mock the repository to throw an error const originalFindById = driverRepository.findById.bind(driverRepository); driverRepository.findById = async () => { throw new Error('Repository error'); }; // When: GetDriverUseCase.execute() is called const result = await getDriverUseCase.execute({ driverId }); // Then: Should propagate the error appropriately expect(result.isErr()).toBe(true); const error = result.unwrapErr(); expect(error.message).toBe('Repository error'); // Restore original method driverRepository.findById = originalFindById; }); }); describe('GetDriverUseCase - Data Orchestration', () => { it('should correctly retrieve driver with all fields populated', async () => { // Scenario: Driver with all fields populated // Given: A driver exists with all possible fields const driverId = 'driver-complete'; const driver = Driver.create({ id: driverId, iracingId: '77777', name: 'Complete Driver', country: 'US', bio: 'Complete driver profile with all fields', avatarRef: MediaReference.createUploaded('avatar-complete'), category: 'pro', }); await driverRepository.create(driver); // When: GetDriverUseCase.execute() is called const result = await getDriverUseCase.execute({ driverId }); // Then: All fields should be correctly retrieved expect(result.isOk()).toBe(true); const retrievedDriver = result.unwrap(); expect(retrievedDriver.id).toBe(driverId); expect(retrievedDriver.iracingId.toString()).toBe('77777'); expect(retrievedDriver.name.toString()).toBe('Complete Driver'); expect(retrievedDriver.country.toString()).toBe('US'); expect(retrievedDriver.bio?.toString()).toBe('Complete driver profile with all fields'); expect(retrievedDriver.avatarRef).toBeDefined(); expect(retrievedDriver.category).toBe('pro'); }); it('should correctly retrieve driver with system-default avatar', async () => { // Scenario: Driver with system-default avatar // Given: A driver exists with system-default avatar const driverId = 'driver-system-avatar'; const driver = Driver.create({ id: driverId, iracingId: '88888', name: 'System Avatar Driver', country: 'US', avatarRef: MediaReference.createSystemDefault('avatar'), }); await driverRepository.create(driver); // When: GetDriverUseCase.execute() is called const result = await getDriverUseCase.execute({ driverId }); // Then: The avatar reference should be correctly retrieved expect(result.isOk()).toBe(true); const retrievedDriver = result.unwrap(); expect(retrievedDriver.avatarRef).toBeDefined(); expect(retrievedDriver.avatarRef.type).toBe('system_default'); }); it('should correctly retrieve driver with generated avatar', async () => { // Scenario: Driver with generated avatar // Given: A driver exists with generated avatar const driverId = 'driver-generated-avatar'; const driver = Driver.create({ id: driverId, iracingId: '99999', name: 'Generated Avatar Driver', country: 'US', avatarRef: MediaReference.createGenerated('gen-123'), }); await driverRepository.create(driver); // When: GetDriverUseCase.execute() is called const result = await getDriverUseCase.execute({ driverId }); // Then: The avatar reference should be correctly retrieved expect(result.isOk()).toBe(true); const retrievedDriver = result.unwrap(); expect(retrievedDriver.avatarRef).toBeDefined(); expect(retrievedDriver.avatarRef.type).toBe('generated'); }); }); });