244 lines
7.1 KiB
TypeScript
244 lines
7.1 KiB
TypeScript
import { describe, it, expect, vi, Mocked } from 'vitest';
|
|
import { PaymentService } from './PaymentService';
|
|
import { PaymentsApiClient } from '@/lib/api/payments/PaymentsApiClient';
|
|
import { PaymentViewModel, MembershipFeeViewModel, PrizeViewModel, WalletViewModel } from '../../view-models';
|
|
|
|
describe('PaymentService', () => {
|
|
let mockApiClient: Mocked<PaymentsApiClient>;
|
|
let service: PaymentService;
|
|
|
|
beforeEach(() => {
|
|
mockApiClient = {
|
|
getPayments: vi.fn(),
|
|
createPayment: vi.fn(),
|
|
getMembershipFees: vi.fn(),
|
|
getPrizes: vi.fn(),
|
|
getWallet: vi.fn(),
|
|
} as Mocked<PaymentsApiClient>;
|
|
|
|
service = new PaymentService(mockApiClient);
|
|
});
|
|
|
|
describe('getPayments', () => {
|
|
it('should call apiClient.getPayments and return PaymentViewModel array', async () => {
|
|
const mockResponse = {
|
|
payments: [
|
|
{
|
|
id: 'payment-1',
|
|
type: 'sponsorship' as const,
|
|
amount: 100,
|
|
platformFee: 10,
|
|
netAmount: 90,
|
|
payerId: 'user-1',
|
|
payerType: 'sponsor' as const,
|
|
leagueId: 'league-1',
|
|
status: 'completed' as const,
|
|
createdAt: new Date(),
|
|
},
|
|
],
|
|
};
|
|
|
|
mockApiClient.getPayments.mockResolvedValue(mockResponse);
|
|
|
|
const result = await service.getPayments();
|
|
|
|
expect(mockApiClient.getPayments).toHaveBeenCalledWith(undefined);
|
|
expect(result).toHaveLength(1);
|
|
expect(result[0]).toBeInstanceOf(PaymentViewModel);
|
|
expect(result[0].id).toBe('payment-1');
|
|
});
|
|
|
|
it('should call apiClient.getPayments with filters', async () => {
|
|
const mockResponse = { payments: [] };
|
|
mockApiClient.getPayments.mockResolvedValue(mockResponse);
|
|
|
|
await service.getPayments('league-1', 'user-1');
|
|
|
|
expect(mockApiClient.getPayments).toHaveBeenCalledWith({ leagueId: 'league-1', payerId: 'user-1' });
|
|
});
|
|
});
|
|
|
|
describe('getPayment', () => {
|
|
it('should return PaymentViewModel when payment exists', async () => {
|
|
const mockResponse = {
|
|
payments: [
|
|
{
|
|
id: 'payment-1',
|
|
type: 'sponsorship' as const,
|
|
amount: 100,
|
|
platformFee: 10,
|
|
netAmount: 90,
|
|
payerId: 'user-1',
|
|
payerType: 'sponsor' as const,
|
|
leagueId: 'league-1',
|
|
status: 'completed' as const,
|
|
createdAt: new Date(),
|
|
},
|
|
],
|
|
};
|
|
|
|
mockApiClient.getPayments.mockResolvedValue(mockResponse);
|
|
|
|
const result = await service.getPayment('payment-1');
|
|
|
|
expect(result).toBeInstanceOf(PaymentViewModel);
|
|
expect(result.id).toBe('payment-1');
|
|
});
|
|
|
|
it('should throw error when payment does not exist', async () => {
|
|
const mockResponse = { payments: [] };
|
|
mockApiClient.getPayments.mockResolvedValue(mockResponse);
|
|
|
|
await expect(service.getPayment('non-existent')).rejects.toThrow(
|
|
'Payment with ID non-existent not found'
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('createPayment', () => {
|
|
it('should call apiClient.createPayment and return PaymentViewModel', async () => {
|
|
const input = {
|
|
type: 'sponsorship' as const,
|
|
amount: 100,
|
|
payerId: 'user-1',
|
|
payerType: 'sponsor' as const,
|
|
leagueId: 'league-1',
|
|
};
|
|
|
|
const mockResponse = {
|
|
payment: {
|
|
id: 'payment-1',
|
|
type: 'sponsorship' as const,
|
|
amount: 100,
|
|
platformFee: 10,
|
|
netAmount: 90,
|
|
payerId: 'user-1',
|
|
payerType: 'sponsor' as const,
|
|
leagueId: 'league-1',
|
|
status: 'pending' as const,
|
|
createdAt: new Date(),
|
|
},
|
|
};
|
|
|
|
mockApiClient.createPayment.mockResolvedValue(mockResponse);
|
|
|
|
const result = await service.createPayment(input);
|
|
|
|
expect(mockApiClient.createPayment).toHaveBeenCalledWith(input);
|
|
expect(result).toBeInstanceOf(PaymentViewModel);
|
|
expect(result.id).toBe('payment-1');
|
|
});
|
|
});
|
|
|
|
describe('getMembershipFees', () => {
|
|
it('should return MembershipFeeViewModel when fee exists', async () => {
|
|
const mockResponse = {
|
|
fee: {
|
|
id: 'fee-1',
|
|
leagueId: 'league-1',
|
|
type: 'season' as const,
|
|
amount: 50,
|
|
enabled: true,
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
},
|
|
payments: [],
|
|
};
|
|
|
|
mockApiClient.getMembershipFees.mockResolvedValue(mockResponse);
|
|
|
|
const result = await service.getMembershipFees('league-1');
|
|
|
|
expect(result).toBeInstanceOf(MembershipFeeViewModel);
|
|
expect(result!.id).toBe('fee-1');
|
|
});
|
|
|
|
it('should return null when fee does not exist', async () => {
|
|
const mockResponse = {
|
|
fee: null,
|
|
payments: [],
|
|
};
|
|
|
|
mockApiClient.getMembershipFees.mockResolvedValue(mockResponse);
|
|
|
|
const result = await service.getMembershipFees('league-1');
|
|
|
|
expect(result).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('getPrizes', () => {
|
|
it('should call apiClient.getPrizes and return PrizeViewModel array', async () => {
|
|
const mockResponse = {
|
|
prizes: [
|
|
{
|
|
id: 'prize-1',
|
|
leagueId: 'league-1',
|
|
seasonId: 'season-1',
|
|
position: 1,
|
|
name: 'First Place',
|
|
amount: 100,
|
|
type: 'cash' as const,
|
|
awarded: false,
|
|
createdAt: new Date(),
|
|
},
|
|
],
|
|
};
|
|
|
|
mockApiClient.getPrizes.mockResolvedValue(mockResponse);
|
|
|
|
const result = await service.getPrizes();
|
|
|
|
expect(mockApiClient.getPrizes).toHaveBeenCalledWith(undefined);
|
|
expect(result).toHaveLength(1);
|
|
expect(result[0]).toBeInstanceOf(PrizeViewModel);
|
|
expect(result[0].id).toBe('prize-1');
|
|
});
|
|
|
|
it('should call apiClient.getPrizes with filters', async () => {
|
|
const mockResponse = { prizes: [] };
|
|
mockApiClient.getPrizes.mockResolvedValue(mockResponse);
|
|
|
|
await service.getPrizes('league-1', 'season-1');
|
|
|
|
expect(mockApiClient.getPrizes).toHaveBeenCalledWith({ leagueId: 'league-1', seasonId: 'season-1' });
|
|
});
|
|
});
|
|
|
|
describe('getWallet', () => {
|
|
it('should call apiClient.getWallet and return WalletViewModel', async () => {
|
|
const mockResponse = {
|
|
wallet: {
|
|
id: 'wallet-1',
|
|
leagueId: 'league-1',
|
|
balance: 1000,
|
|
totalRevenue: 1500,
|
|
totalPlatformFees: 100,
|
|
totalWithdrawn: 400,
|
|
createdAt: new Date(),
|
|
currency: 'EUR',
|
|
},
|
|
transactions: [
|
|
{
|
|
id: 'tx-1',
|
|
walletId: 'wallet-1',
|
|
type: 'deposit' as const,
|
|
amount: 500,
|
|
description: 'Deposit',
|
|
createdAt: new Date(),
|
|
},
|
|
],
|
|
};
|
|
|
|
mockApiClient.getWallet.mockResolvedValue(mockResponse);
|
|
|
|
const result = await service.getWallet('league-1');
|
|
|
|
expect(mockApiClient.getWallet).toHaveBeenCalledWith({ leagueId: 'league-1' });
|
|
expect(result).toBeInstanceOf(WalletViewModel);
|
|
expect(result.id).toBe('wallet-1');
|
|
expect(result.balance).toBe(1000);
|
|
expect(result.transactions).toHaveLength(1);
|
|
});
|
|
});
|
|
}); |