Skip to main content

Take & Settlement Test Cases

File: backend/tests/integration/sanity/08-transfer-settle.test.ts Total: 20 tests, all passing Runs against: Real Postgres DB, real settlement service, real transferSettleService


Setup

Hierarchy: Admin → Agent (CL=10000) → Player (CL varies per test)
Commission: 2% on exchange markets (betfair-ex)
Provider: 5000 USD × 100 exchangeRate = 500,000 FP

A. Basic Direction Tests (Transfer & Settle formulas)

A1: Player loses, agent settles full amount

  • Setup: Player CL=1000, places back bet stake=500 odds=2.0, loses
  • Action: Agent settles full amount (|take|)
  • Assertions:
    • Player balance (AC) unchanged after settlement
    • Player credit limit (CL) decreased by settle amount
    • Player take = 0 after settlement

A2: Player wins, agent settles full amount

  • Setup: Player reset to CL=1000 BP=1000, places back bet stake=200 odds=3.0, wins
  • Action: Agent settles full amount
  • Assertions:
    • Player balance decreased by settle amount (got paid cash off-platform)
    • Player CL unchanged
    • Agent balance increased by settle amount (paid cash, gets on-platform credit)
    • Player take = 0 after settlement

A3: Partial settle (loss)

  • Setup: Player CL=1000, places back bet stake=300 odds=2.0, loses
  • Action: Agent settles 100 of ~300 owed
  • Assertions:
    • CL decreased by 100 (partial)
    • Take moved toward 0 by exactly 100

A4: Partial settle (win)

  • Setup: New player CL=1000, places back bet stake=100 odds=4.0, wins
  • Action: Agent settles 100 of the win
  • Assertions:
    • Player balance decreased by 100
    • Agent balance increased by 100
    • Take moved toward 0 by exactly 100

B. Anti-Recycling Enforcement

B1: Player cannot bet after CL zeroed by settlement

  • Setup: Player CL=500, places back bet stake=500 odds=2.0, loses all
  • Action: Agent settles full amount → CL goes to 0
  • Assertions:
    • CL = 0
    • Balance = 0
    • Attempt to place bet → rejected (insufficient balance)

C. Hierarchy Chain Settlement

C1: Full chain settlement zeroes out all takes

  • Setup: MA → Sub-Agent → Player hierarchy, player places back bet stake=400 odds=2.0, loses
  • Action:
    1. Sub-agent settles player (full amount)
    2. MA settles sub-agent (full amount)
  • Assertions:
    • Player take = 0 after step 1
    • Sub-agent take ≈ 0 after step 2

D. Validation Guards

D1: Settle amount > |take| is rejected

  • Setup: Player loses 200
  • Action: Attempt to settle |take| + 100
  • Assertion: Throws error

D2: Settle when take is 0 is rejected

  • Setup: Fresh player with no bets (take = 0)
  • Action: Attempt to settle 100
  • Assertion: Throws error

D3: Negative amount is rejected

  • Action: Attempt to settle -50
  • Assertion: Throws error

E. PnL-Based Take (Bet Placement vs Settlement)

E1: Open bet does NOT change currentTake

  • Setup: Fresh player (take = 0)
  • Action: Place back bet stake=300 odds=2.5
  • Assertion: Take still = 0 (no PnL event on bet placement)

E2: After bet settles, currentTake reflects profitLoss delta

  • Setup: From E1, open bet exists
  • Action: Settle bet as loss
  • Assertion: Take = -300 (profitLoss applied as delta)

F. Commission Per-User

F1: User A commission processes even when User B has unsettled orders

  • Setup: Two players bet on same market (same fixtureId + marketId)
    • Player 1: back stake=100 odds=3.0
    • Player 2: back stake=100 odds=2.0
  • Action: Settle player 1 as win, player 2 stays unsettled
  • Assertions:
    • Player 1 has commission record (2% of 200 profit = 4)
    • Player 2 has NO commission record (still unsettled)
  • Action: Settle player 2 as loss
  • Assertion: Player 2 still no commission (net PnL <= 0)

H. Settlement History Audit Trail

H1: Settlement record has correct takeBefore/takeAfter

  • Setup: Player places back bet stake=300 odds=2.0, loses
  • Action: Settle full amount with notes
  • Assertions:
    • TransferSettlement record exists
    • takeBefore matches actual take before settlement
    • takeAfter ≈ 0
    • notes = 'Test settlement note'

T. Take Calculation Correctness

T1: Commission deducted from take

  • Setup: Fresh player CL=1000, places back bet stake=200 odds=3.5, wins
  • Calculation: return=700, profitLoss=500, commission=500×0.02=10
  • Assertion: take = 500 - 10 = 490

T2: Commission NOT double-counted in BETS API path (regression)

  • Setup: Fresh player CL=1000, two bets in same market settled one-by-one
    • Bet 1: back stake=100 odds=3.0 → wins (profitLoss=200)
    • Bet 2: back stake=100 odds=2.0 → loses (profitLoss=-100)
  • Action: Settle bet 1 (commission not triggered), then settle bet 2 (triggers commission)
  • Calculation: Net market PnL=100, commission=100×0.02=2
  • Assertions:
    • take = 200 + (-100) + (-2) = 98
    • Commission record exists exactly once (not duplicated)

T3: No commission on bookmaker market

  • Setup: Fresh player CL=1000, bookmaker (bifrost) back bet stake=100 odds=2.5, wins
  • Calculation: profitLoss=150, no commission (bookmaker market)
  • Assertions:
    • take = 150 (raw profitLoss, no commission deduction)
    • No commission record exists for this market

T6: Lay bet win — take += stake minus commission

  • Setup: Fresh player CL=1000, lay bet stake=100 odds=3.0, wins
  • Calculation: profitLoss=+100 (lay win = stake), commission=100×0.02=2
  • Assertion: take = 100 - 2 = 98

T7: Void bet — take unchanged

  • Setup: Fresh player CL=1000, places back bet stake=300 odds=2.0
  • Action: Settle as void
  • Assertion: take = 0 (void = zero profitLoss = zero delta)

T11: Transfer & Settle does NOT propagate to agent take

  • Setup: Fresh player CL=500, places back bet stake=200 odds=2.0, loses
  • Action: Agent settles player (full 200)
  • Assertions:
    • Player take = 0
    • Agent take unchanged (settlement doesn't propagate up)

T12: cumulativePnl tracks PnL only, settledAmount tracks settlements

  • Setup: Fresh player CL=500, places back bet stake=300 odds=2.0, loses
  • After PnL event:
    • cumulativePnl = -300
    • settledAmount = 0
    • currentTake = -300
  • Action: Settle 200
  • After settlement:
    • cumulativePnl = -300 (unchanged — PnL doesn't change on settlement)
    • settledAmount = 200
    • currentTake = -100 (-300 + 200)

Take Touch Points Verified

EventTake changes?Tests covering it
Entity creationNo (initialized at 0)E1 (implicit)
Bet placementNoE1
Back bet loss settlementYes (+profitLoss delta)E2, A1, A3, T12
Back bet win settlementYes (+profitLoss delta)A2, A4, T1, T2
Lay bet win settlementYes (+profitLoss delta)T6
Void settlementNo (zero delta)T7
Commission deductionYes (-commission delta)T1, T2
No commission on bookmakerVerifiedT3
Commission per-user isolationVerifiedF1
Commission not double-countedVerifiedT2
Transfer & Settle (loss direction)Yes (toward 0, CL decreases)A1, A3, B1
Transfer & Settle (win direction)Yes (toward 0, BP decreases)A2, A4
Transfer & Settle does NOT propagate upVerifiedT11
Chain settlement (MA→Agent→Player)VerifiedC1
Over-settle rejectedVerifiedD1
Zero take settle rejectedVerifiedD2
Negative amount rejectedVerifiedD3
Anti-recycling (CL=0 blocks betting)VerifiedB1
Audit trail (takeBefore/takeAfter/notes)VerifiedH1
Audit columns (cumulativePnl, settledAmount)VerifiedT12