diff options
| author | Max Nanis | 2026-08-16 01:38:14 -0700 |
|---|---|---|
| committer | Max Nanis | 2026-08-16 01:38:14 -0700 |
| commit | 24bf43ca9643c1d13f4acd9f14435249b0839df1 (patch) | |
| tree | cb19022f44554a3b23085073503dd938a7fabe9e | |
| parent | fd77cd429cc6205f9a8f2f4168298fe82d461383 (diff) | |
| download | generalresearch-24bf43ca9643c1d13f4acd9f14435249b0839df1.tar.gz generalresearch-24bf43ca9643c1d13f4acd9f14435249b0839df1.zip | |
Pandera supression attempt. Conftest assert for type validation (no none allowed). min_items to min_length
| -rw-r--r-- | generalresearch/config.py | 3 | ||||
| -rw-r--r-- | generalresearch/models/thl/contest/contest.py | 2 | ||||
| -rw-r--r-- | generalresearch/models/thl/product.py | 2 | ||||
| -rw-r--r-- | generalresearch/models/thl/survey/__init__.py | 4 | ||||
| -rw-r--r-- | generalresearch/models/thl/survey/task_collection.py | 4 | ||||
| -rw-r--r-- | requirements.txt | 1 | ||||
| -rw-r--r-- | test_utils/__init__.py | 3 | ||||
| -rw-r--r-- | test_utils/conftest.py | 178 | ||||
| -rw-r--r-- | test_utils/managers/conftest.py | 48 | ||||
| -rw-r--r-- | tests/__init__.py | 3 | ||||
| -rw-r--r-- | tests/managers/thl/test_user_manager/test_base.py | 61 |
11 files changed, 253 insertions, 56 deletions
diff --git a/generalresearch/config.py b/generalresearch/config.py index 94885b1..92eacc2 100644 --- a/generalresearch/config.py +++ b/generalresearch/config.py @@ -1,3 +1,4 @@ +import os from datetime import datetime, timezone from pathlib import Path from typing import Optional @@ -7,6 +8,8 @@ from pydantic_settings import BaseSettings from generalresearch.models.custom_types import DaskDsn, SentryDsn +os.environ["DISABLE_PANDERA_IMPORT_WARNING"] = "True" + def is_debug() -> bool: import os diff --git a/generalresearch/models/thl/contest/contest.py b/generalresearch/models/thl/contest/contest.py index e644ae4..af5b136 100644 --- a/generalresearch/models/thl/contest/contest.py +++ b/generalresearch/models/thl/contest/contest.py @@ -53,7 +53,7 @@ class ContestBase(BaseModel, ABC): end_condition: ContestEndCondition = Field() """Defines the conditions to win one or more prizes once the contest is ended""" - prizes: List[ContestPrize] = Field(default_factory=list, min_items=1) + prizes: List[ContestPrize] = Field(default_factory=list, min_length=1) starts_at: AwareDatetimeISO = Field( description="When the contest starts", diff --git a/generalresearch/models/thl/product.py b/generalresearch/models/thl/product.py index 5889dc3..eb542e1 100644 --- a/generalresearch/models/thl/product.py +++ b/generalresearch/models/thl/product.py @@ -865,7 +865,7 @@ class Product(BaseModel, validate_assignment=True): payments_enabled: bool = Field( default=True, description="This is only to determine if ACH or Wire payments should " - "be made to the Produce.", + "be made to the Product.", ) created: Optional[AwareDatetimeISO] = Field( diff --git a/generalresearch/models/thl/survey/__init__.py b/generalresearch/models/thl/survey/__init__.py index 5feb955..8f27930 100644 --- a/generalresearch/models/thl/survey/__init__.py +++ b/generalresearch/models/thl/survey/__init__.py @@ -37,8 +37,8 @@ class MarketplaceTask(BaseModel, ABC): cpi: Decimal = Field(gt=0, le=100, decimal_places=2, max_digits=5) # In some marketplaces, a task can be targeted to one or more country or language. - country_isos: CountryISOs = Field(min_items=1) - language_isos: LanguageISOs = Field(min_items=1) + country_isos: CountryISOs = Field(min_length=1) + language_isos: LanguageISOs = Field(min_length=1) # For convenience, we'll store a single country/lang field as well, since # 99% of tasks across all marketplaces, even those that support multiple, diff --git a/generalresearch/models/thl/survey/task_collection.py b/generalresearch/models/thl/survey/task_collection.py index c41d8b9..804fb49 100644 --- a/generalresearch/models/thl/survey/task_collection.py +++ b/generalresearch/models/thl/survey/task_collection.py @@ -4,8 +4,8 @@ import logging from typing import List import pandas as pd -import pandera from pandera import DataFrameSchema +from pandera.errors import SchemaErrors from pydantic import BaseModel, ConfigDict, Field, model_validator from generalresearch.models.thl.survey import MarketplaceTask @@ -35,7 +35,7 @@ class TaskCollection(BaseModel): df = self.to_df() try: df = self._schema.validate(df, lazy=True) - except pandera.errors.SchemaErrors as exc: + except SchemaErrors as exc: idx = exc.failure_cases["index"] if len(idx) >= len(df) * 0.10: raise exc diff --git a/requirements.txt b/requirements.txt index 1f55009..6c04995 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,6 +20,7 @@ decorator==5.2.1 Deprecated==1.2.18 distributed==2025.7.0 dnspython==2.7.0 +Django>=5.2 ecdsa==0.19.1 email-validator==2.3.0 Faker==37.6.0 diff --git a/test_utils/__init__.py b/test_utils/__init__.py index e69de29..0c8e77a 100644 --- a/test_utils/__init__.py +++ b/test_utils/__init__.py @@ -0,0 +1,3 @@ +import os + +os.environ["DISABLE_PANDERA_IMPORT_WARNING"] = "True" diff --git a/test_utils/conftest.py b/test_utils/conftest.py index 0e712bb..232c1fc 100644 --- a/test_utils/conftest.py +++ b/test_utils/conftest.py @@ -1,16 +1,20 @@ import os import shutil +import sys +from datetime import datetime, timedelta, timezone from os.path import join as pjoin from pathlib import Path -from typing import TYPE_CHECKING, Callable +from typing import TYPE_CHECKING, Callable, Generator from uuid import uuid4 -from datetime import datetime, timedelta, timezone +import django import pytest import redis from _pytest.config import Config +from django.conf import settings as django_settings +from django.core.management import call_command from dotenv import load_dotenv -from pydantic import MariaDBDsn +from pydantic import MariaDBDsn, PostgresDsn from redis import Redis from generalresearch.pg_helper import PostgresConfig @@ -26,12 +30,19 @@ if TYPE_CHECKING: @pytest.fixture(scope="session") def env_file_path(pytestconfig: Config) -> str: root_path = pytestconfig.rootpath - env_path = os.path.join(root_path, ".env.test") + env_file = ".env.test" - if os.path.exists(env_path): - load_dotenv(dotenv_path=env_path, override=True) + candidates = [ + os.path.join(root_path, env_file), + os.path.join(root_path, "..", env_file), + ] - return env_path + for env_path in candidates: + if os.path.exists(env_path): + load_dotenv(dotenv_path=env_path, override=True) + return os.path.normpath(env_path) + + raise AssertionError(f"No .env.test file found in: {', '.join(candidates)}") @pytest.fixture(scope="session") @@ -57,24 +68,137 @@ def settings(env_file_path: str) -> "GRLBaseSettings": @pytest.fixture(scope="session") -def thl_web_rr(settings: "GRLBaseSettings") -> PostgresConfig: - assert settings.thl_web_rr_db is not None - assert "/unittest-" in settings.thl_web_rr_db.path +def postgres_instance(settings: "GRLBaseSettings") -> Generator[PostgresDsn]: + """Create a ephemeral postgresql instance for us to use during pytest. + + This is simplified, and only based off a single host. We don't want to + create multiple migrated tmp databases for each rw/rr/ro connection + """ + + assert settings.thl_web_rw_db + # assert settings.thl_web_rw_db.host + + dsn: PostgresDsn = settings.thl_web_rw_db + + # Connect to default DB to create the new one + from psycopg import connect + from psycopg.sql import SQL, Identifier + + now = datetime.now(timezone.utc) + ts: str = now.strftime("%Y-%m-%d") + + db_name = f"unittest-{ts}-{uuid4().hex[:6]}" + print("XXX", str(dsn)) + conn = connect(str(dsn)) + conn.autocommit = True + cur = conn.cursor() + cur.execute(SQL("CREATE DATABASE {}").format(Identifier(db_name))) + cur.close() + conn.close() + + host = dsn.hosts()[0] + db_url = ( + f"postgres://{host['username']}:{host['password']}@{host['host']}/{db_name}" + ) + + yield PostgresDsn(db_url) + + # Teardown: drop the DB after the session + conn = connect(str(dsn)) + conn.autocommit = True + cur = conn.cursor() + # cur.execute(SQL("DROP DATABASE {}").format(Identifier(db_name))) + cur.close() + conn.close() + + +@pytest.fixture(scope="session") +def django_db_setup(settings: "GRLBaseSettings") -> Callable[..., None]: + + def _inner(): + + assert settings.thl_web_rw_db + dsn: PostgresDsn = settings.thl_web_rw_db + host = dsn.hosts()[0] + + # 1. Bootstrapping Django settings + if not django_settings.configured: + django_settings.configure( + DATABASES={ + "default": { + "ENGINE": "django.db.backends.postgresql", + # PostgresDsn stores path as "/dbname" + "NAME": str(dsn.path).lstrip("/"), + "USER": host["username"], + "PASSWORD": host["password"], + "HOST": host["host"], + "PORT": "5432", + } + }, + INSTALLED_APPS=[ + "django.contrib.postgres", + "django.contrib.contenttypes", + "generalresearch.thl_django", + ], + ) + django.setup() + + from django.apps import apps + + for model in apps.get_models(): + print(f"Discovered model: {model._meta.label}") + + # 2. Run migrations directly during fixture activation + call_command("migrate") + + return _inner + + +@pytest.fixture(scope="session") +def thl_web_rr( + settings: "GRLBaseSettings", postgres_instance: PostgresDsn, django_db_setup +) -> PostgresConfig: + dsn = settings.thl_web_rr_db + assert dsn + assert dsn.path + + if dsn.path not in ["/", "/postgres"]: + assert "/unittest-" in dsn.path + + db_path = postgres_instance.path + host = dsn.hosts()[0] + db_url = f"postgres://{host['username']}:{host['password']}@{host['host']}{db_path}" + + # Run Migrations now. + django_db_setup() return PostgresConfig( - dsn=settings.thl_web_rr_db, + dsn=PostgresDsn(db_url), connect_timeout=1, statement_timeout=5, ) @pytest.fixture(scope="session") -def thl_web_rw(settings: "GRLBaseSettings") -> PostgresConfig: - assert settings.thl_web_rw_db is not None - assert "/unittest-" in settings.thl_web_rw_db.path +def thl_web_rw( + settings: "GRLBaseSettings", postgres_instance: PostgresDsn, django_db_setup +) -> PostgresConfig: + dsn = settings.thl_web_rw_db + assert dsn + assert dsn.path + + if dsn.path not in ["/", "/postgres"]: + assert "/unittest-" in dsn.path + + db_path = postgres_instance.path + host = dsn.hosts()[0] + db_url = f"postgres://{host['username']}:{host['password']}@{host['host']}{db_path}" + + # Run Migrations now. + django_db_setup() return PostgresConfig( - dsn=settings.thl_web_rw_db, + dsn=PostgresDsn(db_url), connect_timeout=1, statement_timeout=5, ) @@ -82,14 +206,24 @@ def thl_web_rw(settings: "GRLBaseSettings") -> PostgresConfig: @pytest.fixture(scope="session") def gr_db(settings: "GRLBaseSettings") -> PostgresConfig: - assert "/unittest-" in settings.gr_db.path + dsn = settings.gr_db + assert dsn + assert dsn.path + + if dsn.path not in ["/", "/postgres"]: + assert "/unittest-" in dsn.path + return PostgresConfig(dsn=settings.gr_db, connect_timeout=5, statement_timeout=2) @pytest.fixture(scope="session") def spectrum_rw(settings: "GRLBaseSettings") -> SqlHelper: - assert settings.spectrum_rw_db is not None - assert "/unittest-" in settings.spectrum_rw_db.path + dsn = settings.spectrum_rw_db + assert dsn + assert dsn.path + + if dsn.path not in ["/", "/postgres"]: + assert "/unittest-" in dsn.path return SqlHelper( dsn=settings.spectrum_rw_db, @@ -101,8 +235,12 @@ def spectrum_rw(settings: "GRLBaseSettings") -> SqlHelper: @pytest.fixture(scope="session") def grliq_db(settings: "GRLBaseSettings") -> PostgresConfig: - assert settings.grliq_db is not None - assert "/unittest-" in settings.grliq_db.path + dsn = settings.grliq_db + assert dsn + assert dsn.path + + if dsn.path not in ["/", "/postgres"]: + assert "/unittest-" in dsn.path # test_words = {"localhost", "127.0.0.1", "unittest", "grliq-test"} # assert any(w in str(postgres_config.dsn) for w in test_words), "check grliq postgres_config" diff --git a/test_utils/managers/conftest.py b/test_utils/managers/conftest.py index 10ee8ea..c8a6e2f 100644 --- a/test_utils/managers/conftest.py +++ b/test_utils/managers/conftest.py @@ -91,6 +91,7 @@ if TYPE_CHECKING: def ltxm( thl_web_rw: PostgresConfig, thl_redis_config: RedisConfig ) -> "LedgerTransactionManager": + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.ledger_manager.ledger import ( @@ -109,6 +110,7 @@ def ltxm( def lam( thl_web_rw: PostgresConfig, thl_redis_config: RedisConfig ) -> "LedgerAccountManager": + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.ledger_manager.ledger import ( @@ -125,6 +127,7 @@ def lam( @pytest.fixture(scope="session") def lm(thl_web_rw: PostgresConfig, thl_redis_config: RedisConfig) -> "LedgerManager": + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.ledger_manager.ledger import ( @@ -148,6 +151,7 @@ def lm(thl_web_rw: PostgresConfig, thl_redis_config: RedisConfig) -> "LedgerMana def thl_lm( thl_web_rw: PostgresConfig, thl_redis_config: RedisConfig ) -> "ThlLedgerManager": + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.ledger_manager.thl_ledger import ( @@ -171,6 +175,7 @@ def thl_lm( def payout_event_manager( thl_web_rw: PostgresConfig, thl_redis_config: RedisConfig ) -> "PayoutEventManager": + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.payout import PayoutEventManager @@ -186,6 +191,7 @@ def payout_event_manager( def user_payout_event_manager( thl_web_rw: PostgresConfig, thl_redis_config: RedisConfig ) -> "UserPayoutEventManager": + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.payout import UserPayoutEventManager @@ -201,6 +207,7 @@ def user_payout_event_manager( def brokerage_product_payout_event_manager( thl_web_rw: PostgresConfig, thl_redis_config: RedisConfig ) -> "BrokerageProductPayoutEventManager": + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.payout import ( @@ -218,6 +225,7 @@ def brokerage_product_payout_event_manager( def business_payout_event_manager( thl_web_rw: PostgresConfig, thl_redis_config: RedisConfig ) -> "BusinessPayoutEventManager": + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.payout import ( @@ -233,6 +241,8 @@ def business_payout_event_manager( @pytest.fixture(scope="session") def product_manager(thl_web_rw: PostgresConfig) -> "ProductManager": + assert thl_web_rw.dsn + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.product import ProductManager @@ -244,6 +254,10 @@ def product_manager(thl_web_rw: PostgresConfig) -> "ProductManager": def user_manager( settings: "GRLBaseSettings", thl_web_rw: PostgresConfig, thl_web_rr: PostgresConfig ) -> "UserManager": + assert thl_web_rw.dsn + assert thl_web_rw.dsn.path + assert thl_web_rr.dsn + assert thl_web_rr.dsn.path assert "/unittest-" in thl_web_rw.dsn.path assert "/unittest-" in thl_web_rr.dsn.path @@ -260,6 +274,8 @@ def user_manager( @pytest.fixture(scope="session") def user_metadata_manager(thl_web_rw: PostgresConfig) -> "UserMetadataManager": + assert thl_web_rw.dsn + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.user_manager.user_metadata_manager import ( @@ -271,6 +287,8 @@ def user_metadata_manager(thl_web_rw: PostgresConfig) -> "UserMetadataManager": @pytest.fixture(scope="session") def session_manager(thl_web_rw: PostgresConfig) -> "SessionManager": + assert thl_web_rw.dsn + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.session import SessionManager @@ -280,6 +298,8 @@ def session_manager(thl_web_rw: PostgresConfig) -> "SessionManager": @pytest.fixture(scope="session") def wall_manager(thl_web_rw: PostgresConfig) -> "WallManager": + assert thl_web_rw.dsn + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.wall import WallManager @@ -311,6 +331,8 @@ def task_adjustment_manager(thl_web_rw: PostgresConfig) -> "TaskAdjustmentManage @pytest.fixture(scope="session") def contest_manager(thl_web_rw: PostgresConfig) -> "ContestManager": + assert thl_web_rw.dsn + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.contest_manager import ContestManager @@ -328,6 +350,8 @@ def contest_manager(thl_web_rw: PostgresConfig) -> "ContestManager": @pytest.fixture(scope="session") def category_manager(thl_web_rw: PostgresConfig) -> "CategoryManager": + assert thl_web_rw.dsn + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.category import CategoryManager @@ -367,6 +391,7 @@ def surveypenalty_manager(thl_redis_config: RedisConfig): @pytest.fixture(scope="session") def upk_schema_manager(thl_web_rw: PostgresConfig): + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.profiling.schema import ( UpkSchemaManager, @@ -377,6 +402,7 @@ def upk_schema_manager(thl_web_rw: PostgresConfig): @pytest.fixture(scope="session") def user_upk_manager(thl_web_rw: PostgresConfig, thl_redis_config: RedisConfig): + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.profiling.user_upk import ( UserUpkManager, @@ -387,6 +413,7 @@ def user_upk_manager(thl_web_rw: PostgresConfig, thl_redis_config: RedisConfig): @pytest.fixture(scope="session") def question_manager(thl_web_rw: PostgresConfig, thl_redis_config: RedisConfig): + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.profiling.question import ( QuestionManager, @@ -397,6 +424,7 @@ def question_manager(thl_web_rw: PostgresConfig, thl_redis_config: RedisConfig): @pytest.fixture(scope="session") def uqa_manager(thl_web_rw: PostgresConfig, thl_redis_config: RedisConfig): + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.profiling.uqa import UQAManager @@ -414,6 +442,7 @@ def uqa_manager_clear_cache(uqa_manager, user: "User"): @pytest.fixture(scope="session") def audit_log_manager(thl_web_rw: PostgresConfig) -> "AuditLogManager": + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.userhealth import AuditLogManager @@ -423,6 +452,7 @@ def audit_log_manager(thl_web_rw: PostgresConfig) -> "AuditLogManager": @pytest.fixture(scope="session") def ip_geoname_manager(thl_web_rw: PostgresConfig) -> "IPGeonameManager": + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.ipinfo import IPGeonameManager @@ -432,6 +462,7 @@ def ip_geoname_manager(thl_web_rw: PostgresConfig) -> "IPGeonameManager": @pytest.fixture(scope="session") def ip_information_manager(thl_web_rw: PostgresConfig) -> "IPInformationManager": + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.ipinfo import IPInformationManager @@ -443,6 +474,7 @@ def ip_information_manager(thl_web_rw: PostgresConfig) -> "IPInformationManager" def ip_record_manager( thl_web_rw: PostgresConfig, thl_redis_config: RedisConfig ) -> "IPRecordManager": + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.userhealth import IPRecordManager @@ -454,6 +486,7 @@ def ip_record_manager( def user_iphistory_manager( thl_web_rw: PostgresConfig, thl_redis_config: RedisConfig ) -> "UserIpHistoryManager": + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.userhealth import ( @@ -476,6 +509,7 @@ def user_iphistory_manager_clear_cache(user_iphistory_manager, user): def geoipinfo_manager( thl_web_rw: PostgresConfig, thl_redis_config: RedisConfig ) -> "GeoIpInfoManager": + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.ipinfo import GeoIpInfoManager @@ -502,6 +536,7 @@ def maxmind_manager( thl_web_rw: PostgresConfig, thl_redis_config: RedisConfig, ) -> "MaxmindManager": + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.maxmind import MaxmindManager @@ -516,6 +551,7 @@ def maxmind_manager( @pytest.fixture(scope="session") def cashout_method_manager(thl_web_rw: PostgresConfig): + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.cashout_method import ( CashoutMethodManager, @@ -533,6 +569,7 @@ def event_manager(thl_redis_config: RedisConfig): @pytest.fixture(scope="session") def user_streak_manager(thl_web_rw: PostgresConfig): + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path from generalresearch.managers.thl.user_streak import ( UserStreakManager, @@ -545,6 +582,7 @@ def user_streak_manager(thl_web_rw: PostgresConfig): def uqa_db_index(thl_web_rw: PostgresConfig): # There were some custom indices created not through django. # Make sure the index used in the index hint exists + assert thl_web_rw.dsn.path assert "/unittest-" in thl_web_rw.dsn.path # query = f"""create index idx_user_id @@ -605,6 +643,7 @@ def business_manager( ) -> "BusinessManager": from generalresearch.redis_helper import RedisConfig + assert gr_db.dsn.path assert "/unittest-" in gr_db.dsn.path assert isinstance(gr_redis_config, RedisConfig) @@ -618,6 +657,7 @@ def business_manager( @pytest.fixture(scope="session") def business_address_manager(gr_db: PostgresConfig) -> "BusinessAddressManager": + assert gr_db.dsn.path assert "/unittest-" in gr_db.dsn.path from generalresearch.managers.gr.business import BusinessAddressManager @@ -629,6 +669,7 @@ def business_address_manager(gr_db: PostgresConfig) -> "BusinessAddressManager": def business_bank_account_manager( gr_db: PostgresConfig, ) -> "BusinessBankAccountManager": + assert gr_db.dsn.path assert "/unittest-" in gr_db.dsn.path from generalresearch.managers.gr.business import ( @@ -640,6 +681,7 @@ def business_bank_account_manager( @pytest.fixture(scope="session") def team_manager(gr_db: PostgresConfig, gr_redis_config: RedisConfig) -> "TeamManager": + assert gr_db.dsn.path assert "/unittest-" in gr_db.dsn.path from generalresearch.managers.gr.team import TeamManager @@ -649,6 +691,7 @@ def team_manager(gr_db: PostgresConfig, gr_redis_config: RedisConfig) -> "TeamMa @pytest.fixture(scope="session") def gr_um(gr_db: PostgresConfig, gr_redis_config: RedisConfig) -> "GRUserManager": + assert gr_db.dsn.path assert "/unittest-" in gr_db.dsn.path from generalresearch.managers.gr.authentication import GRUserManager @@ -658,6 +701,7 @@ def gr_um(gr_db: PostgresConfig, gr_redis_config: RedisConfig) -> "GRUserManager @pytest.fixture(scope="session") def gr_tm(gr_db: PostgresConfig) -> "GRTokenManager": + assert gr_db.dsn.path assert "/unittest-" in gr_db.dsn.path from generalresearch.managers.gr.authentication import GRTokenManager @@ -667,6 +711,7 @@ def gr_tm(gr_db: PostgresConfig) -> "GRTokenManager": @pytest.fixture(scope="session") def membership_manager(gr_db: PostgresConfig) -> "MembershipManager": + assert gr_db.dsn.path assert "/unittest-" in gr_db.dsn.path from generalresearch.managers.gr.team import MembershipManager @@ -679,6 +724,7 @@ def membership_manager(gr_db: PostgresConfig) -> "MembershipManager": @pytest.fixture(scope="session") def grliq_dm(grliq_db: PostgresConfig) -> "GrlIqDataManager": + assert grliq_db.dsn.path assert "/unittest-" in grliq_db.dsn.path from generalresearch.grliq.managers.forensic_data import ( @@ -690,6 +736,7 @@ def grliq_dm(grliq_db: PostgresConfig) -> "GrlIqDataManager": @pytest.fixture(scope="session") def grliq_em(grliq_db: PostgresConfig) -> "GrlIqEventManager": + assert grliq_db.dsn.path assert "/unittest-" in grliq_db.dsn.path from generalresearch.grliq.managers.forensic_events import ( @@ -701,6 +748,7 @@ def grliq_em(grliq_db: PostgresConfig) -> "GrlIqEventManager": @pytest.fixture(scope="session") def grliq_crr(grliq_db: PostgresConfig) -> "GrlIqCategoryResultsReader": + assert grliq_db.dsn.path assert "/unittest-" in grliq_db.dsn.path from generalresearch.grliq.managers.forensic_results import ( diff --git a/tests/__init__.py b/tests/__init__.py index e69de29..0c8e77a 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -0,0 +1,3 @@ +import os + +os.environ["DISABLE_PANDERA_IMPORT_WARNING"] = "True" diff --git a/tests/managers/thl/test_user_manager/test_base.py b/tests/managers/thl/test_user_manager/test_base.py index 3c7ee38..0d7ffef 100644 --- a/tests/managers/thl/test_user_manager/test_base.py +++ b/tests/managers/thl/test_user_manager/test_base.py @@ -12,77 +12,78 @@ from generalresearch.managers.thl.user_manager import ( from generalresearch.managers.thl.user_manager.rate_limit import ( RateLimitItemPerHourConstantKey, ) -from generalresearch.models.thl.product import UserCreateConfig, Product -from generalresearch.models.thl.user import User -from test_utils.models.conftest import ( - user, - product, - user_manager, - product_manager, +from generalresearch.managers.thl.user_manager.user_manager import ( + UserManager, ) +from generalresearch.models.thl.product import Product, UserCreateConfig +from generalresearch.models.thl.user import User logger = logging.getLogger() class TestUserManager: + @pytest.fixture(autouse=True) + def _setup(self, user_manager: UserManager, user: User): + self.user: User = user + self.user_manager: UserManager = user_manager - def test_copying_lru_cache(self, user_manager, user): + def test_copying_lru_cache(self): # Before adding the deepcopy_return decorator, this would fail b/c the returned user # is mutable, and it would mutate in the cache # user_manager = self.get_user_manager() - user_manager.clear_user_inmemory_cache(user) - u = user_manager.get_user(user_id=user.user_id) + self.user_manager.clear_user_inmemory_cache(self.user) + u = self.user_manager.get_user(user_id=self.user.user_id) assert not u.blocked u.blocked = True - u = user_manager.get_user(user_id=user.user_id) + u = self.user_manager.get_user(user_id=self.user.user_id) assert not u.blocked - def test_get_user_no_inmemory(self, user, user_manager): - user_manager.clear_user_inmemory_cache(user) - user_manager.get_user.__wrapped__.cache_clear() - u = user_manager.get_user(user_id=user.user_id) + def test_get_user_no_inmemory(self): + self.user_manager.clear_user_inmemory_cache(self.user) + self.user_manager.get_user.__wrapped__.cache_clear() + u = self.user_manager.get_user(user_id=self.user.user_id) # this should hit mysql - assert u == user + assert u == self.user - cache_info = user_manager.get_user.__wrapped__.cache_info() + cache_info = self.user_manager.get_user.__wrapped__.cache_info() assert cache_info.hits == 0, cache_info assert cache_info.misses == 1, cache_info # this should hit the lru cache - u = user_manager.get_user(user_id=user.user_id) - assert u == user + u = self.user_manager.get_user(user_id=self.user.user_id) + assert u == self.user - cache_info = user_manager.get_user.__wrapped__.cache_info() + cache_info = self.user_manager.get_user.__wrapped__.cache_info() assert cache_info.hits == 1, cache_info assert cache_info.misses == 1, cache_info - def test_get_user_with_inmemory(self, user_manager, user): + def test_get_user_with_inmemory(self): # user_manager = self.get_user_manager() - user_manager.set_user_inmemory_cache(user) - user_manager.get_user.__wrapped__.cache_clear() - u = user_manager.get_user(user_id=user.user_id) + self.user_manager.set_user_inmemory_cache(self.user) + self.user_manager.get_user.__wrapped__.cache_clear() + u = self.user_manager.get_user(user_id=self.user.user_id) # this should hit inmemory cache - assert u == user + assert u == self.user - cache_info = user_manager.get_user.__wrapped__.cache_info() + cache_info = self.user_manager.get_user.__wrapped__.cache_info() assert cache_info.hits == 0, cache_info assert cache_info.misses == 1, cache_info # this should hit the lru cache - u = user_manager.get_user(user_id=user.user_id) - assert u == user + u = self.user_manager.get_user(user_id=self.user.user_id) + assert u == self.user - cache_info = user_manager.get_user.__wrapped__.cache_info() + cache_info = self.user_manager.get_user.__wrapped__.cache_info() assert cache_info.hits == 1, cache_info assert cache_info.misses == 1, cache_info class TestBlockUserManager: - def test_block_user(self, product, user_manager): + def test_block_user(self, product, user_manager: UserManager): product_user_id = f"user-{uuid4().hex[:10]}" # mysql_user_manager to skip user creation limit check |
