diff options
| author | stuppie | 2026-08-18 19:09:22 -0600 |
|---|---|---|
| committer | stuppie | 2026-08-18 19:09:22 -0600 |
| commit | 28729d407470407bbc78bc7fb6574953b2f03f59 (patch) | |
| tree | 698a5820105f0ff02c93b5205faee7747fcb6ad9 /tests/models/thl/test_product.py | |
| parent | 4d4fce08f3a4c9dbd78fdacf3193b345cf982da3 (diff) | |
| parent | 0742210fc7eaa54d8068bfd18414158dc9b33672 (diff) | |
| download | generalresearch-28729d407470407bbc78bc7fb6574953b2f03f59.tar.gz generalresearch-28729d407470407bbc78bc7fb6574953b2f03f59.zip | |
Merge branch 'master' of ssh://code.g-r-l.com/generalresearch
Diffstat (limited to 'tests/models/thl/test_product.py')
| -rw-r--r-- | tests/models/thl/test_product.py | 186 |
1 files changed, 91 insertions, 95 deletions
diff --git a/tests/models/thl/test_product.py b/tests/models/thl/test_product.py index 52f60c2..5e9b249 100644 --- a/tests/models/thl/test_product.py +++ b/tests/models/thl/test_product.py @@ -1,26 +1,39 @@ import os import shutil -from datetime import datetime, timezone, timedelta +from datetime import datetime, timedelta, timezone from decimal import Decimal -from typing import Optional +from typing import Callable, Optional from uuid import uuid4 import pytest +from dask.distributed import Client as DaskClient from pydantic import ValidationError from generalresearch.currency import USDCent +from generalresearch.incite import GRLDatasets +from generalresearch.incite.mergers.pop_ledger import PopLedgerMerge +from generalresearch.managers.thl.ledger_manager.thl_ledger import ( + ThlLedgerManager, +) +from generalresearch.managers.thl.product import ProductManager from generalresearch.models import Source +from generalresearch.models.gr.business import Business +from generalresearch.models.thl.finance import ProductBalances from generalresearch.models.thl.product import ( - Product, + BrokerageProductPayoutEvent, + BrokerageProductPayoutEventManager, + IntegrationMode, PayoutConfig, PayoutTransformation, + Product, ProfilingConfig, + SourceConfig, SourcesConfig, - IntegrationMode, SupplyConfig, - SourceConfig, SupplyPolicy, ) +from generalresearch.models.thl.session import Session +from generalresearch.models.thl.user import User class TestProduct: @@ -28,11 +41,11 @@ class TestProduct: def test_init(self): # By default, just a Pydantic instance doesn't have an id_int instance = Product.model_validate( - dict( - id="968a9acc79b74b6fb49542d82516d284", - name="test-968a9acc", - redirect_url="https://www.google.com/hey", - ) + obj={ + "id": "968a9acc79b74b6fb49542d82516d284", + "name": "test-968a9acc", + "redirect_url": "https://www.google.com/hey", + } ) assert instance.id_int is None @@ -40,29 +53,31 @@ class TestProduct: # We're not excluding anything here, only in the "*Out" variants assert "id_int" in res - def test_init_db(self, product_manager): + def test_init_db(self, product_manager: ProductManager): # By default, just a Pydantic instance doesn't have an id_int instance = product_manager.create_dummy() assert isinstance(instance.id_int, int) res = instance.model_dump_json() + assert isinstance(res, Product) # we json skip & exclude res = instance.model_dump() + assert isinstance(res, Product) def test_redirect_url(self): p = Product.model_validate( - dict( - id="968a9acc79b74b6fb49542d82516d284", - created="2023-09-21T22:13:09.274672Z", - commission_pct=Decimal("0.05"), - enabled=True, - sources=[{"name": "d", "active": True}], - name="test-968a9acc", - max_session_len=600, - team_id="8b5e94afd8a246bf8556ad9986486baa", - redirect_url="https://www.google.com/hey", - ) + obj={ + "id": "968a9acc79b74b6fb49542d82516d284", + "created": "2023-09-21T22:13:09.274672Z", + "commission_pct": Decimal("0.05"), + "enabled": True, + "sources": [{"name": "d", "active": True}], + "name": "test-968a9acc", + "max_session_len": 600, + "team_id": "8b5e94afd8a246bf8556ad9986486baa", + "redirect_url": "https://www.google.com/hey", + } ) with pytest.raises(expected_exception=ValidationError): @@ -99,14 +114,14 @@ class TestProduct: p.harmonizer_domain = "https://profile.generalresearch.com/" p.harmonizer_domain = "https://profile.generalresearch.com" assert p.harmonizer_domain == "https://profile.generalresearch.com/" - with pytest.raises(expected_exception=Exception): + with pytest.raises(expected_exception=ValueError): p.harmonizer_domain = "" - with pytest.raises(expected_exception=Exception): + with pytest.raises(expected_exception=ValueError): p.harmonizer_domain = None - with pytest.raises(expected_exception=Exception): + with pytest.raises(expected_exception=ValueError): # no https p.harmonizer_domain = "http://profile.generalresearch.com" - with pytest.raises(expected_exception=Exception): + with pytest.raises(expected_exception=ValueError): # "/a" at the end p.harmonizer_domain = "https://profile.generalresearch.com/a" @@ -201,23 +216,29 @@ class TestProduct: assert p.calculate_user_payment( Decimal("0.10"), user_wallet_balance=Decimal(0) ) == Decimal("0.07") + assert p.calculate_user_payment( Decimal("1.05"), user_wallet_balance=Decimal(0) ) == Decimal("0.97") + assert p.calculate_user_payment( Decimal(".05"), user_wallet_balance=Decimal(1) ) == Decimal("0.02") + # final balance will be <0, so pay the full amount assert p.calculate_user_payment( Decimal(".50"), user_wallet_balance=Decimal(-1) ) == p.calculate_user_payment(Decimal("0.50")) + # final balance will be >0, so do the 7c rounding - assert p.calculate_user_payment( + res1 = p.calculate_user_payment( Decimal(".50"), user_wallet_balance=Decimal("-0.10") - ) == ( - p.calculate_user_payment(Decimal(".40"), user_wallet_balance=Decimal(0)) - - Decimal("-0.10") ) + res2 = p.calculate_user_payment( + bp_payout=Decimal(".40"), user_wallet_balance=Decimal(0) + ) + assert res2 + assert res1 == (res2 - Decimal("-0.10")) def test_payout_xform_none(self): p = Product( @@ -568,34 +589,26 @@ class TestProductFinancials: def test_balance( self, - business, - product_factory, - user_factory, - mnt_filepath, - bp_payout_factory, - thl_lm, - lm, - duration, - offset, - thl_redis_config, - start, - thl_web_rr, - brokerage_product_payout_event_manager, - session_with_tx_factory, + business: Business, + product_factory: Callable[..., Product], + user_factory: Callable[..., User], + mnt_filepath: GRLDatasets, + bp_payout_factory: Callable[..., BrokerageProductPayoutEvent], + thl_lm: ThlLedgerManager, + start: datetime, + brokerage_product_payout_event_manager: BrokerageProductPayoutEventManager, + session_with_tx_factory: Callable[..., Session], delete_ledger_db, create_main_accounts, - client_no_amm, + client_no_amm: DaskClient, ledger_collection, - pop_ledger_merge, + pop_ledger_merge: PopLedgerMerge, delete_df_collection, ): delete_ledger_db() create_main_accounts() delete_df_collection(coll=ledger_collection) - from generalresearch.models.thl.product import Product - from generalresearch.models.thl.user import User - from generalresearch.models.thl.finance import ProductBalances from generalresearch.currency import USDCent p1: Product = product_factory(business=business) @@ -759,20 +772,16 @@ class TestProductBalance: def test_inconsistent( self, - product, - mnt_filepath, - thl_lm, - client_no_amm, - thl_redis_config, - brokerage_product_payout_event_manager, + product: Product, + mnt_filepath: GRLDatasets, + thl_lm: ThlLedgerManager, + client_no_amm: DaskClient, delete_ledger_db, create_main_accounts, delete_df_collection, ledger_collection, - business, - user_factory, - product_factory, - session_with_tx_factory, + user_factory: Callable[..., User], + session_with_tx_factory: Callable[..., Session], pop_ledger_merge, start, bp_payout_factory, @@ -817,22 +826,18 @@ class TestProductBalance: def test_not_inconsistent( self, - product, + product: Product, mnt_filepath, - thl_lm, - client_no_amm, - thl_redis_config, - brokerage_product_payout_event_manager, + thl_lm: ThlLedgerManager, + client_no_amm: DaskClient, delete_ledger_db, create_main_accounts, delete_df_collection, ledger_collection, - business, - user_factory, - product_factory, + user_factory: Callable[..., User], session_with_tx_factory, - pop_ledger_merge, - start, + pop_ledger_merge: PopLedgerMerge, + start: datetime, bp_payout_factory, payout_event_manager, ): @@ -896,22 +901,16 @@ class TestProductPOPFinancial: self, product, mnt_filepath, - thl_lm, + thl_lm: ThlLedgerManager, client_no_amm, - thl_redis_config, - brokerage_product_payout_event_manager, delete_ledger_db, create_main_accounts, delete_df_collection, ledger_collection, - business, - user_factory, - product_factory, + user_factory: Callable[..., User], session_with_tx_factory, - pop_ledger_merge, - start, - bp_payout_factory, - payout_event_manager, + pop_ledger_merge: PopLedgerMerge, + start: datetime, ): # This is very similar to the test_complete_payout_pq_inconsistent # test, however this time we're only going to assign the payout @@ -975,22 +974,20 @@ class TestProductCache: def test_basic( self, - product, + product: Product, mnt_filepath, thl_lm, - client_no_amm, + client_no_amm: DaskClient, thl_redis_config, brokerage_product_payout_event_manager, delete_ledger_db, create_main_accounts, delete_df_collection, ledger_collection, - business, - user_factory, - product_factory, + user_factory: Callable[..., User], session_with_tx_factory, - pop_ledger_merge, - start, + pop_ledger_merge: PopLedgerMerge, + start: datetime, ): # Now let's load it up and actually test some things delete_ledger_db() @@ -999,7 +996,7 @@ class TestProductCache: # Confirm the default / null behavior rc = thl_redis_config.create_redis_client() - res: Optional[str] = rc.get(product.cache_key) + res: str | None = rc.get(product.cache_key) assert res is None with pytest.raises(expected_exception=AssertionError): product.set_cache( @@ -1034,13 +1031,14 @@ class TestProductCache: ) # Fetch from cache and assert the instance loaded from redis - res: Optional[str] = rc.get(product.cache_key) + res: str | None = rc.get(product.cache_key) assert isinstance(res, str) from generalresearch.models.thl.ledger import LedgerAccount assert isinstance(product.bp_account, LedgerAccount) p1: Product = Product.model_validate_json(res) + assert isinstance(p1.balance, ProductBalances) assert p1.balance.product_id == product.uuid assert p1.balance.payout_usd_str == "$0.71" assert p1.balance.retainer_usd_str == "$0.17" @@ -1048,22 +1046,20 @@ class TestProductCache: def test_neg_balance_cache( self, - product, + product: Product, mnt_filepath, thl_lm, - client_no_amm, + client_no_amm: DaskClient, thl_redis_config, brokerage_product_payout_event_manager, delete_ledger_db, create_main_accounts, delete_df_collection, ledger_collection, - business, - user_factory, - product_factory, + user_factory: Callable[..., User], session_with_tx_factory, - pop_ledger_merge, - start, + pop_ledger_merge: PopLedgerMerge, + start: datetime, bp_payout_factory, payout_event_manager, adj_to_fail_with_tx_factory, |
