aboutsummaryrefslogtreecommitdiff
path: root/tests/managers/thl/test_contest/test_leaderboard.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/managers/thl/test_contest/test_leaderboard.py')
-rw-r--r--tests/managers/thl/test_contest/test_leaderboard.py138
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