import { describe, expect, it, beforeEach } from 'vitest'; import { CreatePaymentPresenter } from './CreatePaymentPresenter'; import { PaymentType, PayerType, PaymentStatus } from '@core/payments/domain/entities/Payment'; describe('CreatePaymentPresenter', () => { let presenter: CreatePaymentPresenter; beforeEach(() => { presenter = new CreatePaymentPresenter(); }); describe('present', () => { it('should map result to response model', () => { const result = { payment: { id: 'payment-123', type: PaymentType.MEMBERSHIP_FEE, amount: 100, platformFee: 5, netAmount: 95, payerId: 'user-123', payerType: PayerType.DRIVER, leagueId: 'league-123', status: PaymentStatus.PENDING, createdAt: new Date('2024-01-01'), }, }; presenter.present(result); const responseModel = presenter.getResponseModel(); expect(responseModel).toEqual({ payment: { id: 'payment-123', type: PaymentType.MEMBERSHIP_FEE, amount: 100, platformFee: 5, netAmount: 95, payerId: 'user-123', payerType: PayerType.DRIVER, leagueId: 'league-123', status: PaymentStatus.PENDING, createdAt: new Date('2024-01-01'), }, }); }); it('should include seasonId when provided', () => { const result = { payment: { id: 'payment-123', type: PaymentType.MEMBERSHIP_FEE, amount: 100, platformFee: 5, netAmount: 95, payerId: 'user-123', payerType: PayerType.DRIVER, leagueId: 'league-123', seasonId: 'season-123', status: PaymentStatus.PENDING, createdAt: new Date('2024-01-01'), }, }; presenter.present(result); const responseModel = presenter.getResponseModel(); expect(responseModel.payment.seasonId).toBe('season-123'); }); it('should include completedAt when provided', () => { const result = { payment: { id: 'payment-123', type: PaymentType.MEMBERSHIP_FEE, amount: 100, platformFee: 5, netAmount: 95, payerId: 'user-123', payerType: PayerType.DRIVER, leagueId: 'league-123', status: PaymentStatus.COMPLETED, createdAt: new Date('2024-01-01'), completedAt: new Date('2024-01-02'), }, }; presenter.present(result); const responseModel = presenter.getResponseModel(); expect(responseModel.payment.completedAt).toEqual(new Date('2024-01-02')); }); it('should not include seasonId when not provided', () => { const result = { payment: { id: 'payment-123', type: PaymentType.MEMBERSHIP_FEE, amount: 100, platformFee: 5, netAmount: 95, payerId: 'user-123', payerType: PayerType.DRIVER, leagueId: 'league-123', status: PaymentStatus.PENDING, createdAt: new Date('2024-01-01'), }, }; presenter.present(result); const responseModel = presenter.getResponseModel(); expect(responseModel.payment.seasonId).toBeUndefined(); }); it('should not include completedAt when not provided', () => { const result = { payment: { id: 'payment-123', type: PaymentType.MEMBERSHIP_FEE, amount: 100, platformFee: 5, netAmount: 95, payerId: 'user-123', payerType: PayerType.DRIVER, leagueId: 'league-123', status: PaymentStatus.PENDING, createdAt: new Date('2024-01-01'), }, }; presenter.present(result); const responseModel = presenter.getResponseModel(); expect(responseModel.payment.completedAt).toBeUndefined(); }); }); describe('getResponseModel', () => { it('should throw error when accessed before present()', () => { expect(() => presenter.getResponseModel()).toThrow('Presenter not presented'); }); it('should return model after present()', () => { const result = { payment: { id: 'payment-123', type: PaymentType.MEMBERSHIP_FEE, amount: 100, platformFee: 5, netAmount: 95, payerId: 'user-123', payerType: PayerType.DRIVER, leagueId: 'league-123', status: PaymentStatus.PENDING, createdAt: new Date('2024-01-01'), }, }; presenter.present(result); const responseModel = presenter.getResponseModel(); expect(responseModel).toBeDefined(); expect(responseModel.payment.id).toBe('payment-123'); }); }); describe('reset', () => { it('should clear the response model', () => { const result = { payment: { id: 'payment-123', type: PaymentType.MEMBERSHIP_FEE, amount: 100, platformFee: 5, netAmount: 95, payerId: 'user-123', payerType: PayerType.DRIVER, leagueId: 'league-123', status: PaymentStatus.PENDING, createdAt: new Date('2024-01-01'), }, }; presenter.present(result); presenter.reset(); expect(() => presenter.getResponseModel()).toThrow('Presenter not presented'); }); it('should allow presenting again after reset', () => { const firstResult = { payment: { id: 'payment-123', type: PaymentType.MEMBERSHIP_FEE, amount: 100, platformFee: 5, netAmount: 95, payerId: 'user-123', payerType: PayerType.DRIVER, leagueId: 'league-123', status: PaymentStatus.PENDING, createdAt: new Date('2024-01-01'), }, }; const secondResult = { payment: { id: 'payment-456', type: PaymentType.MEMBERSHIP_FEE, amount: 200, platformFee: 10, netAmount: 190, payerId: 'user-456', payerType: PayerType.DRIVER, leagueId: 'league-456', status: PaymentStatus.PENDING, createdAt: new Date('2024-01-02'), }, }; presenter.present(firstResult); presenter.reset(); presenter.present(secondResult); const responseModel = presenter.getResponseModel(); expect(responseModel.payment.id).toBe('payment-456'); }); }); });