diff options
Diffstat (limited to 'tests/managers/thl/test_ledger/test_user_txs.py')
| -rw-r--r-- | tests/managers/thl/test_ledger/test_user_txs.py | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/tests/managers/thl/test_ledger/test_user_txs.py b/tests/managers/thl/test_ledger/test_user_txs.py new file mode 100644 index 0000000..d81b244 --- /dev/null +++ b/tests/managers/thl/test_ledger/test_user_txs.py @@ -0,0 +1,288 @@ +from datetime import timedelta, datetime, timezone +from decimal import Decimal +from uuid import uuid4 + +from generalresearch.managers.thl.payout import ( + AMT_ASSIGNMENT_CASHOUT_METHOD, + AMT_BONUS_CASHOUT_METHOD, +) +from generalresearch.managers.thl.user_compensate import user_compensate +from generalresearch.models.thl.definitions import ( + Status, + WallAdjustedStatus, +) +from generalresearch.models.thl.ledger import ( + UserLedgerTransactionTypesSummary, + UserLedgerTransactionTypeSummary, + TransactionType, +) +from generalresearch.models.thl.session import Session +from generalresearch.models.thl.user import User +from generalresearch.models.thl.wallet import PayoutType + + +def test_user_txs( + user_factory, + product_amt_true, + create_main_accounts, + thl_lm, + lm, + delete_ledger_db, + session_with_tx_factory, + adj_to_fail_with_tx_factory, + adj_to_complete_with_tx_factory, + session_factory, + user_payout_event_manager, + utc_now, +): + delete_ledger_db() + create_main_accounts() + + user: User = user_factory(product=product_amt_true) + account = thl_lm.get_account_or_create_user_wallet(user) + print(f"{account.uuid=}") + + s: Session = session_with_tx_factory(user=user, wall_req_cpi=Decimal("1.00")) + + bribe_uuid = user_compensate( + ledger_manager=thl_lm, + user=user, + amount_int=100, + ) + + pe = user_payout_event_manager.create( + uuid=uuid4().hex, + debit_account_uuid=account.uuid, + cashout_method_uuid=AMT_ASSIGNMENT_CASHOUT_METHOD, + amount=5, + created=utc_now, + payout_type=PayoutType.AMT_HIT, + request_data=dict(), + ) + thl_lm.create_tx_user_payout_request( + user=user, + payout_event=pe, + ) + pe = user_payout_event_manager.create( + uuid=uuid4().hex, + debit_account_uuid=account.uuid, + cashout_method_uuid=AMT_BONUS_CASHOUT_METHOD, + amount=127, + created=utc_now, + payout_type=PayoutType.AMT_BONUS, + request_data=dict(), + ) + thl_lm.create_tx_user_payout_request( + user=user, + payout_event=pe, + ) + + wall = s.wall_events[-1] + adj_to_fail_with_tx_factory(session=s, created=wall.finished) + + # And a fail -> complete adjustment + s_fail: Session = session_factory( + user=user, + wall_count=1, + final_status=Status.FAIL, + wall_req_cpi=Decimal("2.00"), + ) + adj_to_complete_with_tx_factory(session=s_fail, created=utc_now) + + # txs = thl_lm.get_tx_filtered_by_account(account.uuid) + # print(len(txs), txs) + txs = thl_lm.get_user_txs(user) + assert len(txs.transactions) == 6 + assert txs.total == 6 + assert txs.page == 1 + assert txs.size == 50 + + # print(len(txs.transactions), txs) + d = txs.model_dump_json() + # print(d) + + descriptions = {x.description for x in txs.transactions} + assert descriptions == { + "Compensation Bonus", + "HIT Bonus", + "HIT Reward", + "Task Adjustment", + "Task Complete", + } + amounts = {x.amount for x in txs.transactions} + assert amounts == {-127, 100, 38, -38, -5, 76} + + assert txs.summary == UserLedgerTransactionTypesSummary( + bp_adjustment=UserLedgerTransactionTypeSummary( + entry_count=2, min_amount=-38, max_amount=76, total_amount=76 - 38 + ), + bp_payment=UserLedgerTransactionTypeSummary( + entry_count=1, min_amount=38, max_amount=38, total_amount=38 + ), + user_bonus=UserLedgerTransactionTypeSummary( + entry_count=1, min_amount=100, max_amount=100, total_amount=100 + ), + user_payout_request=UserLedgerTransactionTypeSummary( + entry_count=2, min_amount=-127, max_amount=-5, total_amount=-132 + ), + ) + tx_adj_c = [ + tx for tx in txs.transactions if tx.tx_type == TransactionType.BP_ADJUSTMENT + ] + assert sorted([tx.amount for tx in tx_adj_c]) == [-38, 76] + + +def test_user_txs_pagination( + user_factory, + product_amt_true, + create_main_accounts, + thl_lm, + lm, + delete_ledger_db, + session_with_tx_factory, + adj_to_fail_with_tx_factory, + user_payout_event_manager, + utc_now, +): + delete_ledger_db() + create_main_accounts() + + user: User = user_factory(product=product_amt_true) + account = thl_lm.get_account_or_create_user_wallet(user) + print(f"{account.uuid=}") + + for _ in range(12): + user_compensate( + ledger_manager=thl_lm, + user=user, + amount_int=100, + skip_flag_check=True, + ) + + txs = thl_lm.get_user_txs(user, page=1, size=5) + assert len(txs.transactions) == 5 + assert txs.total == 12 + assert txs.page == 1 + assert txs.size == 5 + assert txs.summary.user_bonus.total_amount == 1200 + assert txs.summary.user_bonus.entry_count == 12 + + # Skip to the 3rd page. We made 12, so there are 2 left + txs = thl_lm.get_user_txs(user, page=3, size=5) + assert len(txs.transactions) == 2 + assert txs.total == 12 + assert txs.page == 3 + assert txs.summary.user_bonus.total_amount == 1200 + assert txs.summary.user_bonus.entry_count == 12 + + # Should be empty, not fail + txs = thl_lm.get_user_txs(user, page=4, size=5) + assert len(txs.transactions) == 0 + assert txs.total == 12 + assert txs.page == 4 + assert txs.summary.user_bonus.total_amount == 1200 + assert txs.summary.user_bonus.entry_count == 12 + + # Test filtering. We should pull back only this one + now = datetime.now(tz=timezone.utc) + user_compensate( + ledger_manager=thl_lm, + user=user, + amount_int=100, + skip_flag_check=True, + ) + txs = thl_lm.get_user_txs(user, page=1, size=5, time_start=now) + assert len(txs.transactions) == 1 + assert txs.total == 1 + assert txs.page == 1 + # And the summary is restricted to this time range also! + assert txs.summary.user_bonus.total_amount == 100 + assert txs.summary.user_bonus.entry_count == 1 + + # And filtering with 0 results + now = datetime.now(tz=timezone.utc) + txs = thl_lm.get_user_txs(user, page=1, size=5, time_start=now) + assert len(txs.transactions) == 0 + assert txs.total == 0 + assert txs.page == 1 + assert txs.pages == 0 + # And the summary is restricted to this time range also! + assert txs.summary.user_bonus.total_amount == None + assert txs.summary.user_bonus.entry_count == 0 + + +def test_user_txs_rolling_balance( + user_factory, + product_amt_true, + create_main_accounts, + thl_lm, + lm, + delete_ledger_db, + session_with_tx_factory, + adj_to_fail_with_tx_factory, + user_payout_event_manager, +): + """ + Creates 3 $1.00 bonuses (postive), + then 1 cashout (negative), $1.50 + then 3 more $1.00 bonuses. + Note: pagination + rolling balance will BREAK if txs have + identical timestamps. In practice, they do not. + """ + delete_ledger_db() + create_main_accounts() + + user: User = user_factory(product=product_amt_true) + account = thl_lm.get_account_or_create_user_wallet(user) + + for _ in range(3): + user_compensate( + ledger_manager=thl_lm, + user=user, + amount_int=100, + skip_flag_check=True, + ) + pe = user_payout_event_manager.create( + uuid=uuid4().hex, + debit_account_uuid=account.uuid, + cashout_method_uuid=AMT_BONUS_CASHOUT_METHOD, + amount=150, + payout_type=PayoutType.AMT_BONUS, + request_data=dict(), + ) + thl_lm.create_tx_user_payout_request( + user=user, + payout_event=pe, + ) + for _ in range(3): + user_compensate( + ledger_manager=thl_lm, + user=user, + amount_int=100, + skip_flag_check=True, + ) + + txs = thl_lm.get_user_txs(user, page=1, size=10) + assert txs.transactions[0].balance_after == 100 + assert txs.transactions[1].balance_after == 200 + assert txs.transactions[2].balance_after == 300 + assert txs.transactions[3].balance_after == 150 + assert txs.transactions[4].balance_after == 250 + assert txs.transactions[5].balance_after == 350 + assert txs.transactions[6].balance_after == 450 + + # Ascending order, get 2nd page, make sure the balances include + # the previous txs. (will return last 3 txs) + txs = thl_lm.get_user_txs(user, page=2, size=4) + assert len(txs.transactions) == 3 + assert txs.transactions[0].balance_after == 250 + assert txs.transactions[1].balance_after == 350 + assert txs.transactions[2].balance_after == 450 + + # Descending order, get 1st page. Will + # return most recent 3 txs in desc order + txs = thl_lm.get_user_txs(user, page=1, size=3, order_by="-created") + assert len(txs.transactions) == 3 + assert txs.transactions[0].balance_after == 450 + assert txs.transactions[1].balance_after == 350 + assert txs.transactions[2].balance_after == 250 |
