aboutsummaryrefslogtreecommitdiff
path: root/tests/models/precision
diff options
context:
space:
mode:
Diffstat (limited to 'tests/models/precision')
-rw-r--r--tests/models/precision/__init__.py115
-rw-r--r--tests/models/precision/test_survey.py88
-rw-r--r--tests/models/precision/test_survey_manager.py63
3 files changed, 266 insertions, 0 deletions
diff --git a/tests/models/precision/__init__.py b/tests/models/precision/__init__.py
new file mode 100644
index 0000000..8006fa3
--- /dev/null
+++ b/tests/models/precision/__init__.py
@@ -0,0 +1,115 @@
+survey_json = {
+ "cpi": "1.44",
+ "country_isos": "ca",
+ "language_isos": "eng",
+ "country_iso": "ca",
+ "language_iso": "eng",
+ "buyer_id": "7047",
+ "bid_loi": 1200,
+ "bid_ir": 0.45,
+ "source": "e",
+ "used_question_ids": ["age", "country_iso", "gender", "gender_1"],
+ "survey_id": "0000",
+ "group_id": "633473",
+ "status": "open",
+ "name": "beauty survey",
+ "survey_guid": "c7f375c5077d4c6c8209ff0b539d7183",
+ "category_id": "-1",
+ "global_conversion": None,
+ "desired_count": 96,
+ "achieved_count": 0,
+ "allowed_devices": "1,2,3",
+ "entry_link": "https://www.opinionetwork.com/survey/entry.aspx?mid=[%MID%]&project=633473&key=%%key%%",
+ "excluded_surveys": "470358,633286",
+ "quotas": [
+ {
+ "name": "25-34,Male,Quebec",
+ "id": "2324110",
+ "guid": "23b5760d24994bc08de451b3e62e77c7",
+ "status": "open",
+ "desired_count": 48,
+ "achieved_count": 0,
+ "termination_count": 0,
+ "overquota_count": 0,
+ "condition_hashes": ["b41e1a3", "bc89ee8", "4124366", "9f32c61"],
+ },
+ {
+ "name": "25-34,Female,Quebec",
+ "id": "2324111",
+ "guid": "0706f1a88d7e4f11ad847c03012e68d2",
+ "status": "open",
+ "desired_count": 48,
+ "achieved_count": 0,
+ "termination_count": 4,
+ "overquota_count": 0,
+ "condition_hashes": ["b41e1a3", "0cdc304", "500af2c", "9f32c61"],
+ },
+ ],
+ "conditions": {
+ "b41e1a3": {
+ "logical_operator": "OR",
+ "value_type": 1,
+ "negate": False,
+ "question_id": "country_iso",
+ "values": ["ca"],
+ "criterion_hash": "b41e1a3",
+ "value_len": 1,
+ "sizeof": 2,
+ },
+ "bc89ee8": {
+ "logical_operator": "OR",
+ "value_type": 1,
+ "negate": False,
+ "question_id": "gender",
+ "values": ["male"],
+ "criterion_hash": "bc89ee8",
+ "value_len": 1,
+ "sizeof": 4,
+ },
+ "4124366": {
+ "logical_operator": "OR",
+ "value_type": 1,
+ "negate": False,
+ "question_id": "gender_1",
+ "values": ["male"],
+ "criterion_hash": "4124366",
+ "value_len": 1,
+ "sizeof": 4,
+ },
+ "9f32c61": {
+ "logical_operator": "OR",
+ "value_type": 1,
+ "negate": False,
+ "question_id": "age",
+ "values": ["25", "26", "27", "28", "29", "30", "31", "32", "33", "34"],
+ "criterion_hash": "9f32c61",
+ "value_len": 10,
+ "sizeof": 20,
+ },
+ "0cdc304": {
+ "logical_operator": "OR",
+ "value_type": 1,
+ "negate": False,
+ "question_id": "gender",
+ "values": ["female"],
+ "criterion_hash": "0cdc304",
+ "value_len": 1,
+ "sizeof": 6,
+ },
+ "500af2c": {
+ "logical_operator": "OR",
+ "value_type": 1,
+ "negate": False,
+ "question_id": "gender_1",
+ "values": ["female"],
+ "criterion_hash": "500af2c",
+ "value_len": 1,
+ "sizeof": 6,
+ },
+ },
+ "expected_end_date": "2024-06-28T10:40:33.000000Z",
+ "created": None,
+ "updated": None,
+ "is_live": True,
+ "all_hashes": ["0cdc304", "b41e1a3", "9f32c61", "bc89ee8", "4124366", "500af2c"],
+}
diff --git a/tests/models/precision/test_survey.py b/tests/models/precision/test_survey.py
new file mode 100644
index 0000000..ff2d6d1
--- /dev/null
+++ b/tests/models/precision/test_survey.py
@@ -0,0 +1,88 @@
+class TestPrecisionQuota:
+
+ def test_quota_passes(self):
+ from generalresearch.models.precision.survey import PrecisionSurvey
+ from tests.models.precision import survey_json
+
+ s = PrecisionSurvey.model_validate(survey_json)
+ q = s.quotas[0]
+ ce = {k: True for k in ["b41e1a3", "bc89ee8", "4124366", "9f32c61"]}
+ assert q.matches(ce)
+
+ ce["b41e1a3"] = False
+ assert not q.matches(ce)
+
+ ce.pop("b41e1a3")
+ assert not q.matches(ce)
+ assert not q.matches({})
+
+ def test_quota_passes_closed(self):
+ from generalresearch.models.precision import PrecisionStatus
+ from generalresearch.models.precision.survey import PrecisionSurvey
+ from tests.models.precision import survey_json
+
+ s = PrecisionSurvey.model_validate(survey_json)
+ q = s.quotas[0]
+ q.status = PrecisionStatus.CLOSED
+ ce = {k: True for k in ["b41e1a3", "bc89ee8", "4124366", "9f32c61"]}
+ # We still match, but the quota is not open
+ assert q.matches(ce)
+ assert not q.is_open
+
+
+class TestPrecisionSurvey:
+
+ def test_passes(self):
+ from generalresearch.models.precision.survey import PrecisionSurvey
+ from tests.models.precision import survey_json
+
+ s = PrecisionSurvey.model_validate(survey_json)
+ ce = {k: True for k in ["b41e1a3", "bc89ee8", "4124366", "9f32c61"]}
+ assert s.determine_eligibility(ce)
+
+ def test_elig_closed_quota(self):
+ from generalresearch.models.precision import PrecisionStatus
+ from generalresearch.models.precision.survey import PrecisionSurvey
+ from tests.models.precision import survey_json
+
+ s = PrecisionSurvey.model_validate(survey_json)
+ ce = {k: True for k in ["b41e1a3", "bc89ee8", "4124366", "9f32c61"]}
+ q = s.quotas[0]
+ q.status = PrecisionStatus.CLOSED
+ # We match a closed quota
+ assert not s.determine_eligibility(ce)
+
+ s.quotas[0].status = PrecisionStatus.OPEN
+ s.quotas[1].status = PrecisionStatus.CLOSED
+ # Now me match an open quota and dont match the closed quota, so we should be eligible
+ assert s.determine_eligibility(ce)
+
+ def test_passes_sp(self):
+ from generalresearch.models.precision import PrecisionStatus
+ from generalresearch.models.precision.survey import PrecisionSurvey
+ from tests.models.precision import survey_json
+
+ s = PrecisionSurvey.model_validate(survey_json)
+ ce = {k: True for k in ["b41e1a3", "bc89ee8", "4124366", "9f32c61"]}
+ passes, hashes = s.determine_eligibility_soft(ce)
+
+ # We don't know if we match the 2nd quota, but it is open so it doesn't matter
+ assert passes
+ assert (True, []) == s.quotas[0].matches_soft(ce)
+ assert (None, ["0cdc304", "500af2c"]) == s.quotas[1].matches_soft(ce)
+
+ # Now don't know if we match either
+ ce.pop("9f32c61") # age
+ passes, hashes = s.determine_eligibility_soft(ce)
+ assert passes is None
+ assert {"500af2c", "9f32c61", "0cdc304"} == hashes
+
+ ce["9f32c61"] = False
+ ce["0cdc304"] = False
+ # We know we don't match either
+ assert (False, set()) == s.determine_eligibility_soft(ce)
+
+ # We pass 1st quota, 2nd is unknown but closed, so we don't know for sure we pass
+ ce = {k: True for k in ["b41e1a3", "bc89ee8", "4124366", "9f32c61"]}
+ s.quotas[1].status = PrecisionStatus.CLOSED
+ assert (None, {"0cdc304", "500af2c"}) == s.determine_eligibility_soft(ce)
diff --git a/tests/models/precision/test_survey_manager.py b/tests/models/precision/test_survey_manager.py
new file mode 100644
index 0000000..8532ab0
--- /dev/null
+++ b/tests/models/precision/test_survey_manager.py
@@ -0,0 +1,63 @@
+# from decimal import Decimal
+#
+# from datetime import timezone, datetime
+# from pymysql import IntegrityError
+# from generalresearch.models.precision.survey import PrecisionSurvey
+# from tests.models.precision import survey_json
+
+
+# def delete_survey(survey_id: str):
+# db_name = sql_helper.db
+# # TODO: what is the precision specific db name...
+#
+# sql_helper.execute_sql_query(
+# query="""
+# DELETE FROM `300large-precision`.precision_survey
+# WHERE survey_id = %s
+# """,
+# params=[survey_id], commit=True)
+# sql_helper.execute_sql_query("""
+# DELETE FROM `300large-precision`.precision_survey_country WHERE survey_id = %s
+# """, [survey_id], commit=True)
+# sql_helper.execute_sql_query("""
+# DELETE FROM `300large-precision`.precision_survey_language WHERE survey_id = %s
+# """, [survey_id], commit=True)
+#
+#
+# class TestPrecisionSurvey:
+# def test_survey_create(self):
+# now = datetime.now(tz=timezone.utc)
+# s = PrecisionSurvey.model_validate(survey_json)
+# self.assertEqual(s.survey_id, '0000')
+# delete_survey(s.survey_id)
+#
+# sm.create(s)
+#
+# surveys = sm.get_survey_library(updated_since=now)
+# self.assertEqual(len(surveys), 1)
+# self.assertEqual('0000', surveys[0].survey_id)
+# self.assertTrue(s.is_unchanged(surveys[0]))
+#
+# with self.assertRaises(IntegrityError) as context:
+# sm.create(s)
+#
+# def test_survey_update(self):
+# # There's extra complexity here with the country/lang join tables
+# now = datetime.now(tz=timezone.utc)
+# s = PrecisionSurvey.model_validate(survey_json)
+# self.assertEqual(s.survey_id, '0000')
+# delete_survey(s.survey_id)
+# sm.create(s)
+# s.cpi = Decimal('0.50')
+# # started out at only 'ca' and 'eng'
+# s.country_isos = ['us']
+# s.country_iso = 'us'
+# s.language_isos = ['eng', 'spa']
+# s.language_iso = 'eng'
+# sm.update([s])
+# surveys = sm.get_survey_library(updated_since=now)
+# self.assertEqual(len(surveys), 1)
+# s2 = surveys[0]
+# self.assertEqual('0000', s2.survey_id)
+# self.assertEqual(Decimal('0.50'), s2.cpi)
+# self.assertTrue(s.is_unchanged(s2))