diff options
| author | stuppie | 2026-09-07 10:32:10 -0600 |
|---|---|---|
| committer | stuppie | 2026-09-07 10:32:10 -0600 |
| commit | c25a7351eeb6be4a998348a8cfc96bc4f965b96c (patch) | |
| tree | 301ce11ccd62dec5ab8485ff4b6859b2bea119e6 | |
| parent | e1b1484c1b33708154a21dff095bd56c498115f4 (diff) | |
| download | generalresearch-c25a7351eeb6be4a998348a8cfc96bc4f965b96c.tar.gz generalresearch-c25a7351eeb6be4a998348a8cfc96bc4f965b96c.zip | |
Fix Leaderboard optional fields were made not-optional
| -rw-r--r-- | generalresearch/models/thl/leaderboard.py | 9 | ||||
| -rw-r--r-- | tests/managers/thl/test_contest/test_leaderboard.py | 10 | ||||
| -rw-r--r-- | tests/managers/thl/test_contest/test_milestone.py | 37 | ||||
| -rw-r--r-- | tests/managers/thl/test_contest/test_raffle.py | 49 | ||||
| -rw-r--r-- | tests/managers/thl/test_product.py | 6 | ||||
| -rw-r--r-- | tests/managers/thl/test_session_manager.py | 10 |
6 files changed, 64 insertions, 57 deletions
diff --git a/generalresearch/models/thl/leaderboard.py b/generalresearch/models/thl/leaderboard.py index 523c696..6e49af2 100644 --- a/generalresearch/models/thl/leaderboard.py +++ b/generalresearch/models/thl/leaderboard.py @@ -78,6 +78,9 @@ class Leaderboard(BaseModel): weekly, and monthly leaderboard. """ + # Note: id and name get auto-generated by the model_validators, but the fields need + # to be optional with a default or the model can't be inited. + # todo: these should really be computed_fields instead id: UUIDStr | None = Field( description="Unique ID for this leaderboard", examples=["845b0074ad533df580ebb9c80cc3bce1"], @@ -108,9 +111,10 @@ class Leaderboard(BaseModel): examples=[LeaderboardFrequency.DAILY], ) - timezone_name: str = Field( + timezone_name: str | None = Field( description="The timezone for the requested country", examples=["America/New_York"], + default=None, ) sort_order: Literal["ascending", "descending"] = Field(default="descending") @@ -139,7 +143,7 @@ class Leaderboard(BaseModel): # exclude=True, ) - period_end_local: AwareDatetime = Field( + period_end_local: AwareDatetime | None = Field( description="The end of the time period covered by this board in local time, tz-aware", examples=[ datetime( @@ -153,6 +157,7 @@ class Leaderboard(BaseModel): tzinfo=ZoneInfo("America/New_York"), ) ], + default=None, # exclude=True, ) diff --git a/tests/managers/thl/test_contest/test_leaderboard.py b/tests/managers/thl/test_contest/test_leaderboard.py index 9fd4428..8aa0780 100644 --- a/tests/managers/thl/test_contest/test_leaderboard.py +++ b/tests/managers/thl/test_contest/test_leaderboard.py @@ -26,7 +26,6 @@ if TYPE_CHECKING: class TestLeaderboardContestCRUD: - def test_create( self, leaderboard_contest_create: LeaderboardContestCreate, @@ -35,7 +34,8 @@ class TestLeaderboardContestCRUD: contest_manager: ContestManager, ): c = contest_manager.create( - product_id=product_user_wallet_yes.uuid, contest_create=leaderboard_contest_create + product_id=product_user_wallet_yes.uuid, + contest_create=leaderboard_contest_create, ) c_out = contest_manager.get(c.uuid) assert c == c_out @@ -55,8 +55,9 @@ class TestLeaderboardContestCRUD: thl_ledger_manager: ThlLedgerManager, contest_manager: ContestManager, user_manager: UserManager, - thl_redis: RedisConfig, + thl_redis_config: RedisConfig, ): + thl_redis = thl_redis_config.create_redis_client() contest = leaderboard_contest_in_db user = user_with_wallet @@ -88,8 +89,9 @@ class TestLeaderboardContestCRUD: thl_ledger_manager: ThlLedgerManager, contest_manager: ContestManager, user_manager: UserManager, - thl_redis: RedisConfig, + thl_redis_config: RedisConfig, ): + thl_redis = thl_redis_config.create_redis_client() # The contest should be over. We need to trigger it. contest = leaderboard_contest_in_db contest._redis_client = thl_redis diff --git a/tests/managers/thl/test_contest/test_milestone.py b/tests/managers/thl/test_contest/test_milestone.py index dab02e7..f26819b 100644 --- a/tests/managers/thl/test_contest/test_milestone.py +++ b/tests/managers/thl/test_contest/test_milestone.py @@ -20,17 +20,16 @@ if TYPE_CHECKING: from generalresearch.models.thl.contest.milestone import ( MilestoneContestCreate, ) - from generalresearch.models.thl.contest.raffle import RaffleContest from generalresearch.models.thl.product import Product from generalresearch.models.thl.user import User class TestMilestoneContest: - def test_should_end( self, - contest: MilestoneContest, + milestone_contest: MilestoneContest, ): + contest = milestone_contest # contest is active and has no entries should, msg = contest.should_end() assert not should, msg @@ -51,15 +50,15 @@ class TestMilestoneContest: class TestMilestoneContestCRUD: - def test_create( self, - contest_create: MilestoneContestCreate, + milestone_contest_create: MilestoneContestCreate, product_user_wallet_yes: Product, contest_manager: ContestManager, ): c = contest_manager.create( - product_id=product_user_wallet_yes.uuid, contest_create=contest_create + product_id=product_user_wallet_yes.uuid, + contest_create=milestone_contest_create, ) c_out = contest_manager.get(c.uuid) assert c == c_out @@ -75,13 +74,13 @@ class TestMilestoneContestCRUD: def test_enter( self, user_with_wallet: User, - contest_in_db: MilestoneContest, + milestone_contest_in_db: MilestoneContest, thl_ledger_manager: ThlLedgerManager, contest_manager: ContestManager, ): # Users CANNOT directly enter a milestone contest through the api, # but we'll call this manager method when a trigger is hit. - contest = contest_in_db + contest = milestone_contest_in_db user = user_with_wallet contest_manager.enter_milestone_contest( @@ -131,13 +130,13 @@ class TestMilestoneContestCRUD: def test_enter_win( self, user_with_wallet: User, - contest_in_db: MilestoneContest, + milestone_contest_in_db: MilestoneContest, thl_ledger_manager: ThlLedgerManager, contest_manager: ContestManager, ): # User enters contest, which brings the USER'S total amount above the limit, # and the user reaches the milestone - contest = contest_in_db + contest = milestone_contest_in_db user = user_with_wallet user_wallet = thl_ledger_manager.get_account_or_create_user_wallet(user=user) @@ -196,13 +195,13 @@ class TestMilestoneContestCRUD: self, user_factory: Callable[..., User], product_user_wallet_yes: Product, - contest_in_db: MilestoneContest, + milestone_contest_in_db: MilestoneContest, thl_ledger_manager: ThlLedgerManager, contest_manager: ContestManager, ): # Multiple users reach the milestone. Contest ends after 5 wins. users = [user_factory(product=product_user_wallet_yes) for _ in range(5)] - contest = contest_in_db + contest = milestone_contest_in_db for u in users: contest_manager.enter_milestone_contest( @@ -220,7 +219,7 @@ class TestMilestoneContestCRUD: def test_trigger( self, user_with_wallet: User, - contest_in_db: MilestoneContest, + milestone_contest_in_db: MilestoneContest, thl_ledger_manager: ThlLedgerManager, contest_manager: ContestManager, ): @@ -235,7 +234,7 @@ class TestMilestoneContestCRUD: # Assert this contest got entered c: MilestoneUserView = contest_manager.get_milestone_user_view( - contest_uuid=contest_in_db.uuid, user=user_with_wallet + contest_uuid=milestone_contest_in_db.uuid, user=user_with_wallet ) assert c.user_amount == 1 @@ -244,7 +243,7 @@ class TestMilestoneContestUserViews: def test_list_user_eligible_country( self, user_with_wallet: User, - raffle_contest_factory: Callable[..., RaffleContest], + milestone_contest_factory: Callable[..., MilestoneContest], thl_ledger_manager: ThlLedgerManager, contest_manager: ContestManager, ): @@ -255,7 +254,7 @@ class TestMilestoneContestUserViews: assert len(cs) == 0 # Create a contest. It'll be in the US/CA - raffle_contest_factory(country_isos={"us", "ca"}) + milestone_contest_factory(country_isos={"us", "ca"}) # Not eligible in mexico cs = contest_manager.get_many_by_user_eligible( @@ -268,7 +267,7 @@ class TestMilestoneContestUserViews: assert len(cs) == 1 # Create another, any country - raffle_contest_factory(country_isos=None) + milestone_contest_factory(country_isos=None) cs = contest_manager.get_many_by_user_eligible( user=user_with_wallet, country_iso="mx" ) @@ -281,12 +280,12 @@ class TestMilestoneContestUserViews: def test_list_user_eligible( self, user_with_money: User, - raffle_contest_factory: Callable[..., RaffleContest], + milestone_contest_factory: Callable[..., MilestoneContest], thl_ledger_manager: ThlLedgerManager, contest_manager: ContestManager, ): # User reaches milestone after 1 complete - c = raffle_contest_factory(target_amount=1) + c = milestone_contest_factory(target_amount=1) user = user_with_money cs = contest_manager.get_many_by_user_eligible( diff --git a/tests/managers/thl/test_contest/test_raffle.py b/tests/managers/thl/test_contest/test_raffle.py index 0b2b852..7388991 100644 --- a/tests/managers/thl/test_contest/test_raffle.py +++ b/tests/managers/thl/test_contest/test_raffle.py @@ -47,8 +47,9 @@ class TestRaffleContest: def test_should_end( self, - contest: RaffleContest, + raffle_contest: RaffleContest, ): + contest = raffle_contest # contest is active and has no entries should, msg = contest.should_end() assert not should, msg @@ -71,12 +72,12 @@ class TestRaffleContestCRUD: def test_create( self, - contest_create: RaffleContestCreate, + raffle_contest_create: RaffleContestCreate, product_user_wallet_yes: Product, contest_manager: ContestManager, ): c = contest_manager.create( - product_id=product_user_wallet_yes.uuid, contest_create=contest_create + product_id=product_user_wallet_yes.uuid, contest_create=raffle_contest_create ) c_out = contest_manager.get(c.uuid) assert c == c_out @@ -92,15 +93,15 @@ class TestRaffleContestCRUD: def test_enter( self, user_with_money: User, - contest_in_db: RaffleContest, + raffle_contest_in_db: RaffleContest, thl_ledger_manager: ThlLedgerManager, contest_manager: ContestManager, ): # Raffle ends at $1.00. User enters for $0.60 print(user_with_money.product_id) - print(contest_in_db.product_id) - print(contest_in_db.uuid) - contest = contest_in_db + print(raffle_contest_in_db.product_id) + print(raffle_contest_in_db.uuid) + contest = raffle_contest_in_db user_wallet = thl_ledger_manager.get_account_or_create_user_wallet( user=user_with_money @@ -145,13 +146,13 @@ class TestRaffleContestCRUD: def test_enter_ends( self, user_with_money: User, - contest_in_db: RaffleContest, + raffle_contest_in_db: RaffleContest, thl_ledger_manager: ThlLedgerManager, contest_manager: ContestManager, ): # User enters contest, which brings the total amount above the limit, # and the contest should end, with a winner selected - contest = contest_in_db + contest = raffle_contest_in_db bp_wallet = thl_ledger_manager.get_account_or_create_bp_wallet_by_uuid( user_with_money.product_id @@ -209,13 +210,13 @@ class TestRaffleContestCRUD: def test_enter_ends_cash_prize( self, user_with_money: User, - contest_factory: Callable[..., Contest], + raffle_contest_factory: Callable[..., Contest], thl_ledger_manager: ThlLedgerManager, contest_manager: ContestManager, ): # Same as test_enter_ends, but the prize is cash. Just # testing the ledger methods - c = contest_factory( + c = raffle_contest_factory( prizes=[ ContestPrize( name="$1.00 bonus", @@ -268,11 +269,11 @@ class TestRaffleContestCRUD: def test_enter_failure( self, user_with_wallet: User, - contest_in_db: RaffleContest, + raffle_contest_in_db: RaffleContest, thl_ledger_manager: ThlLedgerManager, contest_manager: ContestManager, ): - c = contest_in_db + c = raffle_contest_in_db user = user_with_wallet # Tries to enter $0 @@ -310,12 +311,12 @@ class TestRaffleContestCRUD: def test_enter_not_eligible( self, user_with_money: User, - contest_factory: Callable[..., Contest], + raffle_contest_factory: Callable[..., Contest], thl_ledger_manager: ThlLedgerManager, contest_manager: ContestManager, ): # Max entry amount per user $0.10. Contest still ends at $1.00 - c = contest_factory( + c = raffle_contest_factory( entry_rule=ContestEntryRule( max_entry_amount_per_user=USDCent(10), max_daily_entries_per_user=USDCent(8), @@ -380,7 +381,7 @@ class TestRaffleContestUserViews: def test_list_user_eligible_country( self, user_with_wallet: User, - contest_factory: Callable[..., Contest], + raffle_contest_factory: Callable[..., Contest], thl_ledger_manager: ThlLedgerManager, contest_manager: ContestManager, ): @@ -391,7 +392,7 @@ class TestRaffleContestUserViews: assert len(cs) == 0 # Create a contest. It'll be in the US/CA - contest_factory(country_isos={"us", "ca"}) + raffle_contest_factory(country_isos={"us", "ca"}) # Not eligible in mexico cs = contest_manager.get_many_by_user_eligible( @@ -404,7 +405,7 @@ class TestRaffleContestUserViews: assert len(cs) == 1 # Create another, any country - contest_factory(country_isos=None) + raffle_contest_factory(country_isos=None) cs = contest_manager.get_many_by_user_eligible( user=user_with_wallet, country_iso="mx" ) @@ -417,11 +418,11 @@ class TestRaffleContestUserViews: def test_list_user_eligible( self, user_with_money: User, - contest_factory: Callable[..., Contest], + raffle_contest_factory: Callable[..., Contest], thl_ledger_manager: ThlLedgerManager, contest_manager: ContestManager, ): - c = contest_factory( + c = raffle_contest_factory( end_condition=ContestEndCondition(target_entry_amount=USDCent(10)), entry_rule=ContestEntryRule( max_entry_amount_per_user=USDCent(1), @@ -467,11 +468,11 @@ class TestRaffleContestUserViews: def test_list_user_winnings( self, user_with_money: User, - contest_factory: Callable[..., Contest], + raffle_contest_factory: Callable[..., Contest], thl_ledger_manager: ThlLedgerManager, contest_manager: ContestManager, ): - c = contest_factory( + c = raffle_contest_factory( end_condition=ContestEndCondition(target_entry_amount=USDCent(100)), ) entry = ContestEntry( @@ -507,11 +508,11 @@ class TestRaffleContestCRUDCount: def test_enter( self, user_with_wallet: User, - contest_factory: Callable[..., Contest], + raffle_contest_factory: Callable[..., Contest], thl_ledger_manager: ThlLedgerManager, contest_manager: ContestManager, ): - c = contest_factory(entry_type=ContestEntryType.COUNT) + c = raffle_contest_factory(entry_type=ContestEntryType.COUNT) entry = ContestEntry( entry_type=ContestEntryType.COUNT, user=user_with_wallet, diff --git a/tests/managers/thl/test_product.py b/tests/managers/thl/test_product.py index 81e0122..8d72fa5 100644 --- a/tests/managers/thl/test_product.py +++ b/tests/managers/thl/test_product.py @@ -203,16 +203,16 @@ class TestProductManager: def test_get_by_uuid1( self, product_manager: ProductManager, - team: Team, + gr_team: Team, product: Product, product_factory: Callable[..., Product], ): - p1 = product_factory(team=team) + p1 = product_factory(team=gr_team) instance = product_manager.get_by_uuid(product_uuid=p1.uuid) assert instance.id == p1.id # No Team and no user_create_config - assert instance.team_id == team.uuid + assert instance.team_id == gr_team.uuid # user_create_config can't be None, so ensure the default was set. assert isinstance(instance.user_create_config, UserCreateConfig) diff --git a/tests/managers/thl/test_session_manager.py b/tests/managers/thl/test_session_manager.py index 67a802e..60edcb9 100644 --- a/tests/managers/thl/test_session_manager.py +++ b/tests/managers/thl/test_session_manager.py @@ -118,20 +118,20 @@ class TestSessionManagerFilter: self, product_factory: Callable[..., Product], user_factory: Callable[..., User], - team: Team, + gr_team: Team, session_manager: SessionManager, utc_hour_ago: datetime, thl_web_rr: PostgresConfig, ): - p1 = product_factory(team=team) + p1 = product_factory(team=gr_team) for _ in range(5): u = user_factory(product=p1) session_manager.create(started=utc_hour_ago, user=u, uuid_id=uuid4().hex) - team.prefetch_products(thl_pg_config=thl_web_rr) - assert len(team.product_uuids) == 1 - res = session_manager.filter(product_uuids=team.product_uuids) + gr_team.prefetch_products(thl_pg_config=thl_web_rr) + assert len(gr_team.product_uuids) == 1 + res = session_manager.filter(product_uuids=gr_team.product_uuids) assert len(res) == 5 def test_business( |
