Files
thebet365/apps/api/src/domains/ledger/wallet.service.spec.ts
2026-06-13 17:38:25 +08:00

76 lines
2.0 KiB
TypeScript

import { Decimal } from '@prisma/client/runtime/library';
import { WalletService } from './wallet.service';
import { expectAppError } from '../../testing/prisma-mock';
describe('WalletService', () => {
const tx = {
$queryRaw: jest.fn(),
wallet: {
update: jest.fn(),
},
walletTransaction: {
findUnique: jest.fn(),
create: jest.fn(),
},
};
const prisma = {
$transaction: jest.fn(async (fn: (client: typeof tx) => Promise<unknown>) => fn(tx)),
};
let service: WalletService;
beforeEach(() => {
jest.clearAllMocks();
service = new WalletService(prisma as never);
tx.walletTransaction.findUnique.mockResolvedValue(null);
});
it('rejects settlement when frozen funds are lower than the stake', async () => {
tx.$queryRaw.mockResolvedValue([
{
id: 1n,
available_balance: new Decimal(10),
frozen_balance: new Decimal(40),
version: 1,
},
]);
await expect(
service.settleBet(
99n,
new Decimal(50),
new Decimal(0),
'BET-LOW-FROZEN',
'LOSE',
undefined,
'settle:BATCH:BET-LOW-FROZEN',
),
).rejects.toMatchObject(expectAppError('WALLET_FROZEN_INSUFFICIENT'));
expect(tx.wallet.update).not.toHaveBeenCalled();
expect(tx.walletTransaction.create).not.toHaveBeenCalled();
});
it('lists player-approved deposits in transfer transactions', async () => {
const listPrisma = {
walletTransaction: {
findMany: jest.fn().mockResolvedValue([]),
count: jest.fn().mockResolvedValue(0),
},
};
const listService = new WalletService(listPrisma as never);
await listService.listTransferTransactions({});
expect(listPrisma.walletTransaction.findMany).toHaveBeenCalledWith(
expect.objectContaining({
where: expect.objectContaining({
transactionType: expect.objectContaining({
in: expect.arrayContaining(['PLAYER_DEPOSIT']),
}),
}),
}),
);
});
});