resolve todos in core
This commit is contained in:
163
core/racing/application/use-cases/GetLeagueWalletUseCase.test.ts
Normal file
163
core/racing/application/use-cases/GetLeagueWalletUseCase.test.ts
Normal file
@@ -0,0 +1,163 @@
|
||||
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
|
||||
import { GetLeagueWalletUseCase } from './GetLeagueWalletUseCase';
|
||||
import type { ILeagueWalletRepository } from '../../domain/repositories/ILeagueWalletRepository';
|
||||
import type { ITransactionRepository } from '../../domain/repositories/ITransactionRepository';
|
||||
import { LeagueWallet } from '../../domain/entities/league-wallet/LeagueWallet';
|
||||
import { Money } from '../../domain/value-objects/Money';
|
||||
import { Transaction } from '../../domain/entities/league-wallet/Transaction';
|
||||
import { TransactionId } from '../../domain/entities/league-wallet/TransactionId';
|
||||
import { LeagueWalletId } from '../../domain/entities/league-wallet/LeagueWalletId';
|
||||
|
||||
describe('GetLeagueWalletUseCase', () => {
|
||||
let leagueWalletRepository: {
|
||||
findByLeagueId: Mock;
|
||||
};
|
||||
let transactionRepository: {
|
||||
findByWalletId: Mock;
|
||||
};
|
||||
let useCase: GetLeagueWalletUseCase;
|
||||
|
||||
beforeEach(() => {
|
||||
leagueWalletRepository = {
|
||||
findByLeagueId: vi.fn(),
|
||||
};
|
||||
|
||||
transactionRepository = {
|
||||
findByWalletId: vi.fn(),
|
||||
};
|
||||
|
||||
useCase = new GetLeagueWalletUseCase(
|
||||
leagueWalletRepository as unknown as ILeagueWalletRepository,
|
||||
transactionRepository as unknown as ITransactionRepository,
|
||||
);
|
||||
});
|
||||
|
||||
it('returns mapped wallet data when wallet exists', async () => {
|
||||
const leagueId = 'league-1';
|
||||
|
||||
const balance = Money.create(2450, 'USD');
|
||||
const wallet = LeagueWallet.create({
|
||||
id: 'wallet-1',
|
||||
leagueId,
|
||||
balance,
|
||||
});
|
||||
|
||||
leagueWalletRepository.findByLeagueId.mockResolvedValue(wallet);
|
||||
|
||||
const sponsorshipTx = Transaction.create({
|
||||
id: TransactionId.create('txn-1'),
|
||||
walletId: LeagueWalletId.create(wallet.id.toString()),
|
||||
type: 'sponsorship_payment',
|
||||
amount: Money.create(1200, 'USD'),
|
||||
description: 'Main Sponsor - TechCorp',
|
||||
metadata: {},
|
||||
}).complete();
|
||||
|
||||
const membershipTx = Transaction.create({
|
||||
id: TransactionId.create('txn-2'),
|
||||
walletId: LeagueWalletId.create(wallet.id.toString()),
|
||||
type: 'membership_payment',
|
||||
amount: Money.create(1600, 'USD'),
|
||||
description: 'Season Fee - 32 drivers',
|
||||
metadata: {},
|
||||
}).complete();
|
||||
|
||||
const withdrawalTx = Transaction.create({
|
||||
id: TransactionId.create('txn-3'),
|
||||
walletId: LeagueWalletId.create(wallet.id.toString()),
|
||||
type: 'withdrawal',
|
||||
amount: Money.create(430, 'USD'),
|
||||
description: 'Bank Transfer - Season 1 Payout',
|
||||
metadata: {},
|
||||
}).complete();
|
||||
|
||||
const pendingPrizeTx = Transaction.create({
|
||||
id: TransactionId.create('txn-4'),
|
||||
walletId: LeagueWalletId.create(wallet.id.toString()),
|
||||
type: 'prize_payout',
|
||||
amount: Money.create(150, 'USD'),
|
||||
description: 'Championship Prize Pool (reserved)',
|
||||
metadata: {},
|
||||
});
|
||||
|
||||
const refundTx = Transaction.create({
|
||||
id: TransactionId.create('txn-5'),
|
||||
walletId: LeagueWalletId.create(wallet.id.toString()),
|
||||
type: 'refund',
|
||||
amount: Money.create(100, 'USD'),
|
||||
description: 'Refund for cancelled sponsorship',
|
||||
metadata: {},
|
||||
});
|
||||
|
||||
const transactions = [
|
||||
sponsorshipTx,
|
||||
membershipTx,
|
||||
withdrawalTx,
|
||||
pendingPrizeTx,
|
||||
refundTx,
|
||||
];
|
||||
|
||||
transactionRepository.findByWalletId.mockResolvedValue(transactions);
|
||||
|
||||
const result = await useCase.execute({ leagueId });
|
||||
|
||||
expect(result.isOk()).toBe(true);
|
||||
const viewModel = result.unwrap();
|
||||
|
||||
expect(viewModel.balance).toBe(balance.amount);
|
||||
expect(viewModel.currency).toBe(balance.currency);
|
||||
|
||||
const expectedTotalRevenue =
|
||||
sponsorshipTx.amount.amount +
|
||||
membershipTx.amount.amount +
|
||||
pendingPrizeTx.amount.amount;
|
||||
|
||||
const expectedTotalFees =
|
||||
sponsorshipTx.platformFee.amount +
|
||||
membershipTx.platformFee.amount +
|
||||
pendingPrizeTx.platformFee.amount;
|
||||
|
||||
const expectedTotalWithdrawals = withdrawalTx.netAmount.amount;
|
||||
const expectedPendingPayouts = pendingPrizeTx.netAmount.amount;
|
||||
|
||||
expect(viewModel.totalRevenue).toBe(expectedTotalRevenue);
|
||||
expect(viewModel.totalFees).toBe(expectedTotalFees);
|
||||
expect(viewModel.totalWithdrawals).toBe(expectedTotalWithdrawals);
|
||||
expect(viewModel.pendingPayouts).toBe(expectedPendingPayouts);
|
||||
|
||||
expect(viewModel.transactions).toHaveLength(transactions.length);
|
||||
expect(viewModel.transactions[0]!.id).toBe(transactions.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())[0]!.id.toString());
|
||||
expect(viewModel.transactions.find(t => t.type === 'sponsorship')).toBeTruthy();
|
||||
expect(viewModel.transactions.find(t => t.type === 'membership')).toBeTruthy();
|
||||
expect(viewModel.transactions.find(t => t.type === 'withdrawal')).toBeTruthy();
|
||||
expect(viewModel.transactions.find(t => t.type === 'prize')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('returns error result when wallet is missing', async () => {
|
||||
const leagueId = 'league-missing';
|
||||
|
||||
leagueWalletRepository.findByLeagueId.mockResolvedValue(null);
|
||||
|
||||
const result = await useCase.execute({ leagueId });
|
||||
|
||||
expect(result.isErr()).toBe(true);
|
||||
expect(result.unwrapErr()).toEqual({
|
||||
code: 'REPOSITORY_ERROR',
|
||||
message: 'Wallet not found',
|
||||
});
|
||||
});
|
||||
|
||||
it('returns repository error when repository throws', async () => {
|
||||
const leagueId = 'league-1';
|
||||
|
||||
leagueWalletRepository.findByLeagueId.mockRejectedValue(new Error('DB error'));
|
||||
|
||||
const result = await useCase.execute({ leagueId });
|
||||
|
||||
expect(result.isErr()).toBe(true);
|
||||
expect(result.unwrapErr()).toEqual({
|
||||
code: 'REPOSITORY_ERROR',
|
||||
message: 'Failed to fetch league wallet',
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user