154 lines
5.1 KiB
TypeScript
154 lines
5.1 KiB
TypeScript
/**
|
|
* Integration Test: Onboarding Wizard Use Case Orchestration
|
|
*
|
|
* Tests the orchestration logic of onboarding wizard-related Use Cases:
|
|
* - CompleteDriverOnboardingUseCase: Orchestrates the driver creation flow
|
|
*
|
|
* 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 { CompleteDriverOnboardingUseCase } from '../../../core/racing/application/use-cases/CompleteDriverOnboardingUseCase';
|
|
import { Logger } from '../../../core/shared/domain/Logger';
|
|
|
|
describe('Onboarding Wizard Use Case Orchestration', () => {
|
|
let driverRepository: InMemoryDriverRepository;
|
|
let completeDriverOnboardingUseCase: CompleteDriverOnboardingUseCase;
|
|
let mockLogger: Logger;
|
|
|
|
beforeAll(() => {
|
|
mockLogger = {
|
|
info: () => {},
|
|
debug: () => {},
|
|
warn: () => {},
|
|
error: () => {},
|
|
} as unknown as Logger;
|
|
|
|
driverRepository = new InMemoryDriverRepository(mockLogger);
|
|
completeDriverOnboardingUseCase = new CompleteDriverOnboardingUseCase(
|
|
driverRepository,
|
|
mockLogger
|
|
);
|
|
});
|
|
|
|
beforeEach(async () => {
|
|
await driverRepository.clear();
|
|
});
|
|
|
|
describe('CompleteDriverOnboardingUseCase - Success Path', () => {
|
|
it('should complete onboarding with valid personal info', async () => {
|
|
// Scenario: Complete onboarding successfully
|
|
// Given: A new user ID
|
|
const userId = 'user-123';
|
|
const input = {
|
|
userId,
|
|
firstName: 'John',
|
|
lastName: 'Doe',
|
|
displayName: 'RacerJohn',
|
|
country: 'US',
|
|
bio: 'New racer on the grid',
|
|
};
|
|
|
|
// When: CompleteDriverOnboardingUseCase.execute() is called
|
|
const result = await completeDriverOnboardingUseCase.execute(input);
|
|
|
|
// Then: Driver should be created
|
|
expect(result.isOk()).toBe(true);
|
|
const { driver } = result.unwrap();
|
|
expect(driver.id).toBe(userId);
|
|
expect(driver.name.toString()).toBe('RacerJohn');
|
|
expect(driver.country.toString()).toBe('US');
|
|
expect(driver.bio?.toString()).toBe('New racer on the grid');
|
|
|
|
// And: Repository should contain the driver
|
|
const savedDriver = await driverRepository.findById(userId);
|
|
expect(savedDriver).not.toBeNull();
|
|
expect(savedDriver?.id).toBe(userId);
|
|
});
|
|
|
|
it('should complete onboarding with minimal required data', async () => {
|
|
// Scenario: Complete onboarding with minimal data
|
|
// Given: A new user ID
|
|
const userId = 'user-456';
|
|
const input = {
|
|
userId,
|
|
firstName: 'Jane',
|
|
lastName: 'Smith',
|
|
displayName: 'JaneS',
|
|
country: 'UK',
|
|
};
|
|
|
|
// When: CompleteDriverOnboardingUseCase.execute() is called
|
|
const result = await completeDriverOnboardingUseCase.execute(input);
|
|
|
|
// Then: Driver should be created successfully
|
|
expect(result.isOk()).toBe(true);
|
|
const { driver } = result.unwrap();
|
|
expect(driver.id).toBe(userId);
|
|
expect(driver.bio).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe('CompleteDriverOnboardingUseCase - Validation & Errors', () => {
|
|
it('should reject onboarding if driver already exists', async () => {
|
|
// Scenario: Already onboarded user
|
|
// Given: A driver already exists for the user
|
|
const userId = 'existing-user';
|
|
const existingInput = {
|
|
userId,
|
|
firstName: 'Old',
|
|
lastName: 'Name',
|
|
displayName: 'OldRacer',
|
|
country: 'DE',
|
|
};
|
|
await completeDriverOnboardingUseCase.execute(existingInput);
|
|
|
|
// When: CompleteDriverOnboardingUseCase.execute() is called again for same user
|
|
const result = await completeDriverOnboardingUseCase.execute({
|
|
userId,
|
|
firstName: 'New',
|
|
lastName: 'Name',
|
|
displayName: 'NewRacer',
|
|
country: 'FR',
|
|
});
|
|
|
|
// Then: Should return DRIVER_ALREADY_EXISTS error
|
|
expect(result.isErr()).toBe(true);
|
|
const error = result.unwrapErr();
|
|
expect(error.code).toBe('DRIVER_ALREADY_EXISTS');
|
|
});
|
|
|
|
it('should handle repository errors gracefully', async () => {
|
|
// Scenario: Repository error
|
|
// Given: Repository throws an error
|
|
const userId = 'error-user';
|
|
const originalCreate = driverRepository.create.bind(driverRepository);
|
|
driverRepository.create = async () => {
|
|
throw new Error('Database failure');
|
|
};
|
|
|
|
// When: CompleteDriverOnboardingUseCase.execute() is called
|
|
const result = await completeDriverOnboardingUseCase.execute({
|
|
userId,
|
|
firstName: 'John',
|
|
lastName: 'Doe',
|
|
displayName: 'RacerJohn',
|
|
country: 'US',
|
|
});
|
|
|
|
// Then: Should return REPOSITORY_ERROR
|
|
expect(result.isErr()).toBe(true);
|
|
const error = result.unwrapErr();
|
|
expect(error.code).toBe('REPOSITORY_ERROR');
|
|
expect(error.details.message).toBe('Database failure');
|
|
|
|
// Restore
|
|
driverRepository.create = originalCreate;
|
|
});
|
|
});
|
|
});
|