Files
gridpilot.gg/core/payments/application/use-cases/GetWalletUseCase.test.ts
2026-01-16 13:48:18 +01:00

133 lines
3.8 KiB
TypeScript

import { beforeEach, describe, expect, it, vi, type Mock } from 'vitest';
import { GetWalletUseCase, type GetWalletInput } from './GetWalletUseCase';
import type { TransactionRepository, IWalletRepository } from '../../domain/repositories/WalletRepository';
import type { Transaction, Wallet } from '../../domain/entities/Wallet';
import { TransactionType } from '../../domain/entities/Wallet';
describe('GetWalletUseCase', () => {
let walletRepository: {
findByLeagueId: Mock;
create: Mock;
};
let transactionRepository: {
findByWalletId: Mock;
};
let useCase: GetWalletUseCase;
beforeEach(() => {
walletRepository = {
findByLeagueId: vi.fn(),
create: vi.fn(),
};
transactionRepository = {
findByWalletId: vi.fn(),
};
useCase = new GetWalletUseCase(
walletRepository as unknown as IWalletRepository,
transactionRepository as unknown as ITransactionRepository,
);
});
it('returns INVALID_INPUT when leagueId is missing', async () => {
const input = { leagueId: '' } as unknown as GetWalletInput;
const result = await useCase.execute(input);
expect(result.isErr()).toBe(true);
expect(result.unwrapErr().code).toBe('INVALID_INPUT');
});
it('returns wallet and transactions sorted desc by createdAt', async () => {
const input: GetWalletInput = { leagueId: 'league-1' };
const wallet: Wallet = {
id: 'wallet-1',
leagueId: 'league-1',
balance: 50,
totalRevenue: 100,
totalPlatformFees: 5,
totalWithdrawn: 10,
currency: 'USD',
createdAt: new Date('2025-01-01T00:00:00.000Z'),
};
const older: Transaction = {
id: 'txn-older',
walletId: 'wallet-1',
type: TransactionType.DEPOSIT,
amount: 25,
description: 'Older',
createdAt: new Date('2025-01-01T00:00:00.000Z'),
};
const newer: Transaction = {
id: 'txn-newer',
walletId: 'wallet-1',
type: TransactionType.WITHDRAWAL,
amount: 10,
description: 'Newer',
createdAt: new Date('2025-01-02T00:00:00.000Z'),
};
walletRepository.findByLeagueId.mockResolvedValue(wallet);
transactionRepository.findByWalletId.mockResolvedValue([older, newer]);
const result = await useCase.execute(input);
expect(result.isOk()).toBe(true);
const value = result.value;
expect(value).toEqual({
wallet,
transactions: [newer, older],
});
expect(transactionRepository.findByWalletId).toHaveBeenCalledWith('wallet-1');
});
it('creates wallet when missing, then returns wallet and transactions', async () => {
const input: GetWalletInput = { leagueId: 'league-1' };
vi.useFakeTimers();
vi.setSystemTime(new Date('2025-01-01T00:00:00.000Z'));
vi.spyOn(Math, 'random').mockReturnValue(0.123456789);
try {
walletRepository.findByLeagueId.mockResolvedValue(null);
walletRepository.create.mockImplementation(async (w: Wallet) => w);
transactionRepository.findByWalletId.mockResolvedValue([]);
const result = await useCase.execute(input);
expect(result.isOk()).toBe(true);
expect(walletRepository.create).toHaveBeenCalledWith(
expect.objectContaining({
id: expect.stringMatching(/^wallet-1735689600000-[a-z0-9]{9}$/),
leagueId: 'league-1',
balance: 0,
totalRevenue: 0,
totalPlatformFees: 0,
totalWithdrawn: 0,
currency: 'USD',
createdAt: new Date('2025-01-01T00:00:00.000Z'),
}),
);
const createdWalletArg = walletRepository.create.mock.calls[0]?.[0] as Wallet;
expect(transactionRepository.findByWalletId).toHaveBeenCalledWith(createdWalletArg.id);
const value = result.value;
expect(value).toEqual({
wallet: createdWalletArg,
transactions: [],
});
} finally {
vi.useRealTimers();
}
});
});