From 9a700d687a503c7f39da3d7690b7e9089ed00f79 Mon Sep 17 00:00:00 2001 From: Philippe Ombredanne Date: Wed, 14 Aug 2024 18:00:46 +0200 Subject: [PATCH] Inline test fixtures Test fixtures should not be shared so we can evolve unit tests separately Signed-off-by: Philippe Ombredanne --- tests/{__init__.py => fedcode_test_utils.py} | 11 ++ tests/test_activitypub.py | 92 ++++++++++-- tests/test_ap_api.py | 77 ++++++++-- tests/test_federation.py | 30 +++- tests/test_importer.py | 28 +++- tests/test_models.py | 143 ++++++------------- tests/test_utils.py | 1 - tests/test_vocabulary_toap.py | 96 +++++++++++-- tests/test_webfinger.py | 39 +++-- 9 files changed, 365 insertions(+), 152 deletions(-) rename tests/{__init__.py => fedcode_test_utils.py} (58%) diff --git a/tests/__init__.py b/tests/fedcode_test_utils.py similarity index 58% rename from tests/__init__.py rename to tests/fedcode_test_utils.py index 8db4365..96165be 100644 --- a/tests/__init__.py +++ b/tests/fedcode_test_utils.py @@ -6,3 +6,14 @@ # See https://github.com/nexB/federatedcode for support or download. # See https://aboutcode.org for more information about AboutCode.org OSS projects. # + +import pytest +from django.db.models.signals import post_save + + +@pytest.fixture(autouse=True) +def mute_post_save_signal(request): + """ + copied from https://www.cameronmaske.com/muting-django-signals-with-a-pytest-fixture/ + """ + post_save.receivers = [] diff --git a/tests/test_activitypub.py b/tests/test_activitypub.py index 7f5d104..b091fe7 100644 --- a/tests/test_activitypub.py +++ b/tests/test_activitypub.py @@ -9,6 +9,8 @@ import json import pytest +from django.contrib.auth.models import User +from fedcode_test_utils import mute_post_save_signal # NOQA from fedcode.activitypub import AP_CONTEXT from fedcode.activitypub import Activity @@ -19,21 +21,87 @@ from fedcode.activitypub import create_activity_obj from fedcode.models import Follow from fedcode.models import Note +from fedcode.models import Package +from fedcode.models import Person from fedcode.models import Repository from fedcode.models import Review +from fedcode.models import Service from fedcode.models import SyncRequest +from fedcode.models import Vulnerability -from .test_models import fake_service -from .test_models import follow -from .test_models import mute_post_save_signal -from .test_models import note -from .test_models import package -from .test_models import person -from .test_models import pkg_note -from .test_models import repo -from .test_models import review -from .test_models import service -from .test_models import vulnerability + +@pytest.fixture +def service(db): + user = User.objects.create(username="vcio", email="vcio@nexb.com", password="complex-password") + return Service.objects.create(user=user) + + +@pytest.fixture +def package(db, service): + return Package.objects.create(purl="pkg:maven/org.apache.logging", service=service) + + +@pytest.fixture +def person(db): + user1 = User.objects.create(username="ziad", email="ziad@nexb.com", password="complex-password") + return Person.objects.create(user=user1, summary="Hello World", public_key="PUBLIC_KEY") + + +@pytest.fixture +def repo(db, service, mute_post_save_signal): + """Simple Git Repository""" + return Repository.objects.create( + url="https://github.com/nexB/fake-repo", + path="./review/tests/test_data/test_git_repo_v1", + admin=service, + ) + + +@pytest.fixture +def vulnerability(db, repo): + return Vulnerability.objects.create(id="VCID-1155-4sem-aaaq", repo=repo) + + +@pytest.fixture +def note(db): + return Note.objects.create(acct="ziad@127.0.0.1:8000", content="Comment #1") + + +@pytest.fixture +def follow(db, package, person): + return Follow.objects.create(package=package, person=person) + + +@pytest.fixture +def fake_service(db): + user = User.objects.create( + username="fake_service", + email="vcio@nexb.com", + password="complex-password", + ) + return Service.objects.create(user=user) + + +@pytest.fixture +def pkg_note(db, package): + return Note.objects.create( + acct=package.acct, + content="purl: " + "pkg:maven/org.apache.logging@2.23-r0?arch=aarch64&distroversion=edge&reponame=community\n" + " affected_by_vulnerabilities: ....", + ) + + +@pytest.fixture +def review(db, repo, person): + return Review.objects.create( + headline="Review title 1", + author=person, + repository=repo, + filepath="/apache/httpd/VCID-1a68-fd5t-aaam.yml", + data="text diff", + commit="49d8c5fd4bea9488186a832b13ebdc83484f1b6a", + ) @pytest.mark.django_db @@ -188,7 +256,7 @@ def test_person_delete_note(person, note): @pytest.mark.django_db -def test_person_delete_note(person, note): +def test_person_delete_note2(person, note): payload = json.dumps( { **AP_CONTEXT, diff --git a/tests/test_ap_api.py b/tests/test_ap_api.py index cee7b4a..1b0e136 100644 --- a/tests/test_ap_api.py +++ b/tests/test_ap_api.py @@ -6,14 +6,14 @@ # See https://github.com/nexB/federatedcode for support or download. # See https://aboutcode.org for more information about AboutCode.org OSS projects. # -import datetime import json -from datetime import datetime from datetime import timedelta import pytest from django.contrib.auth.models import User from django.urls import reverse +from django.utils import timezone +from fedcode_test_utils import mute_post_save_signal # NOQA from oauth2_provider.models import AccessToken from oauth2_provider.models import Application from rest_framework.test import APIClient @@ -21,22 +21,14 @@ from fedcode.activitypub import AP_CONTEXT from fedcode.models import Follow from fedcode.models import Note +from fedcode.models import Package from fedcode.models import Person +from fedcode.models import Repository from fedcode.models import Review +from fedcode.models import Service from fedcode.models import Vulnerability -from fedcode.utils import generate_webfinger from federatedcode.settings import AP_CONTENT_TYPE -from .test_models import follow -from .test_models import mute_post_save_signal -from .test_models import note -from .test_models import package -from .test_models import person -from .test_models import repo -from .test_models import review -from .test_models import service -from .test_models import vulnerability - def create_token(user): app = Application.objects.create( @@ -49,13 +41,68 @@ def create_token(user): token = AccessToken.objects.create( user=user, scope="read write", - expires=datetime.now() + timedelta(seconds=500), + expires=timezone.now() + timedelta(seconds=500), token="fake-access-key", application=app, ) return f"Bearer {token}" +@pytest.fixture +def service(db): + user = User.objects.create( + username="vcio", + email="vcio@nexb.com", + password="complex-password", + ) + return Service.objects.create( + user=user, + ) + + +@pytest.fixture +def package(db, service): + return Package.objects.create(purl="pkg:maven/org.apache.logging", service=service) + + +@pytest.fixture +def person(db): + user1 = User.objects.create(username="ziad", email="ziad@nexb.com", password="complex-password") + return Person.objects.create(user=user1, summary="Hello World", public_key="PUBLIC_KEY") + + +@pytest.fixture +def repo(db, service, mute_post_save_signal): + """Simple Git Repository""" + return Repository.objects.create( + url="https://github.com/nexB/fake-repo", + path="./review/tests/test_data/test_git_repo_v1", + admin=service, + ) + + +@pytest.fixture +def vulnerability(db, repo): + return Vulnerability.objects.create(id="VCID-1155-4sem-aaaq", repo=repo) + + +@pytest.fixture +def review(db, repo, person): + return Review.objects.create( + headline="Review title 1", + author=person, + repository=repo, + filepath="/apache/httpd/VCID-1a68-fd5t-aaam.yml", + data="text diff", + commit="49d8c5fd4bea9488186a832b13ebdc83484f1b6a", + ) + + +@pytest.fixture +def note(db): + return Note.objects.create(acct="ziad@127.0.0.1:8000", content="Comment #1") + + @pytest.mark.django_db def test_get_ap_profile_user(person, service): client = APIClient() @@ -273,7 +320,7 @@ def test_post_user_outbox(person): auth = create_token(person.user) client.credentials(HTTP_AUTHORIZATION=auth) path = reverse("user-outbox", args=[person.user.username]) - response = client.post( + _response = client.post( path, { **AP_CONTEXT, diff --git a/tests/test_federation.py b/tests/test_federation.py index 19936fe..db1f325 100644 --- a/tests/test_federation.py +++ b/tests/test_federation.py @@ -10,18 +10,40 @@ from unittest import mock import pytest +from django.contrib.auth.models import User from fedcode.activitypub import AP_CONTEXT from fedcode.activitypub import create_activity_obj from fedcode.models import Follow from fedcode.models import Note +from fedcode.models import Package +from fedcode.models import Person from fedcode.models import RemoteActor +from fedcode.models import Service from fedcode.utils import file_data -from .test_models import package -from .test_models import person -from .test_models import remote_person -from .test_models import service + +@pytest.fixture +def service(db): + user = User.objects.create(username="vcio", email="vcio@nexb.com", password="complex-password") + return Service.objects.create(user=user) + + +@pytest.fixture +def package(db, service): + return Package.objects.create(purl="pkg:maven/org.apache.logging", service=service) + + +@pytest.fixture +def person(db): + user1 = User.objects.create(username="ziad", email="ziad@nexb.com", password="complex-password") + return Person.objects.create(user=user1, summary="Hello World", public_key="PUBLIC_KEY") + + +@pytest.fixture +def remote_person(db): + remote_user1 = RemoteActor.objects.create(url="127.0.0.2", username="remote-ziad") + return Person.objects.create(remote_actor=remote_user1) @mock.patch("httpx.Client") diff --git a/tests/test_importer.py b/tests/test_importer.py index 91316d7..221377b 100644 --- a/tests/test_importer.py +++ b/tests/test_importer.py @@ -7,15 +7,37 @@ # See https://aboutcode.org for more information about AboutCode.org OSS projects. # import pytest +from django.contrib.auth.models import User +from fedcode_test_utils import mute_post_save_signal # NOQA from fedcode.importer import Importer from fedcode.models import Note from fedcode.models import Package +from fedcode.models import Repository +from fedcode.models import Service from fedcode.models import Vulnerability -from .test_models import mute_post_save_signal -from .test_models import repo -from .test_models import service + +@pytest.fixture +def service(db): + user = User.objects.create( + username="vcio", + email="vcio@nexb.com", + password="complex-password", + ) + return Service.objects.create( + user=user, + ) + + +@pytest.fixture +def repo(db, service, mute_post_save_signal): + """Simple Git Repository""" + return Repository.objects.create( + url="https://github.com/nexB/fake-repo", + path="./review/tests/test_data/test_git_repo_v1", + admin=service, + ) @pytest.mark.skip(reason="Need a real git repo to test the importer") diff --git a/tests/test_models.py b/tests/test_models.py index 72182a9..d533c92 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -9,7 +9,7 @@ import pytest from django.contrib.auth.models import User -from django.db.models.signals import post_save +from fedcode_test_utils import mute_post_save_signal # NOQA from fedcode.models import Follow from fedcode.models import Note @@ -23,51 +23,9 @@ from fedcode.models import Vulnerability -@pytest.fixture -def service(db): - user = User.objects.create( - username="vcio", - email="vcio@nexb.com", - password="complex-password", - ) - return Service.objects.create( - user=user, - ) - - -@pytest.fixture -def fake_service(db): - user = User.objects.create( - username="fake_service", - email="vcio@nexb.com", - password="complex-password", - ) - return Service.objects.create( - user=user, - ) - - -@pytest.fixture -def package(db, service): - return Package.objects.create( - purl="pkg:maven/org.apache.logging", - service=service, - ) - - -@pytest.fixture -def remote_purl(db): - remote_user1 = RemoteActor.objects.create(url="127.0.0.1", username="remote-ziad") - return Package.objects.create(remote_user=remote_user1, string="pkg:maven/org.apache.logging") - - @pytest.fixture def person(db): - user1 = User.objects.create( - username="ziad", - email="ziad@nexb.com", - password="complex-password", - ) + user1 = User.objects.create(username="ziad", email="ziad@nexb.com", password="complex-password") return Person.objects.create(user=user1, summary="Hello World", public_key="PUBLIC_KEY") @@ -89,12 +47,41 @@ def test_remote_person(remote_person): assert remote_person.remote_actor.username == "remote-ziad" +@pytest.fixture +def package(db, service): + return Package.objects.create(purl="pkg:maven/org.apache.logging", service=service) + + +@pytest.fixture +def service(db): + user = User.objects.create(username="vcio", email="vcio@nexb.com", password="complex-password") + return Service.objects.create(user=user) + + def test_purl(package, service): assert package.service == service assert package.purl == "pkg:maven/org.apache.logging" assert Package.objects.count() == 1 +@pytest.fixture +def note(db): + return Note.objects.create( + acct="ziad@127.0.0.1:8000", + content="Comment #1", + ) + + +@pytest.fixture +def follow(db, package, person): + return Follow.objects.create(package=package, person=person) + + +def test_follow(follow, package, person): + assert follow.package.purl == package.purl + assert follow.person.user == person.user + + @pytest.fixture def repo(db, service, mute_post_save_signal): """Simple Git Repository""" @@ -105,14 +92,6 @@ def repo(db, service, mute_post_save_signal): ) -@pytest.fixture -def vulnerability(db, repo): - return Vulnerability.objects.create( - id="VCID-1155-4sem-aaaq", - repo=repo, - ) - - @pytest.fixture def review(db, repo, person): return Review.objects.create( @@ -125,27 +104,14 @@ def review(db, repo, person): ) -@pytest.fixture -def note(db): - return Note.objects.create( - acct="ziad@127.0.0.1:8000", - content="Comment #1", - ) - - -@pytest.fixture -def pkg_note(db, package): - return Note.objects.create( - acct=package.acct, - content="purl: " - "pkg:maven/org.apache.logging@2.23-r0?arch=aarch64&distroversion=edge&reponame=community\n" - " affected_by_vulnerabilities: ....", - ) - - -@pytest.fixture -def follow(db, package, person): - return Follow.objects.create(package=package, person=person) +def test_review(review, person, repo): + assert review.headline == "Review title 1" + assert review.author == person + assert review.repository == repo + assert review.filepath == "/apache/httpd/VCID-1a68-fd5t-aaam.yml" + assert review.data == "text diff" + assert review.status == 0 + assert review.commit == "49d8c5fd4bea9488186a832b13ebdc83484f1b6a" @pytest.fixture @@ -157,35 +123,20 @@ def rep(db, note): ) -def test_follow(follow, package, person): - assert follow.package.purl == package.purl - assert follow.person.user == person.user - - -def test_review(review, person, repo): - assert review.headline == "Review title 1" - assert review.author == person - assert review.repository == repo - assert review.filepath == "/apache/httpd/VCID-1a68-fd5t-aaam.yml" - assert review.data == "text diff" - assert review.status == 0 - assert review.commit == "49d8c5fd4bea9488186a832b13ebdc83484f1b6a" - - def test_reputation(rep, note): assert rep.voter == "ziad@vcio" assert rep.positive is True assert rep.content_object == note +@pytest.fixture +def vulnerability(db, repo): + return Vulnerability.objects.create( + id="VCID-1155-4sem-aaaq", + repo=repo, + ) + + def test_vulnerability(vulnerability, repo): assert vulnerability.id == "VCID-1155-4sem-aaaq" assert vulnerability.repo == repo - - -@pytest.fixture(autouse=True) -def mute_post_save_signal(request): - """ - copied from https://www.cameronmaske.com/muting-django-signals-with-a-pytest-fixture/ - """ - post_save.receivers = [] diff --git a/tests/test_utils.py b/tests/test_utils.py index fadc07f..bb9371b 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -7,7 +7,6 @@ # See https://aboutcode.org for more information about AboutCode.org OSS projects. # import json -import uuid import pytest diff --git a/tests/test_vocabulary_toap.py b/tests/test_vocabulary_toap.py index b62d179..c364253 100644 --- a/tests/test_vocabulary_toap.py +++ b/tests/test_vocabulary_toap.py @@ -1,14 +1,45 @@ import pytest +from django.contrib.auth.models import User +from fedcode_test_utils import mute_post_save_signal # NOQA -from .test_models import mute_post_save_signal -from .test_models import note -from .test_models import package -from .test_models import person -from .test_models import rep -from .test_models import repo -from .test_models import review -from .test_models import service -from .test_models import vulnerability +from fedcode.models import Note +from fedcode.models import Package +from fedcode.models import Person +from fedcode.models import Repository +from fedcode.models import Reputation +from fedcode.models import Review +from fedcode.models import Service +from fedcode.models import Vulnerability + + +@pytest.fixture +def service(db): + user = User.objects.create( + username="vcio", + email="vcio@nexb.com", + password="complex-password", + ) + return Service.objects.create( + user=user, + ) + + +@pytest.fixture +def package(db, service): + return Package.objects.create( + purl="pkg:maven/org.apache.logging", + service=service, + ) + + +@pytest.fixture +def person(db): + user1 = User.objects.create( + username="ziad", + email="ziad@nexb.com", + password="complex-password", + ) + return Person.objects.create(user=user1, summary="Hello World", public_key="PUBLIC_KEY") @pytest.mark.django_db @@ -48,6 +79,53 @@ def test_actors_to_ap(person, package, service): } +@pytest.fixture +def repo(db, service, mute_post_save_signal): + """Simple Git Repository""" + return Repository.objects.create( + url="https://github.com/nexB/fake-repo", + path="./review/tests/test_data/test_git_repo_v1", + admin=service, + ) + + +@pytest.fixture +def vulnerability(db, repo): + return Vulnerability.objects.create( + id="VCID-1155-4sem-aaaq", + repo=repo, + ) + + +@pytest.fixture +def review(db, repo, person): + return Review.objects.create( + headline="Review title 1", + author=person, + repository=repo, + filepath="/apache/httpd/VCID-1a68-fd5t-aaam.yml", + data="text diff", + commit="49d8c5fd4bea9488186a832b13ebdc83484f1b6a", + ) + + +@pytest.fixture +def note(db): + return Note.objects.create( + acct="ziad@127.0.0.1:8000", + content="Comment #1", + ) + + +@pytest.fixture +def rep(db, note): + return Reputation.objects.create( + voter="ziad@vcio", + positive=True, + content_object=note, + ) + + @pytest.mark.django_db def test_objects_to_ap(repo, review, vulnerability, note, rep, mute_post_save_signal): assert repo.to_ap == { diff --git a/tests/test_webfinger.py b/tests/test_webfinger.py index 37ec790..913f289 100644 --- a/tests/test_webfinger.py +++ b/tests/test_webfinger.py @@ -9,33 +9,48 @@ import json import pytest +from django.contrib.auth.models import User from django.test import Client +from fedcode.models import Package +from fedcode.models import Person +from fedcode.models import Service from fedcode.utils import generate_webfinger from federatedcode.settings import FEDERATEDCODE_DOMAIN -from .test_models import package -from .test_models import person -from .test_models import service + +@pytest.fixture +def service(db): + user = User.objects.create(username="vcio", email="vcio@nexb.com", password="complex-password") + return Service.objects.create(user=user) + + +@pytest.fixture +def package(db, service): + return Package.objects.create(purl="pkg:maven/org.apache.logging", service=service) + + +@pytest.fixture +def person(db): + user1 = User.objects.create( + username="ziad", + email="ziad@nexb.com", + password="complex-password", + ) + return Person.objects.create(user=user1, summary="Hello World", public_key="PUBLIC_KEY") @pytest.mark.django_db def test_webfinger(person, service, package): client = Client() person_acct = "acct:" + generate_webfinger(person.user.username) - response_person = client.get( - f"/.well-known/webfinger?resource={person_acct}", - ) + response_person = client.get(f"/.well-known/webfinger?resource={person_acct}") service_acct = "acct:" + generate_webfinger(service.user.username) - response_service = client.get( - f"/.well-known/webfinger?resource={service_acct}", - ) + response_service = client.get(f"/.well-known/webfinger?resource={service_acct}") package_acct = "acct:" + generate_webfinger(package.purl) - response_purl = client.get( - f"/.well-known/webfinger?resource={package_acct}", - ) + response_purl = client.get(f"/.well-known/webfinger?resource={package_acct}") assert json.loads(response_person.content) == { "subject": person_acct,