121 lines
4.5 KiB
TypeScript
121 lines
4.5 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import { CompleteRaceCreationUseCase } from '@core/automation/application/use-cases/CompleteRaceCreationUseCase';
|
|
import { Result } from '@core/shared/result/Result';
|
|
import { RaceCreationResult } from '@core/automation/domain/value-objects/RaceCreationResult';
|
|
import { CheckoutPrice } from '@core/automation/domain/value-objects/CheckoutPrice';
|
|
import type { CheckoutServicePort } from '@core/automation/application/ports/CheckoutServicePort';
|
|
import { CheckoutState } from '@core/automation/domain/value-objects/CheckoutState';
|
|
|
|
describe('CompleteRaceCreationUseCase', () => {
|
|
let mockCheckoutService: CheckoutServicePort;
|
|
let useCase: CompleteRaceCreationUseCase;
|
|
|
|
beforeEach(() => {
|
|
mockCheckoutService = {
|
|
extractCheckoutInfo: vi.fn(),
|
|
proceedWithCheckout: vi.fn(),
|
|
};
|
|
|
|
useCase = new CompleteRaceCreationUseCase(mockCheckoutService);
|
|
});
|
|
|
|
describe('execute', () => {
|
|
it('should extract checkout price and create RaceCreationResult', async () => {
|
|
const price = CheckoutPrice.fromString('$25.50');
|
|
const state = CheckoutState.ready();
|
|
const sessionId = 'test-session-123';
|
|
|
|
vi.mocked(mockCheckoutService.extractCheckoutInfo).mockResolvedValue(
|
|
Result.ok({ price, state, buttonHtml: '<a>$25.50</a>' })
|
|
);
|
|
|
|
const result = await useCase.execute(sessionId);
|
|
|
|
expect(mockCheckoutService.extractCheckoutInfo).toHaveBeenCalled();
|
|
expect(result.isOk()).toBe(true);
|
|
|
|
const raceCreationResult = result.unwrap();
|
|
expect(raceCreationResult).toBeInstanceOf(RaceCreationResult);
|
|
expect(raceCreationResult.sessionId).toBe(sessionId);
|
|
expect(raceCreationResult.price).toBe('$25.50');
|
|
expect(raceCreationResult.timestamp).toBeInstanceOf(Date);
|
|
});
|
|
|
|
it('should return error if checkout info extraction fails', async () => {
|
|
vi.mocked(mockCheckoutService.extractCheckoutInfo).mockResolvedValue(
|
|
Result.err(new Error('Failed to extract checkout info'))
|
|
);
|
|
|
|
const result = await useCase.execute('test-session-123');
|
|
|
|
expect(result.isErr()).toBe(true);
|
|
expect(result.unwrapErr().message).toContain('Failed to extract checkout info');
|
|
});
|
|
|
|
it('should return error if price is missing', async () => {
|
|
const state = CheckoutState.ready();
|
|
|
|
vi.mocked(mockCheckoutService.extractCheckoutInfo).mockResolvedValue(
|
|
Result.ok({ price: null, state, buttonHtml: '<a>n/a</a>' })
|
|
);
|
|
|
|
const result = await useCase.execute('test-session-123');
|
|
|
|
expect(result.isErr()).toBe(true);
|
|
expect(result.unwrapErr().message).toContain('Could not extract price');
|
|
});
|
|
|
|
it('should validate session ID is provided', async () => {
|
|
const result = await useCase.execute('');
|
|
|
|
expect(result.isErr()).toBe(true);
|
|
expect(result.unwrapErr().message).toContain('Session ID is required');
|
|
});
|
|
|
|
it('should format different price values correctly', async () => {
|
|
const testCases = [
|
|
{ input: '$10.00', expected: '$10.00' },
|
|
{ input: '$100.50', expected: '$100.50' },
|
|
{ input: '$0.99', expected: '$0.99' },
|
|
];
|
|
|
|
for (const testCase of testCases) {
|
|
const price = CheckoutPrice.fromString(testCase.input);
|
|
const state = CheckoutState.ready();
|
|
|
|
vi.mocked(mockCheckoutService.extractCheckoutInfo).mockResolvedValue(
|
|
Result.ok({ price, state, buttonHtml: `<a>${testCase.input}</a>` })
|
|
);
|
|
|
|
const result = await useCase.execute('test-session');
|
|
expect(result.isOk()).toBe(true);
|
|
|
|
const raceCreationResult = result.unwrap();
|
|
expect(raceCreationResult.price).toBe(testCase.expected);
|
|
}
|
|
});
|
|
|
|
it('should capture current timestamp when creating result', async () => {
|
|
const price = CheckoutPrice.fromString('$25.50');
|
|
const state = CheckoutState.ready();
|
|
const beforeExecution = new Date();
|
|
|
|
vi.mocked(mockCheckoutService.extractCheckoutInfo).mockResolvedValue(
|
|
Result.ok({ price, state, buttonHtml: '<a>$25.50</a>' })
|
|
);
|
|
|
|
const result = await useCase.execute('test-session');
|
|
const afterExecution = new Date();
|
|
|
|
expect(result.isOk()).toBe(true);
|
|
const raceCreationResult = result.unwrap();
|
|
|
|
expect(raceCreationResult.timestamp.getTime()).toBeGreaterThanOrEqual(
|
|
beforeExecution.getTime()
|
|
);
|
|
expect(raceCreationResult.timestamp.getTime()).toBeLessThanOrEqual(
|
|
afterExecution.getTime()
|
|
);
|
|
});
|
|
});
|
|
}); |