From 130203073c56e3e730d08a0eb4e66824147cdb7c Mon Sep 17 00:00:00 2001 From: PascalEgn Date: Wed, 26 Jul 2023 10:26:31 +0200 Subject: [PATCH] tests: refactor tests --- .github/workflows/backend-tests.yml | 15 ---- config/settings/base.py | 5 +- config/settings/test.py | 11 ++- pyproject.toml | 4 + scoap3/articles/documents.py | 4 +- scoap3/articles/tests.py | 3 - .../articles/tests/test_article_indexing.py | 77 ++++--------------- scoap3/articles/tests/test_article_views.py | 16 ++-- scoap3/articles/tests/test_search.py | 24 ++---- scoap3/authors/tests/test_author_views.py | 16 ++-- scoap3/conftest.py | 15 ++++ scoap3/misc/tests/__init__.py | 0 scoap3/misc/tests/factories.py | 13 ++++ scoap3/misc/tests/test_misc_views.py | 72 ++++++++--------- 14 files changed, 110 insertions(+), 165 deletions(-) delete mode 100644 scoap3/articles/tests.py create mode 100644 scoap3/misc/tests/__init__.py create mode 100644 scoap3/misc/tests/factories.py diff --git a/.github/workflows/backend-tests.yml b/.github/workflows/backend-tests.yml index f8465c883..e947ba5fb 100644 --- a/.github/workflows/backend-tests.yml +++ b/.github/workflows/backend-tests.yml @@ -56,21 +56,6 @@ jobs: uses: actions/checkout@v4 with: ref: ${{ inputs.ref }} - - name: Create index - run: > - docker run - --pull always - --network=host - --entrypoint poetry - --env DJANGO_SETTINGS_MODULE=config.settings.test - --env DISABLE_SECURITY_PLUGIN=true - --env POSTGRES_DB=scoap3 - --env POSTGRES_USER=scoap3 - --env POSTGRES_PASSWORD=scoap3 - --env POSTGRES_HOST=127.0.0.1 - --env OPENSEARCH_HOST=127.0.0.1:9200 - ${{ inputs.image }} - run python manage.py opensearch index --force create - name: Test run: > docker run diff --git a/config/settings/base.py b/config/settings/base.py index 47d8b2b6d..7e8dfe7b0 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -376,7 +376,10 @@ # Opensearch # ------------------------------------------------------------------------------ -OPENSEARCH_INDEX_PREFIX = env("OPENSEARCH_INDEX_PREFIX") +# Name of the Opensearch index +OPENSEARCH_INDEX_NAMES = { + "scoap3.articles.documents": f'{env("OPENSEARCH_INDEX_PREFIX")}-articles', +} OPENSEARCH_DSL = { "default": {"hosts": env("OPENSEARCH_HOST")}, diff --git a/config/settings/test.py b/config/settings/test.py index cddb48982..932ba16d1 100644 --- a/config/settings/test.py +++ b/config/settings/test.py @@ -12,6 +12,9 @@ "DJANGO_SECRET_KEY", default="wpQt7H4zQGseXwknqw5RFWSpBXxKwr3FqavY6iEzFMmRLlUJWJ8U3eftfJlh88Ie", ) +ALLOWED_HOSTS = ["127.0.0.1"] + + # https://docs.djangoproject.com/en/dev/ref/settings/#test-runner TEST_RUNNER = "django.test.runner.DiscoverRunner" @@ -36,9 +39,13 @@ # Opensearch # ------------------------------------------------------------------------------ -# OPENSEARCH_HOST overrides for the default OpenSearch host and port -ALLOWED_HOSTS = ["127.0.0.1"] +# Name of the Opensearch index +OPENSEARCH_INDEX_NAMES = { + "scoap3.articles.documents": "scoap3-backend-test-articles", +} +# Force an index refresh with every save. OPENSEARCH_DSL_AUTO_REFRESH = True + OPENSEARCH_DSL = { "default": { "hosts": [env("OPENSEARCH_HOST")], diff --git a/pyproject.toml b/pyproject.toml index b7f52325d..fcee75b15 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,3 +79,7 @@ build-backend = "poetry.core.masonry.api" [tool.pytest.ini_options] addopts = ["--ds=config.settings.test", "--reuse-db"] python_files = ["test_*.py", "*_test.py"] +filterwarnings = [ + "ignore::DeprecationWarning", + "ignore::UserWarning" + ] diff --git a/scoap3/articles/documents.py b/scoap3/articles/documents.py index 094f49bf9..83e5dafe4 100644 --- a/scoap3/articles/documents.py +++ b/scoap3/articles/documents.py @@ -114,8 +114,8 @@ def prepare_publication_info(self, instance): return serialized_publication_infos class Index: - name = f"{settings.OPENSEARCH_INDEX_PREFIX}-articles" - settings = {"number_of_shards": 1, "number_of_replicas": 0} + name = settings.OPENSEARCH_INDEX_NAMES[__name__] + settings = {"number_of_shards": 1, "number_of_replicas": 1} class Django: model = Article diff --git a/scoap3/articles/tests.py b/scoap3/articles/tests.py deleted file mode 100644 index a79ca8be5..000000000 --- a/scoap3/articles/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -# from django.test import TestCase - -# Create your tests here. diff --git a/scoap3/articles/tests/test_article_indexing.py b/scoap3/articles/tests/test_article_indexing.py index f6ebed3ca..f62d3db41 100644 --- a/scoap3/articles/tests/test_article_indexing.py +++ b/scoap3/articles/tests/test_article_indexing.py @@ -1,76 +1,27 @@ import json import pytest -from django.contrib.auth import get_user_model -from django.test.client import Client -from rest_framework.authtoken.models import Token +from django.urls import reverse -pytestmark = pytest.mark.django_db -User = get_user_model() - -@pytest.fixture -def admin_user_token(user): - client = Client() - password = "admin" - my_admin = User.objects.create_superuser("admin", "myemail@test.com", password) - client.login(username=my_admin.username, password="admin") - user_token = Token.objects.create(user=user) - return {"client": client, "user_token": user_token} - - -@pytest.fixture -def license_id(admin_user_token): - license = {"url": "https://creativecommons.org/about/cclicenses/", "name": "cc"} - response = admin_user_token["client"].post( - "/api/license/", - data=license, - content_type="application/json", - HTTP_AUTHORIZATION=f"Token {admin_user_token['user_token']}", - ) - return json.loads(response.content.decode("utf-8"))["id"] - - -def test_article_post_and_delete(admin_user_token, license_id): - response = admin_user_token["client"].get( - "/api/license/", - content_type="application/json", - HTTP_AUTHORIZATION=f"Token {admin_user_token['user_token']}", - ) +@pytest.mark.django_db +def test_article_post_and_delete(client, user, license): + client.force_login(user) article = { - "reception_date": "2023-07-11", - "acceptance_date": "2023-07-11", - "publication_date": "2023-07-11", - "first_online_date": "2023-07-11", "title": "string", - "subtitle": "string", - "abstract": "string", - "related_licenses": [license_id], - "related_materials": [], - "_files": [], + "related_licenses": [license.id], } - url = "http://localhost:8000/api/articles/" - response = admin_user_token["client"].post( - url, + response = client.post( + reverse("api:article-list"), data=article, - content_type="application/json", - HTTP_AUTHORIZATION=f"Token {admin_user_token['user_token']}", ) - article_id = json.loads(response.content.decode("utf-8"))["id"] assert response.status_code == 201 - opensearch_url = f"http://localhost:8000/search/article/{article_id}/" - response = admin_user_token["client"].get( - opensearch_url, - data=article, - content_type="application/json", - HTTP_AUTHORIZATION=f"Token {admin_user_token['user_token']}", - ) + + article_id = json.loads(response.content)["id"] + article_detail_url = reverse("api:article-detail", kwargs={"pk": article_id}) + + response = client.get(article_detail_url) assert response.status_code == 200 - url_delete_article = f"http://localhost:8000/api/articles/{article_id}/" - response = admin_user_token["client"].delete( - url_delete_article, - data=article, - content_type="application/json", - HTTP_AUTHORIZATION=f"Token {admin_user_token['user_token']}", - ) + + response = client.delete(article_detail_url) assert response.status_code == 204 diff --git a/scoap3/articles/tests/test_article_views.py b/scoap3/articles/tests/test_article_views.py index 69becdcd1..708633f98 100644 --- a/scoap3/articles/tests/test_article_views.py +++ b/scoap3/articles/tests/test_article_views.py @@ -1,29 +1,23 @@ import pytest from django.urls import reverse from rest_framework import status -from rest_framework.test import APIClient pytestmark = pytest.mark.django_db -@pytest.fixture -def api_client(): - return APIClient() - - class TestArticleViewSet: - def test_get_article(self, api_client): + def test_get_article(self, client): url = reverse("api:article-list") - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_200_OK class TestArticleIdentifierViewSet: - def test_get_article_identifier(self, api_client): + def test_get_article_identifier(self, client): url = reverse("api:articleidentifier-list") - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_200_OK url = reverse("api:articleidentifier-detail", kwargs={"pk": 0}) - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_404_NOT_FOUND diff --git a/scoap3/articles/tests/test_search.py b/scoap3/articles/tests/test_search.py index b5bb67100..7274f02da 100644 --- a/scoap3/articles/tests/test_search.py +++ b/scoap3/articles/tests/test_search.py @@ -1,23 +1,11 @@ import pytest +from django.urls import reverse from rest_framework import status -from rest_framework.authtoken.models import Token -from rest_framework.test import APIClient -pytestmark = pytest.mark.django_db - - -@pytest.fixture -def api_client(): - return APIClient() - - -def test_search_article(user, api_client): - user_token = Token.objects.create(user=user) - response = api_client.get( - "/search/article", - content_type="application/json", - HTTP_AUTHORIZATION=f"Token {user_token}", - follow=True, - ) +@pytest.mark.django_db +@pytest.mark.usefixtures("rebuild_opensearch_index") +def test_article_search(user, client): + client.force_login(user) + response = client.get(reverse("search:article-list")) assert response.status_code == status.HTTP_200_OK diff --git a/scoap3/authors/tests/test_author_views.py b/scoap3/authors/tests/test_author_views.py index c43fb5ac3..fc6d5ed44 100644 --- a/scoap3/authors/tests/test_author_views.py +++ b/scoap3/authors/tests/test_author_views.py @@ -1,29 +1,23 @@ import pytest from django.urls import reverse from rest_framework import status -from rest_framework.test import APIClient pytestmark = pytest.mark.django_db -@pytest.fixture -def api_client(): - return APIClient() - - class TestAuthorViewSet: - def test_get_article(self, api_client): + def test_get_article(self, client): url = reverse("api:author-list") - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_200_OK class TestAuthorIdentifierViewSet: - def test_get_article_identifier(self, api_client): + def test_get_article_identifier(self, client): url = reverse("api:authoridentifier-list") - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_200_OK url = reverse("api:authoridentifier-detail", kwargs={"pk": 0}) - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_404_NOT_FOUND diff --git a/scoap3/conftest.py b/scoap3/conftest.py index aa2018f58..b81b52e24 100644 --- a/scoap3/conftest.py +++ b/scoap3/conftest.py @@ -1,9 +1,19 @@ import pytest +from django.core.management import call_command +from scoap3.misc.models import License +from scoap3.misc.tests.factories import LicenseFactory from scoap3.users.models import User from scoap3.users.tests.factories import UserFactory +@pytest.fixture +def rebuild_opensearch_index(): + call_command("opensearch", "index", "rebuild", "--force") + yield + call_command("opensearch", "index", "delete", "--force") + + @pytest.fixture(autouse=True) def media_storage(settings, tmpdir): settings.MEDIA_ROOT = tmpdir.strpath @@ -12,3 +22,8 @@ def media_storage(settings, tmpdir): @pytest.fixture def user(db) -> User: return UserFactory() + + +@pytest.fixture +def license(db) -> License: + return LicenseFactory() diff --git a/scoap3/misc/tests/__init__.py b/scoap3/misc/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/scoap3/misc/tests/factories.py b/scoap3/misc/tests/factories.py new file mode 100644 index 000000000..199b0ca8c --- /dev/null +++ b/scoap3/misc/tests/factories.py @@ -0,0 +1,13 @@ +from factory import Faker +from factory.django import DjangoModelFactory + +from scoap3.misc.models import License + + +class LicenseFactory(DjangoModelFactory): + url = Faker("url") + name = Faker("domain_word") + + class Meta: + model = License + django_get_or_create = ["url"] diff --git a/scoap3/misc/tests/test_misc_views.py b/scoap3/misc/tests/test_misc_views.py index 710a62703..4d3f1e22c 100644 --- a/scoap3/misc/tests/test_misc_views.py +++ b/scoap3/misc/tests/test_misc_views.py @@ -1,132 +1,126 @@ import pytest from django.urls import reverse from rest_framework import status -from rest_framework.test import APIClient pytestmark = pytest.mark.django_db -@pytest.fixture -def api_client(): - return APIClient() - - class TestCountryViewSet: - def test_get_article(self, api_client): + def test_get_article(self, client): url = reverse("api:country-list") - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_200_OK url = reverse("api:country-detail", kwargs={"pk": 0}) - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_404_NOT_FOUND class TestAffiliationViewSet: - def test_get_article_identifier(self, api_client): + def test_get_article_identifier(self, client): url = reverse("api:affiliation-list") - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_200_OK url = reverse("api:affiliation-detail", kwargs={"pk": 0}) - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_404_NOT_FOUND class TestInstitutionIdentifierViewSet: - def test_get_article_identifier(self, api_client): + def test_get_article_identifier(self, client): url = reverse("api:institutionidentifier-list") - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_200_OK url = reverse("api:institutionidentifier-detail", kwargs={"pk": 0}) - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_404_NOT_FOUND class TestPublisherViewSet: - def test_get_article_identifier(self, api_client): + def test_get_article_identifier(self, client): url = reverse("api:publisher-list") - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_200_OK url = reverse("api:publisher-detail", kwargs={"pk": 0}) - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_404_NOT_FOUND class TestPublicationInfoViewSet: - def test_get_article_identifier(self, api_client): + def test_get_article_identifier(self, client): url = reverse("api:publicationinfo-list") - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_200_OK url = reverse("api:publicationinfo-detail", kwargs={"pk": 0}) - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_404_NOT_FOUND class TestLicenseViewSet: - def test_get_article_identifier(self, api_client): + def test_get_article_identifier(self, client): url = reverse("api:license-list") - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_200_OK url = reverse("api:license-detail", kwargs={"pk": 0}) - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_404_NOT_FOUND class TestCopyrightViewSet: - def test_get_article_identifier(self, api_client): + def test_get_article_identifier(self, client): url = reverse("api:copyright-list") - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_200_OK url = reverse("api:copyright-detail", kwargs={"pk": 0}) - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_404_NOT_FOUND class TestArticleArxivCategoryViewSet: - def test_get_article_identifier(self, api_client): + def test_get_article_identifier(self, client): url = reverse("api:articlearxivcategory-list") - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_200_OK url = reverse("api:articlearxivcategory-detail", kwargs={"pk": 0}) - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_404_NOT_FOUND class TestExperimentalCollaborationViewSet: - def test_get_article_identifier(self, api_client): + def test_get_article_identifier(self, client): url = reverse("api:experimentalcollaboration-list") - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_200_OK url = reverse("api:experimentalcollaboration-detail", kwargs={"pk": 0}) - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_404_NOT_FOUND class TestFunderViewSet: - def test_get_article_identifier(self, api_client): + def test_get_article_identifier(self, client): url = reverse("api:funder-list") - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_200_OK url = reverse("api:funder-detail", kwargs={"pk": 0}) - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_404_NOT_FOUND class TestRelatedMaterialViewSet: - def test_get_article_identifier(self, api_client): + def test_get_article_identifier(self, client): url = reverse("api:relatedmaterial-list") - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_200_OK url = reverse("api:relatedmaterial-detail", kwargs={"pk": 0}) - response = api_client.get(url) + response = client.get(url) assert response.status_code == status.HTTP_404_NOT_FOUND