aboutsummaryrefslogtreecommitdiff
path: root/tests/managers/test_events.py
diff options
context:
space:
mode:
authorstuppie2026-09-07 11:47:43 -0600
committerstuppie2026-09-07 11:47:43 -0600
commit092960233652cce1f4dc7841856034a6635e9cd9 (patch)
tree46e5fcd4d1e1b7ed0b987980c6c67ffa6e6b45c7 /tests/managers/test_events.py
parent80fd8aab4c7271ddb619b0de18741d7ac77b490b (diff)
parent242579a44855873d5e054e375440e9d3492cd682 (diff)
downloadgeneralresearch-092960233652cce1f4dc7841856034a6635e9cd9.tar.gz
generalresearch-092960233652cce1f4dc7841856034a6635e9cd9.zip
Merge branch 'master' into dev-greg
Diffstat (limited to 'tests/managers/test_events.py')
-rw-r--r--tests/managers/test_events.py146
1 files changed, 80 insertions, 66 deletions
diff --git a/tests/managers/test_events.py b/tests/managers/test_events.py
index a0fab38..5ebd015 100644
--- a/tests/managers/test_events.py
+++ b/tests/managers/test_events.py
@@ -1,60 +1,48 @@
-import random
+from __future__ import annotations
+
+import math
import time
-from datetime import timedelta, datetime, timezone
+from collections.abc import Callable
+from datetime import UTC, datetime, timedelta
from decimal import Decimal
-from functools import partial
-from typing import Optional
+from typing import TYPE_CHECKING
from uuid import uuid4
-import math
import pytest
-from math import floor
from generalresearch.managers.events import EventSubscriber
-from generalresearch.models import Source
+from generalresearch.models.definitions import Source
from generalresearch.models.events import (
- MessageKind,
- EventType,
AggregateBySource,
+ EventType,
MaxGaugeBySource,
+ MessageKind,
)
from generalresearch.models.legacy.bucket import Bucket
+from generalresearch.models.thl import Product
from generalresearch.models.thl.definitions import Status, StatusCode1
from generalresearch.models.thl.session import Session, Wall
from generalresearch.models.thl.user import User
+if TYPE_CHECKING:
+ from generalresearch.managers.events import EventManager
+ from generalresearch.managers.thl.product import ProductManager
+ from generalresearch.redis_helper import RedisConfig
+
# We don't need anything in the db, so not using the db fixtures
@pytest.fixture(scope="function")
-def product_id(product_manager):
+def product_id(product_manager: ProductManager) -> str:
return uuid4().hex
@pytest.fixture(scope="function")
-def user_factory(product_id):
- return partial(create_dummy, product_id=product_id)
-
-
-@pytest.fixture(scope="function")
-def event_subscriber(thl_redis_config, product_id):
+def event_subscriber(thl_redis_config: RedisConfig, product_id: str) -> EventSubscriber:
return EventSubscriber(redis_config=thl_redis_config, product_id=product_id)
-def create_dummy(
- product_id: Optional[str] = None, product_user_id: Optional[str] = None
-) -> User:
- return User(
- product_id=product_id,
- product_user_id=product_user_id or uuid4().hex,
- uuid=uuid4().hex,
- created=datetime.now(tz=timezone.utc),
- user_id=random.randint(0, floor(2**32 / 2)),
- )
-
-
class TestActiveUsers:
-
- def test_run_empty(self, event_manager, product_id):
+ def test_run_empty(self, event_manager: EventManager, product_id: str):
res = event_manager.get_user_stats(product_id)
assert res == {
"active_users_last_1h": 0,
@@ -63,7 +51,12 @@ class TestActiveUsers:
"in_progress_users": 0,
}
- def test_run(self, event_manager, product_id, user_factory):
+ def test_run(
+ self,
+ event_manager: EventManager,
+ product_factory,
+ user_factory: Callable[..., User],
+ ):
event_manager.clear_global_user_stats()
user1: User = user_factory()
@@ -72,7 +65,7 @@ class TestActiveUsers:
event_manager.handle_user(user1)
event_manager.handle_user(user1)
- res = event_manager.get_user_stats(product_id)
+ res = event_manager.get_user_stats(user1.product_id)
assert res == {
"active_users_last_1h": 1,
"active_users_last_24h": 1,
@@ -88,21 +81,23 @@ class TestActiveUsers:
}
# Create a 2nd user in another product
- product_id2 = uuid4().hex
- user2: User = user_factory(product_id=product_id2)
+ product2 = product_factory()
+ user2: User = user_factory(product=product2)
+ assert isinstance(user2, User)
+ assert isinstance(user2.created, datetime)
# Change to say user was created >24 hrs ago
user2.created = user2.created - timedelta(hours=25)
event_manager.handle_user(user2)
# And now each have 1 active user
- assert event_manager.get_user_stats(product_id) == {
+ assert event_manager.get_user_stats(user1.product_id) == {
"active_users_last_1h": 1,
"active_users_last_24h": 1,
"signups_last_24h": 1,
"in_progress_users": 0,
}
# user2 was created older than 24hrs ago
- assert event_manager.get_user_stats(product_id2) == {
+ assert event_manager.get_user_stats(user2.product_id) == {
"active_users_last_1h": 1,
"active_users_last_24h": 1,
"signups_last_24h": 0,
@@ -116,10 +111,16 @@ class TestActiveUsers:
"in_progress_users": 0,
}
- def test_inprogress(self, event_manager, product_id, user_factory):
+ def test_inprogress(
+ self,
+ event_manager: EventManager,
+ user_factory: Callable[..., User],
+ product
+ ):
event_manager.clear_global_user_stats()
- user1: User = user_factory()
- user2: User = user_factory()
+ user1: User = user_factory(product=product)
+ user2: User = user_factory(product=product)
+ product_id = product.id
# No matter how many times we do this, they're only active once
event_manager.mark_user_inprogress(user1)
@@ -139,9 +140,14 @@ class TestActiveUsers:
res = event_manager.get_user_stats(product_id)
assert res["in_progress_users"] == 1
- def test_expiry(self, event_manager, product_id, user_factory):
+ def test_expiry(
+ self,
+ event_manager: EventManager,
+ user_factory: Callable[..., User],
+ ):
event_manager.clear_global_user_stats()
user1: User = user_factory()
+ product_id = user1.product_id
event_manager.handle_user(user1)
event_manager.mark_user_inprogress(user1)
sec_24hr = timedelta(hours=24).total_seconds()
@@ -166,8 +172,7 @@ class TestActiveUsers:
class TestSessionStats:
-
- def test_run_empty(self, event_manager, product_id):
+ def test_run_empty(self, event_manager: EventManager, product_id: str):
res = event_manager.get_session_stats(product_id)
assert res == {
"session_enters_last_1h": 0,
@@ -186,10 +191,18 @@ class TestSessionStats:
"session_fail_avg_loi_last_24h": None,
}
- def test_run(self, event_manager, product_id, user_factory, utc_now, utc_hour_ago):
+ def test_run(
+ self,
+ event_manager: EventManager,
+ product_factory: Callable[..., Product],
+ user_factory: Callable[..., User],
+ utc_now: datetime,
+ utc_hour_ago: datetime,
+ ):
event_manager.clear_global_session_stats()
-
- user: User = user_factory()
+ product = product_factory()
+ product_id = product.id
+ user: User = user_factory(product=product)
session = Session(
country_iso="us",
started=utc_hour_ago + timedelta(minutes=10),
@@ -266,29 +279,29 @@ class TestSessionStats:
field_name = str(field)
assert res == {field_name: "1"}
assert (
- 3600 - 60 < event_manager.redis_client.httl(name, field_name)[0] < 3600 + 60
+ 3600 - 61 < event_manager.redis_client.httl(name, field_name)[0] < 3600 + 60
)
# Second BP, fail
- product_id2 = uuid4().hex
- user2: User = user_factory(product_id=product_id2)
+ product2 = product_factory()
+ user2: User = user_factory(product=product2)
session3 = Session(
country_iso="us",
started=utc_now - timedelta(minutes=1),
user=user2,
)
- event_manager.session_on_enter(session=session3, user=user)
+ event_manager.session_on_enter(session=session3, user=user2)
session3.update(
finished=utc_now,
status=Status.FAIL,
status_code_1=StatusCode1.BUYER_FAIL,
)
- event_manager.session_on_finish(session=session3, user=user)
+ event_manager.session_on_finish(session=session3, user=user2)
avg_loi_complete = (
round(session.elapsed.total_seconds())
+ round(session2.elapsed.total_seconds())
) / 2
- assert event_manager.get_session_stats(product_id) == {
+ assert event_manager.get_global_session_stats() == {
"session_enters_last_1h": 2,
"session_enters_last_24h": 3,
"session_fails_last_1h": 1,
@@ -307,7 +320,7 @@ class TestSessionStats:
class TestTaskStatsManager:
- def test_empty(self, event_manager):
+ def test_empty(self, event_manager: EventManager):
event_manager.clear_task_stats()
assert event_manager.get_task_stats_raw() == {
"live_task_count": AggregateBySource(total=0),
@@ -321,7 +334,7 @@ class TestTaskStatsManager:
assert sm.data.task_created_count_last_24h.total == 0
assert sm.data.live_tasks_max_payout.value is None
- def test(self, event_manager):
+ def test(self, event_manager: EventManager):
event_manager.clear_task_stats()
event_manager.set_source_task_stats(
source=Source.TESTING,
@@ -384,7 +397,7 @@ class TestTaskStatsManager:
"task_created_count_last_24h": AggregateBySource(total=0),
}
event_manager.set_source_task_stats(
- source=Source.TESTING, live_task_count=0, live_tasks_max_payout=Decimal("0")
+ source=Source.TESTING, live_task_count=0, live_tasks_max_payout=Decimal(0)
)
assert event_manager.get_task_stats_raw() == {
"live_task_count": AggregateBySource(
@@ -400,7 +413,7 @@ class TestTaskStatsManager:
event_manager.set_source_task_stats(
source=Source.TESTING,
live_task_count=0,
- live_tasks_max_payout=Decimal("0"),
+ live_tasks_max_payout=Decimal(0),
created_count=10,
)
res = event_manager.get_task_stats_raw()
@@ -414,7 +427,7 @@ class TestTaskStatsManager:
event_manager.set_source_task_stats(
source=Source.TESTING,
live_task_count=0,
- live_tasks_max_payout=Decimal("0"),
+ live_tasks_max_payout=Decimal(0),
created_count=10,
)
res = event_manager.get_task_stats_raw()
@@ -428,7 +441,7 @@ class TestTaskStatsManager:
event_manager.set_source_task_stats(
source=Source.TESTING2,
live_task_count=0,
- live_tasks_max_payout=Decimal("0"),
+ live_tasks_max_payout=Decimal(0),
created_count=1,
)
res = event_manager.get_task_stats_raw()
@@ -444,14 +457,15 @@ class TestTaskStatsManager:
class TestChannelsSubscriptions:
+ @pytest.mark.skip("sits there doing nothing forever? todo")
def test_stats_worker(
self,
- event_manager,
- event_subscriber,
- product_id,
- user_factory,
- utc_hour_ago,
- utc_now,
+ event_manager: EventManager,
+ event_subscriber: EventSubscriber,
+ product_id: str,
+ user_factory: Callable[..., User],
+ utc_hour_ago: datetime,
+ utc_now: datetime,
):
event_manager.clear_stats()
assert event_subscriber.pubsub
@@ -481,7 +495,7 @@ class TestChannelsSubscriptions:
wall = Wall(
req_survey_id="a",
- req_cpi=Decimal("1"),
+ req_cpi=Decimal(1),
source=Source.TESTING,
session_id=session.id,
user_id=user.user_id,
@@ -496,8 +510,8 @@ class TestChannelsSubscriptions:
wall.update(
status=Status.COMPLETE,
status_code_1=StatusCode1.COMPLETE,
- finished=datetime.now(tz=timezone.utc),
- cpi=Decimal("1"),
+ finished=datetime.now(tz=UTC),
+ cpi=Decimal(1),
)
event_manager.handle_task_finish(wall, session, user)
msg = event_subscriber.get_next_message()