aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstuppie2026-09-06 18:42:11 -0600
committerstuppie2026-09-06 18:42:11 -0600
commit282e224429516efbf00f6c876bfbb82be00bb266 (patch)
tree9ef8cf8c5174409f634fc1bd519f93a30b8461ce
parent5d20e51ba4149b9ba04f6a70de4f6c8ff0425fc3 (diff)
downloadgeneralresearch-282e224429516efbf00f6c876bfbb82be00bb266.tar.gz
generalresearch-282e224429516efbf00f6c876bfbb82be00bb266.zip
user cashout method to user UserRef
-rw-r--r--generalresearch/managers/thl/cashout_method.py20
-rw-r--r--generalresearch/models/thl/user.py18
-rw-r--r--test_utils/managers/cashout_methods.py90
-rw-r--r--test_utils/managers/conftest.py64
4 files changed, 78 insertions, 114 deletions
diff --git a/generalresearch/managers/thl/cashout_method.py b/generalresearch/managers/thl/cashout_method.py
index ee86bec..6e32a45 100644
--- a/generalresearch/managers/thl/cashout_method.py
+++ b/generalresearch/managers/thl/cashout_method.py
@@ -9,6 +9,7 @@ from uuid import UUID, uuid4
from pydantic import NonNegativeInt
from generalresearch.managers.base import PostgresManager
+from generalresearch.models.thl.user_ref import UserRef
from generalresearch.models.thl.wallet.definitions import PayoutType
if TYPE_CHECKING:
@@ -21,7 +22,6 @@ if TYPE_CHECKING:
class CashoutMethodManager(PostgresManager):
-
def create(self, cm: CashoutMethod) -> None:
now = datetime.now(tz=UTC)
query = """
@@ -58,9 +58,9 @@ class CashoutMethodManager(PostgresManager):
res = next(iter(db_res), None)
assert res, f"cashout method id {cm_id} not found"
# Don't let anyone delete a non-user-scoped cashout method
- assert (
- res["user_id"] is not None
- ), "error trying to delete non user-scoped cashout method"
+ assert res["user_id"] is not None, (
+ "error trying to delete non user-scoped cashout method"
+ )
self.pg_config.execute_write(
query="""
@@ -93,7 +93,7 @@ class CashoutMethodManager(PostgresManager):
max_value=25000, # $250.00
data=data,
type=PayoutType.CASH_IN_MAIL,
- user=user,
+ user=user.to_user_ref(),
ext_id=data.delivery_address.md5sum(),
)
@@ -137,7 +137,7 @@ class CashoutMethodManager(PostgresManager):
max_value=25_000, # $250.00
data=data,
type=PayoutType.PAYPAL,
- user=user,
+ user=user.to_user_ref(),
ext_id=data.email,
)
# Make sure this user doesn't already have one
@@ -159,7 +159,7 @@ class CashoutMethodManager(PostgresManager):
@staticmethod
def make_filter_str(
uuid: str | None = None,
- user: User | None = None,
+ user: UserRef | None = None,
ext_id: str | None = None,
payout_types: Collection[PayoutType] | None = None,
is_live: bool | None = True,
@@ -190,7 +190,7 @@ class CashoutMethodManager(PostgresManager):
def filter_count(
self,
uuid: str | None = None,
- user: User | None = None,
+ user: UserRef | None = None,
ext_id: str | None = None,
payout_types: Collection[PayoutType] | None = None,
is_live: bool | None = True,
@@ -215,7 +215,7 @@ class CashoutMethodManager(PostgresManager):
def filter(
self,
uuid: str | None = None,
- user: User | None = None,
+ user: UserRef | None = None,
ext_id: str | None = None,
payout_types: Collection[PayoutType] | None = None,
is_live: bool | None = True,
@@ -303,6 +303,6 @@ class CashoutMethodManager(PostgresManager):
x["data"].update(x.pop("_data_"))
x["data"]["type"] = x["type"]
if user and x["type"] in {PayoutType.PAYPAL, PayoutType.CASH_IN_MAIL}:
- x["user"] = user
+ x["user"] = user.to_user_ref()
return CashoutMethod.model_validate(x)
diff --git a/generalresearch/models/thl/user.py b/generalresearch/models/thl/user.py
index 77f9069..59a14db 100644
--- a/generalresearch/models/thl/user.py
+++ b/generalresearch/models/thl/user.py
@@ -2,19 +2,16 @@ from __future__ import annotations
import json
import logging
-import re
from datetime import UTC, datetime
-from typing import TYPE_CHECKING, Annotated, Any, Self
+from typing import TYPE_CHECKING, Any, Self
from uuid import UUID, uuid4
from pydantic import (
- AfterValidator,
AwareDatetime,
BaseModel,
ConfigDict,
Field,
PositiveInt,
- StringConstraints,
field_validator,
model_validator,
)
@@ -29,6 +26,7 @@ from generalresearch.models.thl.ipinfo import GeoIPInformation
from generalresearch.models.thl.ledger import LedgerTransaction
from generalresearch.models.thl.product import Product
from generalresearch.models.thl.user_identifiers import BPUIDStr
+from generalresearch.models.thl.user_ref import UserRef
from generalresearch.models.thl.userhealth import AuditLog
if TYPE_CHECKING:
@@ -193,6 +191,16 @@ class User(BaseModel):
d["user_id"] = self.user_id
return json.dumps(d)
+ def to_user_ref(self) -> UserRef:
+ assert self.user_id is not None
+ assert self.product_id is not None
+ assert self.product_user_id is not None
+ return UserRef(
+ user_id=self.user_id,
+ product_id=self.product_id,
+ product_user_id=self.product_user_id,
+ )
+
def set_sentry_user(self):
# https://docs.sentry.io/platforms/python/enriching-events/identify-user/
set_user(
@@ -296,6 +304,4 @@ class User(BaseModel):
)
-
-
User.model_rebuild()
diff --git a/test_utils/managers/cashout_methods.py b/test_utils/managers/cashout_methods.py
index adf82f4..e69de29 100644
--- a/test_utils/managers/cashout_methods.py
+++ b/test_utils/managers/cashout_methods.py
@@ -1,90 +0,0 @@
-from __future__ import annotations
-
-import random
-from collections.abc import Callable
-from uuid import uuid4
-
-import pytest
-
-from generalresearch.models.thl.wallet.cashout_method import (
- CashoutMethod,
- TangoCashoutMethodData,
-)
-from generalresearch.models.thl.wallet.definitions import Currency, PayoutType
-
-
-@pytest.fixture(scope="session")
-def random_ext_id_factory(base: str = "U02") -> Callable[..., str]:
-
- def _inner() -> str:
- suffix = random.randint(0, 99999)
- return f"{base}{suffix:05d}"
-
- return _inner
-
-
-@pytest.fixture(scope="session")
-def example_tango_cashout_methods(
- random_ext_id_factory: Callable[..., str],
-) -> list[CashoutMethod]:
- return [
- CashoutMethod(
- id=uuid4().hex,
- last_updated="2021-06-23T20:45:38.239182Z",
- is_live=True,
- type=PayoutType.TANGO,
- ext_id=random_ext_id_factory(),
- name="Safeway eGift Card $25",
- data=TangoCashoutMethodData(
- value_type="fixed", countries=["US"], utid=random_ext_id_factory()
- ),
- user=None,
- image_url="https://d30s7yzk2az89n.cloudfront.net/images/brands/b694446-1200w-326ppi.png",
- original_currency=Currency.USD,
- min_value=2500,
- max_value=2500,
- ),
- CashoutMethod(
- id=uuid4().hex,
- last_updated="2021-06-23T20:45:38.239182Z",
- is_live=True,
- type=PayoutType.TANGO,
- ext_id=random_ext_id_factory(),
- name="Amazon.it Gift Certificate",
- data=TangoCashoutMethodData(
- value_type="variable", countries=["IT"], utid="U006961"
- ),
- user=None,
- image_url="https://d30s7yzk2az89n.cloudfront.net/images/brands/b405753-1200w-326ppi.png",
- original_currency=Currency.EUR,
- min_value=1,
- max_value=10000,
- ),
- ]
-
-
-# AMT_ASSIGNMENT_CASHOUT_METHOD = CashoutMethod(
-# id=uuid4().hex,
-# last_updated="2021-06-23T20:45:38.239182Z",
-# is_live=True,
-# type=PayoutType.AMT,
-# ext_id=None,
-# name="AMT Assignment",
-# data=AmtCashoutMethodData(),
-# user=None,
-# min_value=1,
-# max_value=5,
-# )
-
-# AMT_BONUS_CASHOUT_METHOD = CashoutMethod(
-# id=uuid4().hex,
-# last_updated="2021-06-23T20:45:38.239182Z",
-# is_live=True,
-# type=PayoutType.AMT,
-# ext_id=None,
-# name="AMT Bonus",
-# data=AmtCashoutMethodData(),
-# user=None,
-# min_value=7,
-# max_value=4000,
-# )
diff --git a/test_utils/managers/conftest.py b/test_utils/managers/conftest.py
index 3e7b304..391e6bf 100644
--- a/test_utils/managers/conftest.py
+++ b/test_utils/managers/conftest.py
@@ -1,7 +1,10 @@
from __future__ import annotations
+import random
from collections.abc import Callable
+from datetime import datetime
from typing import TYPE_CHECKING
+from uuid import uuid4
import pytest
@@ -12,6 +15,11 @@ from generalresearch.managers.thl.user_streak import (
UserStreakManager,
)
from generalresearch.models.definitions import Source
+from generalresearch.models.thl.wallet.cashout_method import (
+ CashoutMethod,
+ TangoCashoutMethodData,
+)
+from generalresearch.models.thl.wallet.definitions import Currency, PayoutType
if TYPE_CHECKING:
from generalresearch.managers.spectrum.survey import SpectrumSurveyManager
@@ -19,7 +27,6 @@ if TYPE_CHECKING:
from generalresearch.managers.thl.ipinfo import (
GeoIpInfoManager,
IPGeonameManager,
- IPInformationManager,
)
from generalresearch.managers.thl.userhealth import (
AuditLogManager,
@@ -27,7 +34,6 @@ if TYPE_CHECKING:
UserIpHistoryManager,
)
from generalresearch.models.thl.user import User
- from generalresearch.models.thl.wallet.cashout_method import CashoutMethod
from generalresearch.pg_helper import PostgresConfig
from generalresearch.redis_helper import RedisConfig
from generalresearch.sql_helper import SqlHelper
@@ -164,17 +170,59 @@ def setup_cashoutmethod_db(
for x in example_tango_cashout_methods:
cashout_method_manager.create(x)
- # TODO: convert these ids into instances to use.
- # settings.amt_bonus_cashout_method_id
- # settings.amt_assignment_cashout_method_id
+ return _inner
+
+
+@pytest.fixture(scope="session")
+def random_ext_id_factory(base: str = "U02") -> Callable[..., str]:
- # cashout_method_manager.create(AMT_ASSIGNMENT_CASHOUT_METHOD)
- # cashout_method_manager.create(AMT_BONUS_CASHOUT_METHOD)
- # raise NotImplementedError("Need to implement setup_cashoutmethod_db")
+ def _inner() -> str:
+ suffix = random.randint(0, 99999)
+ return f"{base}{suffix:05d}"
return _inner
+@pytest.fixture(scope="session")
+def example_tango_cashout_methods(
+ random_ext_id_factory: Callable[..., str],
+) -> list[CashoutMethod]:
+ return [
+ CashoutMethod(
+ id=uuid4().hex,
+ last_updated=datetime.fromisoformat("2021-06-23T20:45:38.239182Z"),
+ is_live=True,
+ type=PayoutType.TANGO,
+ ext_id='U025035',
+ name="Safeway eGift Card $25",
+ data=TangoCashoutMethodData(
+ value_type="fixed", countries=["US"], utid='U025035'
+ ),
+ user=None,
+ image_url="https://d30s7yzk2az89n.cloudfront.net/images/brands/b694446-1200w-326ppi.png",
+ original_currency=Currency.USD,
+ min_value=2500,
+ max_value=2500,
+ ),
+ CashoutMethod(
+ id=uuid4().hex,
+ last_updated=datetime.fromisoformat("2021-06-23T20:45:38.239182Z"),
+ is_live=True,
+ type=PayoutType.TANGO,
+ ext_id='U006961',
+ name="Amazon.it Gift Certificate",
+ data=TangoCashoutMethodData(
+ value_type="variable", countries=["IT"], utid="U006961"
+ ),
+ user=None,
+ image_url="https://d30s7yzk2az89n.cloudfront.net/images/brands/b405753-1200w-326ppi.png",
+ original_currency=Currency.EUR,
+ min_value=1,
+ max_value=10000,
+ ),
+ ]
+
+
# === THL: Marketplaces ===