From 1d049c12722b9def73b85c9e192c8f01c7d1946b Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 19 Jun 2025 18:03:03 -0500 Subject: [PATCH] Consolidate event creation in test suite with faker-based fixture --- tests/conftest.py | 38 ++++++++++++++++++++++++++ tests/events/test_ainstallation.py | 25 +++++++++-------- tests/events/test_arepository.py | 5 ++-- tests/events/test_installation.py | 27 +++++++++++-------- tests/events/test_repository.py | 5 ++-- tests/test_models.py | 43 +++++++++++------------------- tests/test_views.py | 30 +++++++++------------ 7 files changed, 100 insertions(+), 73 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 8f8fe80..70bf9cb 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -12,6 +12,8 @@ from django.test import override_settings from django.urls import clear_url_caches from django.urls import path +from faker import Faker +from gidgethub import sansio from django_github_app.conf import GITHUB_APP_SETTINGS_NAME from django_github_app.github import AsyncGitHubAPI @@ -232,3 +234,39 @@ async def arepository(ainstallation, get_mock_github_api, baker): mock_github_api.installation_id = repository.installation.installation_id repository.get_gh_client = MagicMock(return_value=mock_github_api) return repository + + +@pytest.fixture +def faker(): + return Faker() + + +@pytest.fixture +def create_event(faker): + def _create_event(event_type, delivery_id=None, **data): + if delivery_id is None: + delivery_id = seq.next() + + if event_type == "issue_comment" and "comment" not in data: + data["comment"] = {"body": faker.sentence()} + + if "comment" in data and isinstance(data["comment"], str): + # Allow passing just the comment body as a string + data["comment"] = {"body": data["comment"]} + + if "comment" in data and "user" not in data["comment"]: + data["comment"]["user"] = {"login": faker.user_name()} + + if "repository" not in data and event_type in [ + "issue_comment", + "pull_request", + "push", + ]: + data["repository"] = { + "owner": {"login": faker.user_name()}, + "name": faker.slug(), + } + + return sansio.Event(data=data, event=event_type, delivery_id=delivery_id) + + return _create_event diff --git a/tests/events/test_ainstallation.py b/tests/events/test_ainstallation.py index f2fdbd7..4117e06 100644 --- a/tests/events/test_ainstallation.py +++ b/tests/events/test_ainstallation.py @@ -2,7 +2,6 @@ import pytest from asgiref.sync import sync_to_async -from gidgethub.abc import sansio from model_bakery import baker from django_github_app.events.ainstallation import acreate_installation @@ -20,7 +19,11 @@ @pytest.mark.parametrize("app_settings_app_id_type", [int, str]) async def test_acreate_installation( - app_settings_app_id_type, installation_id, repository_id, override_app_settings + app_settings_app_id_type, + installation_id, + repository_id, + override_app_settings, + create_event, ): data = { "installation": { @@ -31,7 +34,7 @@ async def test_acreate_installation( {"id": repository_id, "node_id": "node1234", "full_name": "owner/repo"} ], } - event = sansio.Event(data, event="installation", delivery_id="1234") + event = create_event("installation", delivery_id="1234", **data) with override_app_settings( APP_ID=data["installation"]["app_id"] @@ -47,13 +50,13 @@ async def test_acreate_installation( assert installation.data == data["installation"] -async def test_adelete_installation(ainstallation): +async def test_adelete_installation(ainstallation, create_event): data = { "installation": { "id": ainstallation.installation_id, } } - event = sansio.Event(data, event="installation", delivery_id="1234") + event = create_event("installation", delivery_id="1234", **data) await adelete_installation(event, None) @@ -70,7 +73,7 @@ async def test_adelete_installation(ainstallation): ], ) async def test_atoggle_installation_status_suspend( - status, action, expected, ainstallation + status, action, expected, ainstallation, create_event ): ainstallation.status = status await ainstallation.asave() @@ -81,7 +84,7 @@ async def test_atoggle_installation_status_suspend( "id": ainstallation.installation_id, }, } - event = sansio.Event(data, event="installation", delivery_id="1234") + event = create_event("installation", delivery_id="1234", **data) assert ainstallation.status != expected @@ -91,13 +94,13 @@ async def test_atoggle_installation_status_suspend( assert ainstallation.status == expected -async def test_async_installation_data(ainstallation): +async def test_async_installation_data(ainstallation, create_event): data = { "installation": { "id": ainstallation.installation_id, }, } - event = sansio.Event(data, event="installation", delivery_id="1234") + event = create_event("installation", delivery_id="1234", **data) assert ainstallation.data != data @@ -107,7 +110,7 @@ async def test_async_installation_data(ainstallation): assert ainstallation.data == data["installation"] -async def test_async_installation_repositories(ainstallation): +async def test_async_installation_repositories(ainstallation, create_event): existing_repo = await sync_to_async(baker.make)( "django_github_app.Repository", installation=ainstallation, @@ -131,7 +134,7 @@ async def test_async_installation_repositories(ainstallation): } ], } - event = sansio.Event(data, event="installation", delivery_id="1234") + event = create_event("installation", delivery_id="1234", **data) assert await Repository.objects.filter( repository_id=data["repositories_removed"][0]["id"] diff --git a/tests/events/test_arepository.py b/tests/events/test_arepository.py index 0d3d3a7..e0bfec9 100644 --- a/tests/events/test_arepository.py +++ b/tests/events/test_arepository.py @@ -2,7 +2,6 @@ import pytest from asgiref.sync import sync_to_async -from gidgethub import sansio from model_bakery import baker from django_github_app.events.arepository import arename_repository @@ -12,7 +11,7 @@ pytestmark = [pytest.mark.asyncio, pytest.mark.django_db] -async def test_arename_repository(ainstallation, repository_id): +async def test_arename_repository(ainstallation, repository_id, create_event): repository = await sync_to_async(baker.make)( "django_github_app.Repository", installation=ainstallation, @@ -26,7 +25,7 @@ async def test_arename_repository(ainstallation, repository_id): "full_name": f"owner/new_name_{seq.next()}", }, } - event = sansio.Event(data, event="repository", delivery_id="1234") + event = create_event("repository", delivery_id="1234", **data) assert not await Repository.objects.filter( full_name=data["repository"]["full_name"] diff --git a/tests/events/test_installation.py b/tests/events/test_installation.py index 6c34301..1d3f37a 100644 --- a/tests/events/test_installation.py +++ b/tests/events/test_installation.py @@ -1,7 +1,6 @@ from __future__ import annotations import pytest -from gidgethub.abc import sansio from model_bakery import baker from django_github_app.events.installation import create_installation @@ -19,7 +18,11 @@ @pytest.mark.parametrize("app_settings_app_id_type", [int, str]) def test_create_installation( - app_settings_app_id_type, installation_id, repository_id, override_app_settings + app_settings_app_id_type, + installation_id, + repository_id, + override_app_settings, + create_event, ): data = { "installation": { @@ -30,7 +33,7 @@ def test_create_installation( {"id": repository_id, "node_id": "node1234", "full_name": "owner/repo"} ], } - event = sansio.Event(data, event="installation", delivery_id="1234") + event = create_event("installation", delivery_id="1234", **data) with override_app_settings( APP_ID=data["installation"]["app_id"] @@ -44,13 +47,13 @@ def test_create_installation( assert installation.data == data["installation"] -def test_delete_installation(installation): +def test_delete_installation(installation, create_event): data = { "installation": { "id": installation.installation_id, } } - event = sansio.Event(data, event="installation", delivery_id="1234") + event = create_event("installation", delivery_id="1234", **data) delete_installation(event, None) @@ -66,7 +69,9 @@ def test_delete_installation(installation): (InstallationStatus.INACTIVE, "unsuspend", InstallationStatus.ACTIVE), ], ) -def test_toggle_installation_status_suspend(status, action, expected, installation): +def test_toggle_installation_status_suspend( + status, action, expected, installation, create_event +): installation.status = status installation.save() @@ -76,7 +81,7 @@ def test_toggle_installation_status_suspend(status, action, expected, installati "id": installation.installation_id, }, } - event = sansio.Event(data, event="installation", delivery_id="1234") + event = create_event("installation", delivery_id="1234", **data) assert installation.status != expected @@ -86,13 +91,13 @@ def test_toggle_installation_status_suspend(status, action, expected, installati assert installation.status == expected -def test_sync_installation_data(installation): +def test_sync_installation_data(installation, create_event): data = { "installation": { "id": installation.installation_id, }, } - event = sansio.Event(data, event="installation", delivery_id="1234") + event = create_event("installation", delivery_id="1234", **data) assert installation.data != data @@ -102,7 +107,7 @@ def test_sync_installation_data(installation): assert installation.data == data["installation"] -def test_sync_installation_repositories(installation): +def test_sync_installation_repositories(installation, create_event): existing_repo = baker.make( "django_github_app.Repository", installation=installation, @@ -126,7 +131,7 @@ def test_sync_installation_repositories(installation): } ], } - event = sansio.Event(data, event="installation", delivery_id="1234") + event = create_event("installation", delivery_id="1234", **data) assert Repository.objects.filter( repository_id=data["repositories_removed"][0]["id"] diff --git a/tests/events/test_repository.py b/tests/events/test_repository.py index 72db763..9b9ec4c 100644 --- a/tests/events/test_repository.py +++ b/tests/events/test_repository.py @@ -1,7 +1,6 @@ from __future__ import annotations import pytest -from gidgethub import sansio from model_bakery import baker from django_github_app.events.repository import rename_repository @@ -11,7 +10,7 @@ pytestmark = [pytest.mark.django_db] -def test_rename_repository(installation, repository_id): +def test_rename_repository(installation, repository_id, create_event): repository = baker.make( "django_github_app.Repository", installation=installation, @@ -25,7 +24,7 @@ def test_rename_repository(installation, repository_id): "full_name": f"owner/new_name_{seq.next()}", }, } - event = sansio.Event(data, event="repository", delivery_id="1234") + event = create_event("repository", delivery_id="1234", **data) assert not Repository.objects.filter( full_name=data["repository"]["full_name"] diff --git a/tests/test_models.py b/tests/test_models.py index 12bb85d..bc1d5c6 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -9,7 +9,6 @@ from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import rsa from django.utils import timezone -from gidgethub import sansio from model_bakery import baker from django_github_app.github import AsyncGitHubAPI @@ -23,14 +22,6 @@ pytestmark = pytest.mark.django_db -@pytest.fixture -def create_event(): - def _create_event(data, event): - return sansio.Event(data=data, event=event, delivery_id=seq.next()) - - return _create_event - - @pytest.fixture def private_key(): private_key = rsa.generate_private_key( @@ -52,7 +43,9 @@ async def test_acreate_from_event(self, create_event): data = {"foo": "bar"} event = "baz" - event_log = await EventLog.objects.acreate_from_event(create_event(data, event)) + event_log = await EventLog.objects.acreate_from_event( + create_event(event, **data) + ) assert event_log.event == event assert event_log.payload == data @@ -61,7 +54,7 @@ def test_create_from_event(self, create_event): data = {"foo": "bar"} event = "baz" - event_log = EventLog.objects.create_from_event(create_event(data, event)) + event_log = EventLog.objects.create_from_event(create_event(event, **data)) assert event_log.event == event assert event_log.payload == data @@ -140,11 +133,9 @@ async def test_acreate_from_event( "app_id": seq.next(), } event = create_event( - { - "installation": installation_data, - "repositories": repositories, - }, "installation", + installation=installation_data, + repositories=repositories, ) with override_app_settings( @@ -173,11 +164,9 @@ def test_create_from_event( "app_id": seq.next(), } event = create_event( - { - "installation": installation_data, - "repositories": repositories, - }, "installation", + installation=installation_data, + repositories=repositories, ) with override_app_settings( @@ -221,7 +210,7 @@ def test_create_from_gh_data(self): @pytest.mark.asyncio async def test_aget_from_event(self, ainstallation, create_event): event = create_event( - {"installation": {"id": ainstallation.installation_id}}, "installation" + "installation", installation={"id": ainstallation.installation_id} ) result = await Installation.objects.aget_from_event(event) @@ -230,7 +219,7 @@ async def test_aget_from_event(self, ainstallation, create_event): @pytest.mark.asyncio async def test_aget_from_event_doesnotexist(self, installation_id, create_event): - event = create_event({"installation": {"id": installation_id}}, "installation") + event = create_event("installation", installation={"id": installation_id}) installation = await Installation.objects.aget_from_event(event) @@ -238,7 +227,7 @@ async def test_aget_from_event_doesnotexist(self, installation_id, create_event) def test_get_from_event(self, installation, create_event): event = create_event( - {"installation": {"id": installation.installation_id}}, "installation" + "installation", installation={"id": installation.installation_id} ) result = Installation.objects.get_from_event(event) @@ -258,12 +247,12 @@ class TestInstallationStatus: ], ) def test_from_event(self, action, expected, create_event): - event = create_event({"action": action}, "installation") + event = create_event("installation", action=action) assert InstallationStatus.from_event(event) == expected def test_from_event_invalid_action(self, create_event): - event = create_event({"action": "invalid"}, "installation") + event = create_event("installation", action="invalid") with pytest.raises(ValueError): InstallationStatus.from_event(event) @@ -411,7 +400,7 @@ async def test_aget_from_event(self, arepository, create_event): } repo = await Repository.objects.aget_from_event( - create_event(data, "repository") + create_event("repository", **data) ) assert repo.repository_id == data["repository"]["id"] @@ -428,7 +417,7 @@ async def test_aget_from_event_doesnotexist(self, repository_id, create_event): } repo = await Repository.objects.aget_from_event( - create_event(data, "repository") + create_event("repository", **data) ) assert repo is None @@ -442,7 +431,7 @@ def test_get_from_event(self, repository, create_event): } } - repo = Repository.objects.get_from_event(create_event(data, "repository")) + repo = Repository.objects.get_from_event(create_event("repository", **data)) assert repo.repository_id == data["repository"]["id"] assert repo.repository_node_id == data["repository"]["node_id"] diff --git a/tests/test_views.py b/tests/test_views.py index c43bb11..eff55a9 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -239,14 +239,13 @@ async def test_router_dispatch(self, aregister_webhook_event, webhook_request): assert isinstance(webhook_data["gh"], AsyncGitHubAPI) async def test_router_dispatch_unhandled_event( - self, monkeypatch, aregister_webhook_event, override_app_settings + self, monkeypatch, aregister_webhook_event, override_app_settings, create_event ): with override_app_settings(LOG_ALL_EVENTS=False): aregister_webhook_event("push", should_fail=True) view = AsyncWebhookView() - data = {"action": "opened"} - event = sansio.Event(data, event="issues", delivery_id="12345") + event = create_event("issues", action="opened", delivery_id="12345") monkeypatch.setattr(view, "get_event", lambda request: event) @@ -256,14 +255,13 @@ async def test_router_dispatch_unhandled_event( assert json.loads(response.content) == {"message": "ok"} async def test_unhandled_event_log_creation_with_log_all( - self, monkeypatch, aregister_webhook_event, override_app_settings + self, monkeypatch, aregister_webhook_event, override_app_settings, create_event ): with override_app_settings(LOG_ALL_EVENTS=True): aregister_webhook_event("push", should_fail=True) view = AsyncWebhookView() - data = {"action": "opened"} - event = sansio.Event(data, event="issues", delivery_id="12345") + event = create_event("issues", action="opened", delivery_id="12345") monkeypatch.setattr(view, "get_event", lambda request: event) @@ -275,14 +273,13 @@ async def test_unhandled_event_log_creation_with_log_all( assert count_after - count_before == 1 async def test_unhandled_event_log_creation_without_log_all( - self, monkeypatch, aregister_webhook_event, override_app_settings + self, monkeypatch, aregister_webhook_event, override_app_settings, create_event ): with override_app_settings(LOG_ALL_EVENTS=False): aregister_webhook_event("push", should_fail=True) view = AsyncWebhookView() - data = {"action": "opened"} - event = sansio.Event(data, event="issues", delivery_id="12345") + event = create_event("issues", action="opened", delivery_id="12345") monkeypatch.setattr(view, "get_event", lambda request: event) @@ -352,14 +349,13 @@ def test_router_dispatch(self, register_webhook_event, webhook_request): assert isinstance(webhook_data["gh"], SyncGitHubAPI) def test_router_dispatch_unhandled_event( - self, monkeypatch, register_webhook_event, override_app_settings + self, monkeypatch, register_webhook_event, override_app_settings, create_event ): with override_app_settings(LOG_ALL_EVENTS=False): register_webhook_event("push", should_fail=True) view = SyncWebhookView() - data = {"action": "opened"} - event = sansio.Event(data, event="issues", delivery_id="12345") + event = create_event("issues", action="opened", delivery_id="12345") monkeypatch.setattr(view, "get_event", lambda request: event) @@ -369,14 +365,13 @@ def test_router_dispatch_unhandled_event( assert json.loads(response.content) == {"message": "ok"} def test_unhandled_event_log_creation_with_log_all( - self, monkeypatch, register_webhook_event, override_app_settings + self, monkeypatch, register_webhook_event, override_app_settings, create_event ): with override_app_settings(LOG_ALL_EVENTS=True): register_webhook_event("push", should_fail=True) view = SyncWebhookView() - data = {"action": "opened"} - event = sansio.Event(data, event="issues", delivery_id="12345") + event = create_event("issues", action="opened", delivery_id="12345") monkeypatch.setattr(view, "get_event", lambda request: event) @@ -388,14 +383,13 @@ def test_unhandled_event_log_creation_with_log_all( assert count_after - count_before == 1 def test_unhandled_event_log_creation_without_log_all( - self, monkeypatch, register_webhook_event, override_app_settings + self, monkeypatch, register_webhook_event, override_app_settings, create_event ): with override_app_settings(LOG_ALL_EVENTS=False): register_webhook_event("push", should_fail=True) view = SyncWebhookView() - data = {"action": "opened"} - event = sansio.Event(data, event="issues", delivery_id="12345") + event = create_event("issues", action="opened", delivery_id="12345") monkeypatch.setattr(view, "get_event", lambda request: event)