Files
thebet365/apps/api/src/integration.spec.ts
Mars 414998ce36 feat(admin,api,player): 代理层级管理、额度上下分与玩家钱包详情
新增代理管理器与二级代理体系,完善信用额度/上下分上下文与冻结策略;代理端玩家与子代理管理增强;玩家端新增钱包详情页与交易筛选优化。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-08 15:34:12 +08:00

125 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {
settleSelection,
calculatePayout,
isQuarterHandicapOrTotal,
} from './domains/settlement/domain/settlement-calculator';
/**
* Agent credit & wallet integration scenarios (A001-A007)
* These tests validate business rules without DB dependency.
*/
describe('Agent Credit Rules', () => {
it('A001: deposit increases player balance and reduces agent available credit', () => {
const creditLimit = 10000;
const usedCredit = 1000;
const depositAmount = 500;
const newUsed = usedCredit + depositAmount;
expect(creditLimit - newUsed).toBe(8500);
});
it('A002: bet freeze does not change total balance or agent credit', () => {
const available = 1000;
const frozen = 0;
const stake = 100;
const totalBefore = available + frozen;
const totalAfter = (available - stake) + (frozen + stake);
expect(totalAfter).toBe(totalBefore);
});
it('A003: player lose releases agent credit', () => {
const usedBefore = 1000;
const stake = 100;
const usedAfter = usedBefore - stake;
expect(usedAfter).toBe(900);
});
it('A004: player win increases agent credit usage', () => {
const usedBefore = 1000;
const payout = 185;
const stake = 100;
const netGain = payout - stake;
const usedAfter = usedBefore + netGain;
expect(usedAfter).toBe(1085);
});
it('A005: negative credit blocks further deposit', () => {
const creditLimit = 1000;
const usedCredit = 1200;
const available = creditLimit - usedCredit;
expect(available).toBeLessThan(0);
const canDeposit = available > 0;
expect(canDeposit).toBe(false);
});
it('A006: level 1 allocating credit to level 2 reduces available', () => {
const available = 10000;
const allocate = 3000;
expect(available - allocate).toBe(7000);
});
it('A007: non-direct player deposit should be rejected', () => {
const agentId = BigInt(1);
const playerParentId = BigInt(2);
const canDeposit = agentId === playerParentId;
expect(canDeposit).toBe(false);
});
it('A008: admin deposit cannot exceed parent agent available credit', () => {
const creditLimit = 5000;
const usedCredit = 4800;
const depositAmount = 300;
const available = creditLimit - usedCredit;
expect(depositAmount).toBeGreaterThan(available);
const allowed = depositAmount <= available;
expect(allowed).toBe(false);
});
});
describe('Bet Validation Rules (B001-B010)', () => {
it('B003: odds version mismatch should reject', () => {
const submitted = BigInt(1);
const current = BigInt(2);
expect(submitted === current).toBe(false);
});
it('B007: same match legs allowed in parlay (25 legs)', () => {
const legs = [
{ matchId: '1', selectionId: 'a' },
{ matchId: '1', selectionId: 'b' },
];
expect(legs.length).toBeGreaterThanOrEqual(2);
expect(legs.length).toBeLessThanOrEqual(5);
});
it('B008: quarter line in parlay rejected', () => {
expect(isQuarterHandicapOrTotal(-0.25)).toBe(true);
expect(isQuarterHandicapOrTotal(-0.5)).toBe(false);
});
it('B009: more than 5 legs rejected', () => {
const legs = 6;
expect(legs > 5).toBe(true);
});
});
describe('Settlement payout accuracy', () => {
it('half win payout formula', () => {
const payout = calculatePayout(100, 1.85, 'HALF_WIN');
expect(payout.toNumber()).toBe(142.5);
});
it('half lose payout formula', () => {
const payout = calculatePayout(100, 1.85, 'HALF_LOSE');
expect(payout.toNumber()).toBe(50);
});
it('S004: 0-0 odd/even is even', () => {
const result = settleSelection({
marketType: 'FT_ODD_EVEN',
selectionCode: 'EVEN',
score: { htHome: 0, htAway: 0, ftHome: 0, ftAway: 0 },
});
expect(result).toBe('WIN');
});
});