add tests to core
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
import { beforeEach, describe, expect, it, vi, type Mock } from 'vitest';
|
||||
import { UpdatePaymentStatusUseCase, type UpdatePaymentStatusInput } from './UpdatePaymentStatusUseCase';
|
||||
import type { IPaymentRepository } from '../../domain/repositories/IPaymentRepository';
|
||||
import { PaymentStatus, PaymentType, PayerType, type Payment } from '../../domain/entities/Payment';
|
||||
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
|
||||
|
||||
describe('UpdatePaymentStatusUseCase', () => {
|
||||
let paymentRepository: {
|
||||
findById: Mock;
|
||||
update: Mock;
|
||||
};
|
||||
|
||||
let output: {
|
||||
present: Mock;
|
||||
};
|
||||
|
||||
let useCase: UpdatePaymentStatusUseCase;
|
||||
|
||||
beforeEach(() => {
|
||||
paymentRepository = {
|
||||
findById: vi.fn(),
|
||||
update: vi.fn(),
|
||||
};
|
||||
|
||||
output = {
|
||||
present: vi.fn(),
|
||||
};
|
||||
|
||||
useCase = new UpdatePaymentStatusUseCase(
|
||||
paymentRepository as unknown as IPaymentRepository,
|
||||
output as unknown as UseCaseOutputPort<unknown>,
|
||||
);
|
||||
});
|
||||
|
||||
it('returns PAYMENT_NOT_FOUND when payment does not exist', async () => {
|
||||
const input: UpdatePaymentStatusInput = {
|
||||
paymentId: 'payment-1',
|
||||
status: PaymentStatus.COMPLETED,
|
||||
};
|
||||
|
||||
paymentRepository.findById.mockResolvedValue(null);
|
||||
|
||||
const result = await useCase.execute(input);
|
||||
|
||||
expect(result.isErr()).toBe(true);
|
||||
expect(result.unwrapErr().code).toBe('PAYMENT_NOT_FOUND');
|
||||
expect(paymentRepository.update).not.toHaveBeenCalled();
|
||||
expect(output.present).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('sets completedAt when status becomes COMPLETED', async () => {
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date('2025-01-01T00:00:00.000Z'));
|
||||
|
||||
try {
|
||||
const input: UpdatePaymentStatusInput = {
|
||||
paymentId: 'payment-1',
|
||||
status: PaymentStatus.COMPLETED,
|
||||
};
|
||||
|
||||
const existingPayment: Payment = {
|
||||
id: 'payment-1',
|
||||
type: PaymentType.SPONSORSHIP,
|
||||
amount: 100,
|
||||
platformFee: 5,
|
||||
netAmount: 95,
|
||||
payerId: 'payer-1',
|
||||
payerType: PayerType.SPONSOR,
|
||||
leagueId: 'league-1',
|
||||
status: PaymentStatus.PENDING,
|
||||
createdAt: new Date('2024-12-31T00:00:00.000Z'),
|
||||
};
|
||||
|
||||
paymentRepository.findById.mockResolvedValue(existingPayment);
|
||||
paymentRepository.update.mockImplementation(async (p: Payment) => ({ ...p }));
|
||||
|
||||
const result = await useCase.execute(input);
|
||||
|
||||
expect(result.isOk()).toBe(true);
|
||||
|
||||
expect(paymentRepository.update).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
id: 'payment-1',
|
||||
status: PaymentStatus.COMPLETED,
|
||||
completedAt: new Date('2025-01-01T00:00:00.000Z'),
|
||||
}),
|
||||
);
|
||||
|
||||
const savedPayment = paymentRepository.update.mock.results[0]?.value;
|
||||
await expect(savedPayment).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
id: 'payment-1',
|
||||
status: PaymentStatus.COMPLETED,
|
||||
completedAt: new Date('2025-01-01T00:00:00.000Z'),
|
||||
}),
|
||||
);
|
||||
|
||||
const presentedPayment = (output.present.mock.calls[0]?.[0] as { payment: Payment }).payment;
|
||||
expect(presentedPayment.status).toBe(PaymentStatus.COMPLETED);
|
||||
expect(presentedPayment.completedAt).toEqual(new Date('2025-01-01T00:00:00.000Z'));
|
||||
} finally {
|
||||
vi.useRealTimers();
|
||||
}
|
||||
});
|
||||
|
||||
it('preserves completedAt when status is not COMPLETED', async () => {
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date('2026-01-01T00:00:00.000Z'));
|
||||
|
||||
try {
|
||||
const input: UpdatePaymentStatusInput = {
|
||||
paymentId: 'payment-1',
|
||||
status: PaymentStatus.FAILED,
|
||||
};
|
||||
|
||||
const existingCompletedAt = new Date('2025-01-01T00:00:00.000Z');
|
||||
|
||||
const existingPayment: Payment = {
|
||||
id: 'payment-1',
|
||||
type: PaymentType.SPONSORSHIP,
|
||||
amount: 100,
|
||||
platformFee: 5,
|
||||
netAmount: 95,
|
||||
payerId: 'payer-1',
|
||||
payerType: PayerType.SPONSOR,
|
||||
leagueId: 'league-1',
|
||||
status: PaymentStatus.COMPLETED,
|
||||
createdAt: new Date('2024-12-31T00:00:00.000Z'),
|
||||
completedAt: existingCompletedAt,
|
||||
};
|
||||
|
||||
paymentRepository.findById.mockResolvedValue(existingPayment);
|
||||
paymentRepository.update.mockImplementation(async (p: Payment) => ({ ...p }));
|
||||
|
||||
const result = await useCase.execute(input);
|
||||
|
||||
expect(result.isOk()).toBe(true);
|
||||
|
||||
expect(paymentRepository.update).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
id: 'payment-1',
|
||||
status: PaymentStatus.FAILED,
|
||||
completedAt: existingCompletedAt,
|
||||
}),
|
||||
);
|
||||
|
||||
const presentedPayment = (output.present.mock.calls[0]?.[0] as { payment: Payment }).payment;
|
||||
expect(presentedPayment.status).toBe(PaymentStatus.FAILED);
|
||||
expect(presentedPayment.completedAt).toEqual(existingCompletedAt);
|
||||
} finally {
|
||||
vi.useRealTimers();
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user