aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--Jenkinsfile24
-rw-r--r--README.md22
-rw-r--r--generalresearch/managers/thl/delete_request.py2
-rw-r--r--generalresearch/managers/thl/userhealth.py2
-rw-r--r--generalresearch/models/thl/offerwall/base.py2
-rw-r--r--generalresearch/thl_django/README.md2
-rw-r--r--generalresearch/thl_django/event/models.py4
-rw-r--r--generalresearch/wxet/models/definitions.py2
-rw-r--r--test_utils/managers/ledger/conftest.py3
-rw-r--r--test_utils/managers/network/conftest.py4
-rw-r--r--tests/models/network/test_nmap_parser.py2
-rw-r--r--tests/models/thl/test_contest/test_raffle_contest.py10
-rw-r--r--tests/models/thl/test_marketplace_condition.py26
-rw-r--r--tests/models/thl/test_payout_format.py10
-rw-r--r--tests/models/thl/test_product.py127
-rw-r--r--tests/models/thl/test_product_userwalletconfig.py1
-rw-r--r--tests/models/thl/test_upkquestion.py22
-rw-r--r--tests/models/thl/test_user.py11
-rw-r--r--tests/models/thl/test_user_streak.py6
-rw-r--r--tests/models/thl/test_wall.py4
-rw-r--r--tests/wall_status_codes/test_analyze.py24
22 files changed, 159 insertions, 154 deletions
diff --git a/.gitignore b/.gitignore
index df17d04..c7c1d0b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,4 +7,5 @@ __pycache__
generalresearch/resources/brokerage_trust_calculated.csv
tests/.env.test
.env.*
-.DS_Store \ No newline at end of file
+.DS_Store
+build/ \ No newline at end of file
diff --git a/Jenkinsfile b/Jenkinsfile
index 05c4617..a684caf 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -11,7 +11,7 @@ pipeline {
}
environment {
- VENV = "${env.WORKSPACE}/py-utils-venv"
+ VENV = "${env.WORKSPACE}/generalresearch-venv"
SPECTRUM_CARER_VENV = "${env.WORKSPACE}/thl-spectrum-carer-venv"
GRLIQ_CARER_VENV = "${env.WORKSPACE}/grliq-carer-venv"
GR_CARER_VENV = "${env.WORKSPACE}/gr-carer-venv"
@@ -26,7 +26,7 @@ pipeline {
axes {
axis {
name 'PYTHON_VERSION'
- values 'python3.13', 'python3.12', 'python3.11', 'python3.10'
+ values 'python3.14' 'python3.13', 'python3.12', 'python3.11', 'python3.10'
}
}
@@ -99,13 +99,13 @@ pipeline {
sh 'pwd -P'
}
- dir("py-utils:$PYTHON_VERSION/") {
+ dir("generalresearch:$PYTHON_VERSION/") {
checkout scmGit(
branches: [[name: env.BRANCH_NAME]],
extensions: [ cloneOption(shallow: true) ],
userRemoteConfigs: [
[credentialsId: 'abdeb570-b708-44f3-b857-8a6b06ed9822',
- url: 'ssh://code.g-r-l.com:6611/py-utils']
+ url: 'ssh://code.g-r-l.com:6611/generalresearch']
],
)
}
@@ -147,7 +147,7 @@ pipeline {
stage('Env & Migration') {
steps {
- dir("py-utils:$PYTHON_VERSION/") {
+ dir("generalresearch:$PYTHON_VERSION/") {
sh "/usr/local/bin/$PYTHON_VERSION -m venv $VENV-$PYTHON_VERSION"
sh "$VENV-$PYTHON_VERSION/bin/pip install -U setuptools wheel pip"
sh "$VENV-$PYTHON_VERSION/bin/pip install -r requirements.txt"
@@ -205,7 +205,7 @@ pipeline {
expression { return true }
}
steps {
- dir("py-utils:$PYTHON_VERSION") {
+ dir("generalresearch:$PYTHON_VERSION") {
sh "$VENV-$PYTHON_VERSION/bin/pytest -v tests/sql_helper.py"
}
}
@@ -216,7 +216,7 @@ pipeline {
expression { return true }
}
steps {
- dir("py-utils:$PYTHON_VERSION") {
+ dir("generalresearch:$PYTHON_VERSION") {
sh "$VENV-$PYTHON_VERSION/bin/pytest -v tests/models"
}
}
@@ -224,7 +224,7 @@ pipeline {
stage('managers') {
steps {
- dir("py-utils:$PYTHON_VERSION") {
+ dir("generalresearch:$PYTHON_VERSION") {
sh "$VENV-$PYTHON_VERSION/bin/pytest -v tests/managers"
}
}
@@ -232,7 +232,7 @@ pipeline {
stage('wall_status_codes') {
steps {
- dir("py-utils:$PYTHON_VERSION") {
+ dir("generalresearch:$PYTHON_VERSION") {
sh "$VENV-$PYTHON_VERSION/bin/pytest -v tests/wall_status_codes"
}
}
@@ -240,7 +240,7 @@ pipeline {
stage('wxet') {
steps {
- dir("py-utils:$PYTHON_VERSION") {
+ dir("generalresearch:$PYTHON_VERSION") {
sh "$VENV-$PYTHON_VERSION/bin/pytest -v tests/wxet"
}
}
@@ -248,7 +248,7 @@ pipeline {
stage('grliq') {
steps {
- dir("py-utils:$PYTHON_VERSION") {
+ dir("generalresearch:$PYTHON_VERSION") {
sh "$VENV-$PYTHON_VERSION/bin/pytest -v tests/grliq"
}
}
@@ -256,7 +256,7 @@ pipeline {
stage('incite') {
steps {
- dir("py-utils:$PYTHON_VERSION") {
+ dir("generalresearch:$PYTHON_VERSION") {
sh "$VENV-$PYTHON_VERSION/bin/pytest -v tests/incite"
}
}
diff --git a/README.md b/README.md
index 7315013..f403d54 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# [generalresearch](https://git.generalresearch.com/generalresearch/) · [![license](https://cdn.generalresearch.com/buildStatus/icon?subject=license&status=Priority&color=blue)](./LICENSE) ![master](https://cdn.generalresearch.com/buildStatus/icon?subject=master&job=py-utils%2Fmaster) ![python](https://cdn.generalresearch.com/buildStatus/icon?subject=Python&status=3.12.11&color=blue)
+# [generalresearch](https://git.generalresearch.com/generalresearch/) · [![license](https://cdn.generalresearch.com/buildStatus/icon?subject=license&status=Priority&color=blue)](./LICENSE) ![master](https://cdn.generalresearch.com/buildStatus/icon?subject=master&job=generalresearch%2Fmaster) ![python](https://cdn.generalresearch.com/buildStatus/icon?subject=Python&status=3.12.11&color=blue)
@@ -24,37 +24,37 @@ pip install --force-reinstall psycopg[binary]
</tr>
<tr>
<td>
- <img src="https://cdn.generalresearch.com/buildStatus/icon?subject=master&job=py-utils%2Fmaster">
+ <img src="https://cdn.generalresearch.com/buildStatus/icon?subject=master&job=generalresearch%2Fmaster">
</td>
<td>
- <a href="https://code.g-r-l.com/py-utils/~files/v2.2.0">
- <img src="https://cdn.generalresearch.com/buildStatus/icon?subject=2.2.0&job=py-utils%2Fv2.2.0">
+ <a href="https://code.g-r-l.com/generalresearch/~files/v2.2.0">
+ <img src="https://cdn.generalresearch.com/buildStatus/icon?subject=2.2.0&job=generalresearch%2Fv2.2.0">
</a>
</td>
</tr>
<tr>
<td>
- <img src="https://cdn.generalresearch.com/buildStatus/icon?subject=dev&job=py-utils%2Fdev">
+ <img src="https://cdn.generalresearch.com/buildStatus/icon?subject=dev&job=generalresearch%2Fdev">
</td>
<td>
- <a href="https://code.g-r-l.com/py-utils/~files/v2.1.0">
- <img src="https://cdn.generalresearch.com/buildStatus/icon?subject=2.1.0&job=py-utils%2Fv2.1.0">
+ <a href="https://code.g-r-l.com/generalresearch/~files/v2.1.0">
+ <img src="https://cdn.generalresearch.com/buildStatus/icon?subject=2.1.0&job=generalresearch%2Fv2.1.0">
</a>
</td>
</tr>
<tr>
<td></td>
<td>
- <a href="https://code.g-r-l.com/py-utils/~files/v2.0.0">
- <img src="https://cdn.generalresearch.com/buildStatus/icon?subject=2.0.0&job=py-utils%2Fv2.0.0">
+ <a href="https://code.g-r-l.com/generalresearch/~files/v2.0.0">
+ <img src="https://cdn.generalresearch.com/buildStatus/icon?subject=2.0.0&job=generalresearch%2Fv2.0.0">
</a>
</td>
</tr>
<tr>
<td></td>
<td>
- <a href="https://code.g-r-l.com/py-utils/~files/v1.9.0">
- <img src="https://cdn.generalresearch.com/buildStatus/icon?subject=1.9.0&job=py-utils%2Fv1.9.0">
+ <a href="https://code.g-r-l.com/generalresearch/~files/v1.9.0">
+ <img src="https://cdn.generalresearch.com/buildStatus/icon?subject=1.9.0&job=generalresearch%2Fv1.9.0">
</a>
</td>
</tr>
diff --git a/generalresearch/managers/thl/delete_request.py b/generalresearch/managers/thl/delete_request.py
index f9d15c5..963cb7b 100644
--- a/generalresearch/managers/thl/delete_request.py
+++ b/generalresearch/managers/thl/delete_request.py
@@ -46,7 +46,7 @@
# assert finish == start + 1
-# @pytest.mark.skip(reason="Moving to py-utils in 2.5.1")
+# @pytest.mark.skip(reason="Moving to generalresearch in 2.5.1")
# class TestProductUserDeleteRequest:
#
# def test_no_user_provided(self, product, business, team, gr_user):
diff --git a/generalresearch/managers/thl/userhealth.py b/generalresearch/managers/thl/userhealth.py
index 5924938..8b951c0 100644
--- a/generalresearch/managers/thl/userhealth.py
+++ b/generalresearch/managers/thl/userhealth.py
@@ -54,7 +54,7 @@ class UserIpHistoryManager(PostgresManagerWithRedis):
)
def get_redis_key(self, user_id: int) -> str:
- return f"py-utils:user-ip-history:{user_id}"
+ return f"generalreserach:user-ip-history:{user_id}"
def get_user_ip_records_sql(self, user_id: int) -> list[UserIPRecord]:
# The IP metadata is ONLY for the 'ip', NOT for any forwarded ips.
diff --git a/generalresearch/models/thl/offerwall/base.py b/generalresearch/models/thl/offerwall/base.py
index 8e24958..3a867b6 100644
--- a/generalresearch/models/thl/offerwall/base.py
+++ b/generalresearch/models/thl/offerwall/base.py
@@ -383,7 +383,7 @@ class ScoredTaskResults(BaseModel):
class OfferwallBucket(BaseModel):
"""
- See also py-utils: models.legacy.bucket: Bucket. That is used only in
+ See also generalresearch: models.legacy.bucket: Bucket. That is used only in
handling API responses. This class is used internally to handle offerwall
creation/management.
"""
diff --git a/generalresearch/thl_django/README.md b/generalresearch/thl_django/README.md
index c9479ee..54af83f 100644
--- a/generalresearch/thl_django/README.md
+++ b/generalresearch/thl_django/README.md
@@ -17,7 +17,7 @@ pip install generalresearch[django]
(e.g. editable install recommended during development)
```bash
-pip install -e '/path/to/project/py-utils[django]'
+pip install -e '/path/to/project/generalresearch[django]'
```
diff --git a/generalresearch/thl_django/event/models.py b/generalresearch/thl_django/event/models.py
index 3e19910..19c79e2 100644
--- a/generalresearch/thl_django/event/models.py
+++ b/generalresearch/thl_django/event/models.py
@@ -62,14 +62,14 @@ class Payout(models.Model):
# In the smallest unit of the currency being transacted. For USD, this is cents.
amount = models.BigIntegerField(null=False)
- # The allowed values for `status` are defined in py-utils:
+ # The allowed values for `status` are defined in generalresearch:
# generalresearch/models/thl/payout.py:PayoutStatus
status = models.CharField(max_length=20, null=True)
# Used for holding an external, payouttype-specific identifier
ext_ref_id = models.CharField(max_length=64, null=True)
- # The allowed values for `payout_type` are defined in py-utils:
+ # The allowed values for `payout_type` are defined in generalresearch:
# generalresearch/models/thl/payout.py:PayoutType
payout_type = models.CharField(max_length=14)
diff --git a/generalresearch/wxet/models/definitions.py b/generalresearch/wxet/models/definitions.py
index 801346d..8d0d6b8 100644
--- a/generalresearch/wxet/models/definitions.py
+++ b/generalresearch/wxet/models/definitions.py
@@ -10,7 +10,7 @@ class IncExcFilterType(str, Enum, metaclass=ReprEnumMeta):
EXCLUDE = "exclude"
-# Note: This is exactly the same as the py-utils:models/thl/definitions.py:Status.
+# Note: This is exactly the same as the generalresearch:models/thl/definitions.py:Status.
# Keeping this because the comments (and as a result, the documentation)
# is slightly different, and specific to wxet.
class WXETStatus(str, Enum, metaclass=ReprEnumMeta):
diff --git a/test_utils/managers/ledger/conftest.py b/test_utils/managers/ledger/conftest.py
index c66ee4e..0aa6cb3 100644
--- a/test_utils/managers/ledger/conftest.py
+++ b/test_utils/managers/ledger/conftest.py
@@ -586,7 +586,6 @@ def session_with_tx_factory(
) -> Callable[..., "Session"]:
from generalresearch.models.thl.session import (
- Session,
Status,
StatusCode1,
)
@@ -661,7 +660,7 @@ def adj_to_fail_with_tx_factory(
# This is defined in `thl-grpc/thl/user_quality_history/recons.py:150`
# so we can't use it as part of this test anyway to add rows to the
# thl_taskadjustment table anyway.. until we created a
- # TaskAdjustment Manager to put into py-utils!
+ # TaskAdjustment Manager to put into generalresearch!
# create_task_adjustment_event(
# wall,
diff --git a/test_utils/managers/network/conftest.py b/test_utils/managers/network/conftest.py
index 979dd63..c699c93 100644
--- a/test_utils/managers/network/conftest.py
+++ b/test_utils/managers/network/conftest.py
@@ -43,7 +43,7 @@ def toolrun_manager(thl_web_rw) -> ToolRunManager:
@pytest.fixture(scope="session")
def nmap_raw_output(request) -> str:
fp = os.path.join(request.config.rootpath, "data/nmaprun1.xml")
- with open(fp, "r") as f:
+ with open(fp) as f:
data = f.read()
return data
@@ -107,7 +107,7 @@ def rdns_run(rdns_result, scan_group_id):
@pytest.fixture(scope="session")
def mtr_raw_output(request):
fp = os.path.join(request.config.rootpath, "data/mtr_fatbeam.json")
- with open(fp, "r") as f:
+ with open(fp) as f:
data = f.read()
return data
diff --git a/tests/models/network/test_nmap_parser.py b/tests/models/network/test_nmap_parser.py
index 96d7b37..abc83c9 100644
--- a/tests/models/network/test_nmap_parser.py
+++ b/tests/models/network/test_nmap_parser.py
@@ -7,7 +7,7 @@ from generalresearch.models.network.nmap.parser import parse_nmap_xml
@pytest.fixture
def nmap_raw_output_2(request) -> str:
fp = os.path.join(request.config.rootpath, "data/nmaprun2.xml")
- with open(fp, "r") as f:
+ with open(fp) as f:
data = f.read()
return data
diff --git a/tests/models/thl/test_contest/test_raffle_contest.py b/tests/models/thl/test_contest/test_raffle_contest.py
index e1c0a15..d7920f0 100644
--- a/tests/models/thl/test_contest/test_raffle_contest.py
+++ b/tests/models/thl/test_contest/test_raffle_contest.py
@@ -6,26 +6,26 @@ from pytest import approx
from generalresearch.currency import USDCent
from generalresearch.models.thl.contest import (
- ContestPrize,
ContestEndCondition,
+ ContestPrize,
)
from generalresearch.models.thl.contest.contest_entry import ContestEntry
from generalresearch.models.thl.contest.definitions import (
+ ContestEndReason,
ContestEntryType,
ContestPrizeKind,
- ContestType,
ContestStatus,
- ContestEndReason,
+ ContestType,
)
from generalresearch.models.thl.contest.raffle import RaffleContest
-
+from generalresearch.models.thl.product import Product
from tests.models.thl.test_contest.test_contest import TestContest
class TestRaffleContest(TestContest):
@pytest.fixture(scope="function")
- def raffle_contest(self, product) -> RaffleContest:
+ def raffle_contest(self, product: Product) -> RaffleContest:
return RaffleContest(
product_id=product.uuid,
name=f"Raffle Contest {uuid4().hex}",
diff --git a/tests/models/thl/test_marketplace_condition.py b/tests/models/thl/test_marketplace_condition.py
index 217616d..8a4b25c 100644
--- a/tests/models/thl/test_marketplace_condition.py
+++ b/tests/models/thl/test_marketplace_condition.py
@@ -7,8 +7,8 @@ class TestMarketplaceCondition:
def test_list_or(self):
from generalresearch.models import LogicalOperator
from generalresearch.models.thl.survey.condition import (
- MarketplaceCondition,
ConditionValueType,
+ MarketplaceCondition,
)
user_qas = {"q1": {"a2"}}
@@ -48,8 +48,8 @@ class TestMarketplaceCondition:
def test_list_or_negate(self):
from generalresearch.models import LogicalOperator
from generalresearch.models.thl.survey.condition import (
- MarketplaceCondition,
ConditionValueType,
+ MarketplaceCondition,
)
user_qas = {"q1": {"a2"}}
@@ -89,8 +89,8 @@ class TestMarketplaceCondition:
def test_list_and(self):
from generalresearch.models import LogicalOperator
from generalresearch.models.thl.survey.condition import (
- MarketplaceCondition,
ConditionValueType,
+ MarketplaceCondition,
)
user_qas = {"q1": {"a1", "a2"}}
@@ -139,8 +139,8 @@ class TestMarketplaceCondition:
def test_list_and_negate(self):
from generalresearch.models import LogicalOperator
from generalresearch.models.thl.survey.condition import (
- MarketplaceCondition,
ConditionValueType,
+ MarketplaceCondition,
)
user_qas = {"q1": {"a1", "a2"}}
@@ -180,8 +180,8 @@ class TestMarketplaceCondition:
def test_ranges(self):
from generalresearch.models import LogicalOperator
from generalresearch.models.thl.survey.condition import (
- MarketplaceCondition,
ConditionValueType,
+ MarketplaceCondition,
)
user_qas = {"q1": {"2", "50"}}
@@ -247,8 +247,8 @@ class TestMarketplaceCondition:
def test_ranges_to_list(self):
from generalresearch.models import LogicalOperator
from generalresearch.models.thl.survey.condition import (
- MarketplaceCondition,
ConditionValueType,
+ MarketplaceCondition,
)
user_qas = {"q1": {"2", "50"}}
@@ -267,8 +267,8 @@ class TestMarketplaceCondition:
def test_ranges_infinity(self):
from generalresearch.models import LogicalOperator
from generalresearch.models.thl.survey.condition import (
- MarketplaceCondition,
ConditionValueType,
+ MarketplaceCondition,
)
user_qas = {"q1": {"2", "50"}}
@@ -310,8 +310,8 @@ class TestMarketplaceCondition:
def test_answered(self):
from generalresearch.models.thl.survey.condition import (
- MarketplaceCondition,
ConditionValueType,
+ MarketplaceCondition,
)
user_qas = {"q1": {"a2"}}
@@ -346,8 +346,8 @@ class TestMarketplaceCondition:
def test_invite(self):
from generalresearch.models.thl.survey.condition import (
- MarketplaceCondition,
ConditionValueType,
+ MarketplaceCondition,
)
user_groups = {"g1", "g2", "g3"}
@@ -357,14 +357,14 @@ class TestMarketplaceCondition:
value_type=ConditionValueType.RECONTACT,
values=["g1", "g4"],
)
- assert c.evaluate_criterion(user_qas=dict(), user_groups=user_groups)
+ assert c.evaluate_criterion(user_qas={}, user_groups=user_groups)
c = MarketplaceCondition(
question_id=None,
negate=False,
value_type=ConditionValueType.RECONTACT,
values=["g4"],
)
- assert not c.evaluate_criterion(user_qas=dict(), user_groups=user_groups)
+ assert not c.evaluate_criterion(user_qas={}, user_groups=user_groups)
c = MarketplaceCondition(
question_id=None,
@@ -372,11 +372,11 @@ class TestMarketplaceCondition:
value_type=ConditionValueType.RECONTACT,
values=["g1", "g4"],
)
- assert not c.evaluate_criterion(user_qas=dict(), user_groups=user_groups)
+ assert not c.evaluate_criterion(user_qas={}, user_groups=user_groups)
c = MarketplaceCondition(
question_id=None,
negate=True,
value_type=ConditionValueType.RECONTACT,
values=["g4"],
)
- assert c.evaluate_criterion(user_qas=dict(), user_groups=user_groups)
+ assert c.evaluate_criterion(user_qas={}, user_groups=user_groups)
diff --git a/tests/models/thl/test_payout_format.py b/tests/models/thl/test_payout_format.py
index dc91f39..83fde25 100644
--- a/tests/models/thl/test_payout_format.py
+++ b/tests/models/thl/test_payout_format.py
@@ -2,8 +2,8 @@ import pytest
from pydantic import BaseModel
from generalresearch.models.thl.payout_format import (
- PayoutFormatType,
PayoutFormatField,
+ PayoutFormatType,
format_payout_format,
)
@@ -20,16 +20,16 @@ class TestPayoutFormat:
PayoutFormatTestClass(payout_format="${payout/100:.2f}")
# invalid
- with pytest.raises(expected_exception=Exception) as e:
+ with pytest.raises(expected_exception=ValueError):
PayoutFormatTestClass(payout_format="{payout10:,.0f} Points")
- with pytest.raises(expected_exception=Exception) as e:
+ with pytest.raises(expected_exception=ValueError):
PayoutFormatTestClass(payout_format="payout:,.0f} Points")
- with pytest.raises(expected_exception=Exception):
+ with pytest.raises(expected_exception=ValueError):
PayoutFormatTestClass(payout_format="payout")
- with pytest.raises(expected_exception=Exception):
+ with pytest.raises(expected_exception=ValueError):
PayoutFormatTestClass(payout_format="{payout;import sys:.0f}")
def test_payout_format(self):
diff --git a/tests/models/thl/test_product.py b/tests/models/thl/test_product.py
index 52f60c2..2d20ba1 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,
diff --git a/tests/models/thl/test_product_userwalletconfig.py b/tests/models/thl/test_product_userwalletconfig.py
index 4583c46..4f6a6cc 100644
--- a/tests/models/thl/test_product_userwalletconfig.py
+++ b/tests/models/thl/test_product_userwalletconfig.py
@@ -4,7 +4,6 @@ from random import shuffle as rshuffle
from generalresearch.models.thl.product import (
UserWalletConfig,
)
-
from generalresearch.models.thl.wallet import PayoutType
diff --git a/tests/models/thl/test_upkquestion.py b/tests/models/thl/test_upkquestion.py
index e67427e..d32875c 100644
--- a/tests/models/thl/test_upkquestion.py
+++ b/tests/models/thl/test_upkquestion.py
@@ -9,8 +9,12 @@ class TestUpkQuestion:
UPKImportance,
)
- ui = UPKImportance(task_score=1, task_count=None)
- ui = UPKImportance(task_score=0)
+ res = UPKImportance(task_score=1, task_count=None)
+ assert isinstance(res, UPKImportance)
+
+ res = UPKImportance(task_score=0)
+ assert isinstance(res, UPKImportance)
+
with pytest.raises(ValidationError) as e:
UPKImportance(task_score=-1)
assert "Input should be greater than or equal to 0" in str(e.value)
@@ -27,11 +31,11 @@ class TestUpkQuestion:
def test_mc(self):
from generalresearch.models.thl.profiling.upk_question import (
+ UpkQuestion,
UpkQuestionChoice,
+ UpkQuestionConfigurationMC,
UpkQuestionSelectorMC,
UpkQuestionType,
- UpkQuestion,
- UpkQuestionConfigurationMC,
)
q = UpkQuestion(
@@ -123,12 +127,12 @@ class TestUpkQuestion:
def test_te(self):
from generalresearch.models.thl.profiling.upk_question import (
- UpkQuestionType,
+ PatternValidation,
UpkQuestion,
+ UpkQuestionConfigurationTE,
UpkQuestionSelectorTE,
+ UpkQuestionType,
UpkQuestionValidation,
- PatternValidation,
- UpkQuestionConfigurationTE,
)
q = UpkQuestion(
@@ -223,10 +227,10 @@ class TestUpkQuestion:
def test_order(self):
from generalresearch.models.thl.profiling.upk_question import (
+ UpkQuestion,
UpkQuestionChoice,
UpkQuestionSelectorMC,
UpkQuestionType,
- UpkQuestion,
order_exclusive_options,
)
@@ -296,7 +300,7 @@ class TestUpkQuestionValidateAnswer:
answer = ("0", "1")
assert question.validate_question_answer(answer) == (
False,
- "Single Answer MC question with >1 selected " "answers",
+ "Single Answer MC question with >1 selected answers",
)
def test_validate_answer_MA(self):
diff --git a/tests/models/thl/test_user.py b/tests/models/thl/test_user.py
index 4f10861..25af694 100644
--- a/tests/models/thl/test_user.py
+++ b/tests/models/thl/test_user.py
@@ -1,7 +1,8 @@
import json
-from datetime import datetime, timezone, timedelta
+from datetime import datetime, timedelta, timezone
from decimal import Decimal
-from random import randint, choice as rand_choice
+from random import choice as rand_choice
+from random import randint
from uuid import uuid4
import pytest
@@ -315,7 +316,7 @@ class TestUserUUID:
with pytest.raises(ValueError) as cm:
User(user_id=self.user_id, uuid=Decimal("0"))
- assert "1 validation error for User", str(cm.value)
+ assert "1 validation error for User" in str(cm.value)
assert "Input should be a valid string" in str(cm.value)
def test_empty(self):
@@ -323,8 +324,8 @@ class TestUserUUID:
with pytest.raises(ValueError) as cm:
User(user_id=self.user_id, uuid="")
- assert "1 validation error for User", str(cm.value)
- assert "String should have at least 32 characters", str(cm.value)
+ assert "1 validation error for User" in str(cm.value)
+ assert "String should have at least 32 characters" in str(cm.value)
def test_invalid_len(self):
from generalresearch.models.thl.user import User
diff --git a/tests/models/thl/test_user_streak.py b/tests/models/thl/test_user_streak.py
index 72efd05..0cacd3e 100644
--- a/tests/models/thl/test_user_streak.py
+++ b/tests/models/thl/test_user_streak.py
@@ -1,14 +1,14 @@
from datetime import datetime, timedelta
-from zoneinfo import ZoneInfo
import pytest
from pydantic import ValidationError
+from zoneinfo import ZoneInfo
from generalresearch.models.thl.user_streak import (
- UserStreak,
- StreakPeriod,
StreakFulfillment,
+ StreakPeriod,
StreakState,
+ UserStreak,
)
diff --git a/tests/models/thl/test_wall.py b/tests/models/thl/test_wall.py
index 057aad2..8398c81 100644
--- a/tests/models/thl/test_wall.py
+++ b/tests/models/thl/test_wall.py
@@ -1,4 +1,4 @@
-from datetime import datetime, timezone, timedelta
+from datetime import datetime, timedelta, timezone
from decimal import Decimal
from uuid import uuid4
@@ -76,7 +76,7 @@ class TestWall:
)
assert "If status is f, status_code_1 should be in" in str(e.value)
- with pytest.raises(expected_exception=ValidationError) as cm:
+ with pytest.raises(expected_exception=ValidationError):
Wall(
user_id=1,
source=Source.DYNATA,
diff --git a/tests/wall_status_codes/test_analyze.py b/tests/wall_status_codes/test_analyze.py
index da6efb3..fa53dbb 100644
--- a/tests/wall_status_codes/test_analyze.py
+++ b/tests/wall_status_codes/test_analyze.py
@@ -1,4 +1,4 @@
-from generalresearch.models.thl.definitions import StatusCode1, Status
+from generalresearch.models.thl.definitions import Status, StatusCode1
from generalresearch.wall_status_codes import innovate
@@ -16,43 +16,35 @@ class TestInnovate:
assert status_code_2 is None
def test_unknown(self):
- status, status_code_1, status_code_2 = innovate.annotate_status_code(
- "69420", None
- )
+ status, status_code_1, _ = innovate.annotate_status_code("69420", None)
assert Status.FAIL == status
assert StatusCode1.UNKNOWN == status_code_1
- status, status_code_1, status_code_2 = innovate.annotate_status_code(
- "69420", "Speeder"
- )
+ status, status_code_1, _ = innovate.annotate_status_code("69420", "Speeder")
assert Status.FAIL == status
assert StatusCode1.UNKNOWN == status_code_1
def test_ps(self):
- status, status_code_1, status_code_2 = innovate.annotate_status_code("5", None)
+ status, status_code_1, _ = innovate.annotate_status_code("5", None)
assert Status.FAIL == status
assert StatusCode1.PS_FAIL == status_code_1
# The ext_status_code_2 should reclassify this as PS_FAIL
- status, status_code_1, status_code_2 = innovate.annotate_status_code(
- "8", "DeviceType"
- )
+ status, status_code_1, _ = innovate.annotate_status_code("8", "DeviceType")
assert Status.FAIL == status
assert StatusCode1.PS_FAIL == status_code_1
# this should be reclassified from PS_FAIL to PS_OQ
- status, status_code_1, status_code_2 = innovate.annotate_status_code(
- "5", "Group NA"
- )
+ status, status_code_1, _ = innovate.annotate_status_code("5", "Group NA")
assert Status.FAIL == status
assert StatusCode1.PS_OVERQUOTA == status_code_1
def test_dupe(self):
# innovate calls it a quality, should be dupe
- status, status_code_1, status_code_2 = innovate.annotate_status_code(
+ status, status_code_1, _ = innovate.annotate_status_code(
"8", "Duplicated to token Tq2SwRVX7PUWnFunGPAYWHk"
)
assert Status.FAIL == status
assert StatusCode1.PS_DUPLICATE == status_code_1
# stay as quality
- status, status_code_1, status_code_2 = innovate.annotate_status_code(
+ status, status_code_1, _ = innovate.annotate_status_code(
"8", "Selected threat potential score at joblevel not allow the survey"
)
assert Status.FAIL == status