diff options
Diffstat (limited to 'tests/managers/thl/test_contest/test_leaderboard.py')
| -rw-r--r-- | tests/managers/thl/test_contest/test_leaderboard.py | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/tests/managers/thl/test_contest/test_leaderboard.py b/tests/managers/thl/test_contest/test_leaderboard.py new file mode 100644 index 0000000..80a88a5 --- /dev/null +++ b/tests/managers/thl/test_contest/test_leaderboard.py @@ -0,0 +1,138 @@ +from datetime import datetime, timezone, timedelta +from zoneinfo import ZoneInfo + +from generalresearch.currency import USDCent +from generalresearch.models.thl.contest.definitions import ( + ContestStatus, + ContestEndReason, +) +from generalresearch.models.thl.contest.leaderboard import ( + LeaderboardContest, + LeaderboardContestCreate, +) +from generalresearch.models.thl.product import Product +from generalresearch.models.thl.user import User +from test_utils.managers.contest.conftest import ( + leaderboard_contest_in_db as contest_in_db, + leaderboard_contest_create as contest_create, +) + + +class TestLeaderboardContestCRUD: + + def test_create( + self, + contest_create: LeaderboardContestCreate, + product_user_wallet_yes: Product, + thl_lm, + contest_manager, + ): + c = contest_manager.create( + product_id=product_user_wallet_yes.uuid, contest_create=contest_create + ) + c_out = contest_manager.get(c.uuid) + assert c == c_out + + assert isinstance(c, LeaderboardContest) + assert c.prize_count == 2 + assert c.status == ContestStatus.ACTIVE + # We have it set in the fixture as the daily contest for 2025-01-01 + assert c.end_condition.ends_at == datetime( + 2025, 1, 1, 23, 59, 59, 999999, tzinfo=ZoneInfo("America/New_York") + ).astimezone(tz=timezone.utc) + timedelta(minutes=90) + + def test_enter( + self, + user_with_wallet: User, + contest_in_db: LeaderboardContest, + thl_lm, + contest_manager, + user_manager, + thl_redis, + ): + contest = contest_in_db + user = user_with_wallet + + c: LeaderboardContest = contest_manager.get(contest_uuid=contest.uuid) + + c = contest_manager.get_leaderboard_user_view( + contest_uuid=contest.uuid, + user=user, + redis_client=thl_redis, + user_manager=user_manager, + ) + assert c.user_rank is None + + lbm = c.get_leaderboard_manager() + lbm.hit_complete_count(user.product_user_id) + + c = contest_manager.get_leaderboard_user_view( + contest_uuid=contest.uuid, + user=user, + redis_client=thl_redis, + user_manager=user_manager, + ) + assert c.user_rank == 1 + + def test_contest_ends( + self, + user_with_wallet: User, + contest_in_db: LeaderboardContest, + thl_lm, + contest_manager, + user_manager, + thl_redis, + ): + # The contest should be over. We need to trigger it. + contest = contest_in_db + contest._redis_client = thl_redis + contest._user_manager = user_manager + user = user_with_wallet + + lbm = contest.get_leaderboard_manager() + lbm.hit_complete_count(user.product_user_id) + + c = contest_manager.get_leaderboard_user_view( + contest_uuid=contest.uuid, + user=user, + redis_client=thl_redis, + user_manager=user_manager, + ) + assert c.user_rank == 1 + + bp_wallet = thl_lm.get_account_or_create_bp_wallet_by_uuid(user.product_id) + bp_wallet_balance = thl_lm.get_account_balance(account=bp_wallet) + assert bp_wallet_balance == 0 + user_wallet = thl_lm.get_account_or_create_user_wallet(user=user) + user_balance = thl_lm.get_account_balance(user_wallet) + assert user_balance == 0 + + decision, reason = contest.should_end() + assert decision + assert reason == ContestEndReason.ENDS_AT + + contest_manager.end_contest_if_over(contest=contest, ledger_manager=thl_lm) + + c: LeaderboardContest = contest_manager.get(contest_uuid=contest.uuid) + assert c.status == ContestStatus.COMPLETED + print(c) + + user_contest = contest_manager.get_leaderboard_user_view( + contest_uuid=contest.uuid, + user=user, + redis_client=thl_redis, + user_manager=user_manager, + ) + assert len(user_contest.user_winnings) == 1 + w = user_contest.user_winnings[0] + assert w.product_user_id == user.product_user_id + assert w.prize.cash_amount == USDCent(15_00) + + # The prize is $15.00, so the user should get $15, paid by the bp + assert thl_lm.get_account_balance(account=user_wallet) == 15_00 + # contest wallet is 0, and the BP gets 20c + contest_wallet = thl_lm.get_account_or_create_contest_wallet_by_uuid( + contest_uuid=c.uuid + ) + assert thl_lm.get_account_balance(account=contest_wallet) == 0 + assert thl_lm.get_account_balance(account=bp_wallet) == -15_00 |
