diff options
| author | Max Nanis | 2026-03-06 16:49:46 -0500 |
|---|---|---|
| committer | Max Nanis | 2026-03-06 16:49:46 -0500 |
| commit | 91d040211a4ed6e4157896256a762d3854777b5e (patch) | |
| tree | cd95922ea4257dc8d3f4e4cbe8534474709a20dc /tests/grliq | |
| download | generalresearch-91d040211a4ed6e4157896256a762d3854777b5e.tar.gz generalresearch-91d040211a4ed6e4157896256a762d3854777b5e.zip | |
Initial commitv3.3.4
Diffstat (limited to 'tests/grliq')
| -rw-r--r-- | tests/grliq/__init__.py | 0 | ||||
| -rw-r--r-- | tests/grliq/managers/__init__.py | 0 | ||||
| -rw-r--r-- | tests/grliq/managers/test_forensic_data.py | 212 | ||||
| -rw-r--r-- | tests/grliq/managers/test_forensic_results.py | 16 | ||||
| -rw-r--r-- | tests/grliq/models/__init__.py | 0 | ||||
| -rw-r--r-- | tests/grliq/models/test_forensic_data.py | 49 | ||||
| -rw-r--r-- | tests/grliq/test_utils.py | 17 |
7 files changed, 294 insertions, 0 deletions
diff --git a/tests/grliq/__init__.py b/tests/grliq/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/grliq/__init__.py diff --git a/tests/grliq/managers/__init__.py b/tests/grliq/managers/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/grliq/managers/__init__.py diff --git a/tests/grliq/managers/test_forensic_data.py b/tests/grliq/managers/test_forensic_data.py new file mode 100644 index 0000000..ed4da80 --- /dev/null +++ b/tests/grliq/managers/test_forensic_data.py @@ -0,0 +1,212 @@ +from datetime import timedelta +from uuid import uuid4 + +import pytest + +from generalresearch.grliq.models.events import TimingData, MouseEvent +from generalresearch.grliq.models.forensic_data import GrlIqData +from generalresearch.grliq.models.forensic_result import ( + GrlIqCheckerResults, + GrlIqForensicCategoryResult, +) + +try: + from psycopg.errors import UniqueViolation +except ImportError: + pass + + +class TestGrlIqDataManager: + + def test_create_dummy(self, grliq_dm): + from generalresearch.grliq.managers.forensic_data import GrlIqDataManager + from generalresearch.grliq.models.forensic_data import GrlIqData + + grliq_dm: GrlIqDataManager + gd1: GrlIqData = grliq_dm.create_dummy(is_attempt_allowed=True) + + assert isinstance(gd1, GrlIqData) + assert isinstance(gd1.results, GrlIqCheckerResults) + assert isinstance(gd1.category_result, GrlIqForensicCategoryResult) + + def test_create(self, grliq_data, grliq_dm): + grliq_dm.create(grliq_data) + assert grliq_data.id is not None + + with pytest.raises(UniqueViolation): + grliq_dm.create(grliq_data) + + @pytest.mark.skip(reason="todo") + def test_set_result(self): + pass + + @pytest.mark.skip(reason="todo") + def test_update_fingerprint(self): + pass + + @pytest.mark.skip(reason="todo") + def test_update_fingerprint(self): + pass + + @pytest.mark.skip(reason="todo") + def test_update_data(self): + pass + + def test_get_id(self, grliq_data, grliq_dm): + grliq_dm.create(grliq_data) + + res = grliq_dm.get_data(forensic_id=grliq_data.id) + assert res == grliq_data + + def test_get_uuid(self, grliq_data, grliq_dm): + grliq_dm.create(grliq_data) + + res = grliq_dm.get_data(forensic_uuid=grliq_data.uuid) + assert res == grliq_data + + @pytest.mark.skip(reason="todo") + def test_filter_timing_data(self): + pass + + @pytest.mark.skip(reason="todo") + def test_get_unique_user_count_by_fingerprint(self): + pass + + def test_filter_data(self, grliq_data, grliq_dm): + grliq_dm.create(grliq_data) + res = grliq_dm.filter_data(uuids=[grliq_data.uuid])[0] + assert res == grliq_data + now = res.created_at + res = grliq_dm.filter_data( + created_after=now, created_before=now + timedelta(minutes=1) + ) + assert len(res) == 1 + res = grliq_dm.filter_data( + created_after=now + timedelta(seconds=1), + created_before=now + timedelta(minutes=1), + ) + assert len(res) == 0 + + @pytest.mark.skip(reason="todo") + def test_filter_results(self): + pass + + @pytest.mark.skip(reason="todo") + def test_filter_category_results(self): + pass + + @pytest.mark.skip(reason="todo") + def test_make_filter_str(self): + pass + + def test_filter_count(self, grliq_dm, product): + res = grliq_dm.filter_count(product_id=product.uuid) + + assert isinstance(res, int) + + @pytest.mark.skip(reason="todo") + def test_filter(self): + pass + + @pytest.mark.skip(reason="todo") + def test_temporary_add_missing_fields(self): + pass + + +class TestForensicDataGetAndFilter: + + def test_events(self, grliq_dm, grliq_em): + """If load_events=True, the events and mouse_events attributes should + be an array no matter what. An empty array means that the events were + loaded, but there were no events available. + + If loaded_eventsFalse, the events and mouse_events attributes should + be None + """ + # Load Events == False + forensic_uuid = uuid4().hex + grliq_dm.create_dummy(is_attempt_allowed=True, uuid=forensic_uuid) + + instance = grliq_dm.filter_data(uuids=[forensic_uuid])[0] + assert isinstance(instance, GrlIqData) + + assert instance.events is None + assert instance.mouse_events is None + + # Load Events == True + instance = grliq_dm.get_data(forensic_uuid=forensic_uuid, load_events=True) + assert isinstance(instance, GrlIqData) + # This one doesn't have any events though + assert len(instance.events) == 0 + assert len(instance.mouse_events) == 0 + + def test_timing(self, grliq_dm, grliq_em): + forensic_uuid = uuid4().hex + grliq_dm.create_dummy(is_attempt_allowed=True, uuid=forensic_uuid) + + instance = grliq_dm.filter_data(uuids=[forensic_uuid])[0] + + grliq_em.update_or_create_timing( + session_uuid=instance.mid, + timing_data=TimingData( + client_rtts=[100, 200, 150], server_rtts=[150, 120, 120] + ), + ) + instance = grliq_dm.get_data(forensic_uuid=forensic_uuid, load_events=True) + assert isinstance(instance, GrlIqData) + assert isinstance(instance.events, list) + assert isinstance(instance.mouse_events, list) + assert isinstance(instance.timing_data, TimingData) + + def test_events_events(self, grliq_dm, grliq_em): + forensic_uuid = uuid4().hex + grliq_dm.create_dummy(is_attempt_allowed=True, uuid=forensic_uuid) + + instance = grliq_dm.filter_data(uuids=[forensic_uuid])[0] + + grliq_em.update_or_create_events( + session_uuid=instance.mid, + events=[{"a": "b"}], + mouse_events=[], + event_start=instance.created_at, + event_end=instance.created_at + timedelta(minutes=1), + ) + instance = grliq_dm.get_data(forensic_uuid=forensic_uuid, load_events=True) + assert isinstance(instance, GrlIqData) + assert isinstance(instance.events, list) + assert isinstance(instance.mouse_events, list) + assert instance.timing_data is None + assert instance.events == [{"a": "b"}] + assert len(instance.mouse_events) == 0 + assert len(instance.pointer_move_events) == 0 + assert len(instance.keyboard_events) == 0 + + def test_events_click(self, grliq_dm, grliq_em): + forensic_uuid = uuid4().hex + grliq_dm.create_dummy(is_attempt_allowed=True, uuid=forensic_uuid) + instance = grliq_dm.get_data(forensic_uuid=forensic_uuid, load_events=True) + + click_event = { + "type": "click", + "pageX": 0, + "pageY": 0, + "timeStamp": 123, + "pointerType": "mouse", + } + me = MouseEvent.from_dict(click_event) + grliq_em.update_or_create_events( + session_uuid=instance.mid, + events=[click_event], + mouse_events=[], + event_start=instance.created_at, + event_end=instance.created_at + timedelta(minutes=1), + ) + instance = grliq_dm.get_data(forensic_uuid=forensic_uuid, load_events=True) + assert isinstance(instance, GrlIqData) + assert isinstance(instance.events, list) + assert isinstance(instance.mouse_events, list) + assert instance.timing_data is None + assert instance.events == [click_event] + assert instance.mouse_events == [me] + assert len(instance.pointer_move_events) == 0 + assert len(instance.keyboard_events) == 0 diff --git a/tests/grliq/managers/test_forensic_results.py b/tests/grliq/managers/test_forensic_results.py new file mode 100644 index 0000000..a837a64 --- /dev/null +++ b/tests/grliq/managers/test_forensic_results.py @@ -0,0 +1,16 @@ +class TestGrlIqCategoryResultsReader: + + def test_filter_category_results(self, grliq_dm, grliq_crr): + from generalresearch.grliq.models.forensic_result import ( + Phase, + GrlIqForensicCategoryResult, + ) + + # this is just testing that it doesn't fail + grliq_dm.create_dummy(is_attempt_allowed=True) + grliq_dm.create_dummy(is_attempt_allowed=True) + + res = grliq_crr.filter_category_results(limit=2, phase=Phase.OFFERWALL_ENTER)[0] + assert res.get("category_result") + assert isinstance(res["category_result"], GrlIqForensicCategoryResult) + assert res["user_agent"].os.family diff --git a/tests/grliq/models/__init__.py b/tests/grliq/models/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/grliq/models/__init__.py diff --git a/tests/grliq/models/test_forensic_data.py b/tests/grliq/models/test_forensic_data.py new file mode 100644 index 0000000..653f9a9 --- /dev/null +++ b/tests/grliq/models/test_forensic_data.py @@ -0,0 +1,49 @@ +import pytest +from pydantic import ValidationError + +from generalresearch.grliq.models.forensic_data import GrlIqData, Platform + + +class TestGrlIqData: + + def test_supported_fonts(self, grliq_data): + s = grliq_data.supported_fonts_binary + assert len(s) == 1043 + assert "Ubuntu" in grliq_data.supported_fonts + + def test_battery(self, grliq_data): + assert not grliq_data.battery_charging + assert grliq_data.battery_level == 0.41 + + def test_base(self, grliq_data): + g: GrlIqData = grliq_data + assert g.timezone == "America/Los_Angeles" + assert g.platform == Platform.LINUX_X86_64 + assert g.webgl_extensions + # ... more + + assert g.results is None + assert g.category_result is None + + s = g.model_dump_json() + g2: GrlIqData = GrlIqData.model_validate_json(s) + + assert g2.results is None + assert g2.category_result is None + + assert g == g2 + + # Testing things that will cause a validation error, should only be + # because something is "corrupt", not b/c the user is a baddie + def test_corrupt(self, grliq_data): + """Test for timestamp and timezone offset mismatch validation.""" + d = grliq_data.model_dump(mode="json") + d.update( + { + "timezone": "America/XXX", + } + ) + with pytest.raises(ValidationError) as e: + GrlIqData.model_validate(d) + + assert "Invalid timezone name" in str(e.value) diff --git a/tests/grliq/test_utils.py b/tests/grliq/test_utils.py new file mode 100644 index 0000000..d9034d5 --- /dev/null +++ b/tests/grliq/test_utils.py @@ -0,0 +1,17 @@ +from pathlib import Path +from uuid import uuid4 + + +class TestUtils: + + def test_get_screenshot_fp(self, mnt_grliq_archive_dir, utc_hour_ago): + from generalresearch.grliq.utils import get_screenshot_fp + + fp1 = get_screenshot_fp( + created_at=utc_hour_ago, + forensic_uuid=uuid4(), + grliq_archive_dir=mnt_grliq_archive_dir, + create_dir_if_not_exists=True, + ) + + assert isinstance(fp1, Path) |
