From 4f3eecd7984439dc2b07aec32d32fae48d338bfb Mon Sep 17 00:00:00 2001 From: Florian Knappers <73856313+JJFlorian@users.noreply.github.com> Date: Wed, 10 Apr 2024 09:06:53 +0200 Subject: [PATCH 1/3] started views tests --- api/tests/test_views.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 api/tests/test_views.py diff --git a/api/tests/test_views.py b/api/tests/test_views.py new file mode 100644 index 0000000..442a6ec --- /dev/null +++ b/api/tests/test_views.py @@ -0,0 +1,15 @@ +from rest_framework import status +from rest_framework.test import APIClient +import pytest + +@pytest.fixture +def api_client(): + return APIClient() + +def test_host_redirect_view(api_client): + """Test the localhost-redirect endpoint""" + url = "/api/localhost-redirect" + + r = api_client.get(url) + + assert r.status_code == status.HTTP_302_FOUND \ No newline at end of file From 6cecad960e6327fbc0e9ff5f190315477acde205 Mon Sep 17 00:00:00 2001 From: Florian Knappers <73856313+JJFlorian@users.noreply.github.com> Date: Wed, 10 Apr 2024 11:34:22 +0200 Subject: [PATCH 2/3] tested views --- api/tests/fixtures.py | 20 ++- api/tests/test_views.py | 282 +++++++++++++++++++++++++++++++++++++++- api/urls.py | 2 +- 3 files changed, 301 insertions(+), 3 deletions(-) diff --git a/api/tests/fixtures.py b/api/tests/fixtures.py index a378e79..c63efb3 100644 --- a/api/tests/fixtures.py +++ b/api/tests/fixtures.py @@ -1,5 +1,8 @@ import pytest +from django.contrib.auth.models import User + + from api import models as api_models from gmn import models as gmn_models from gmw import models as gmw_models @@ -13,9 +16,24 @@ def organisation(): bro_user_token="secret", bro_user_password="secret", ) - organisation.save() return organisation +@pytest.fixture +def user(): + user = User.objects.create_user( + username='test_user', + email='test@example.com', + password='test_password' + ) + return user + +@pytest.fixture +def userprofile(user, organisation): + userprofile = api_models.UserProfile.objects.create( + user=user, + organisation=organisation, + ) + return userprofile @pytest.fixture def gmn(organisation): diff --git a/api/tests/test_views.py b/api/tests/test_views.py index 442a6ec..7333a69 100644 --- a/api/tests/test_views.py +++ b/api/tests/test_views.py @@ -1,15 +1,295 @@ from rest_framework import status +from django.urls import reverse from rest_framework.test import APIClient import pytest +from api.tests import fixtures +from api import models as api_models +from unittest.mock import patch + +user = fixtures.user +organisation = fixtures.organisation # imported, even though not used in this file, because required for userprofile fixture +userprofile = fixtures.userprofile + @pytest.fixture def api_client(): return APIClient() + def test_host_redirect_view(api_client): """Test the localhost-redirect endpoint""" url = "/api/localhost-redirect" r = api_client.get(url) - assert r.status_code == status.HTTP_302_FOUND \ No newline at end of file + assert r.status_code == status.HTTP_302_FOUND + +@pytest.mark.django_db +def test_user_view_set_list(api_client, user): + """Test the UserViewSet listview""" + + api_client.force_authenticate(user=user) + url = reverse("api:user-list") + response = api_client.get(url) + + assert response.status_code == status.HTTP_200_OK + +@pytest.mark.django_db +def test_user_view_set_logged_in(api_client, user, userprofile): + """Test the logged_in action of UserViewSet with a logged in user""" + + api_client.force_authenticate(user=user) + + url = reverse("api:user-logged-in") + response = api_client.get(url) + + assert response.status_code == status.HTTP_200_OK + + expected_data = { + "logged_in": True, + "login_url": None, + "logout_url": "http://testserver/api-auth/logout/", + "user_id": user.pk, + "username": user.username, + "first_name": user.first_name, + "last_name": user.last_name, + "email": user.email, + "organisation": userprofile.organisation.name, + "kvk": userprofile.organisation.kvk_number, + } + assert response.data == expected_data + +@pytest.mark.django_db +def test_user_view_set_not_logged_in(api_client): + """Test the logged_in action of UserViewSet with no logged in user""" + url = reverse("api:user-logged-in") + response = api_client.get(url) + + assert response.status_code == status.HTTP_200_OK + + expected_data = { + "logged_in": False, + "login_url": "http://testserver/api-auth/login/", + "logout_url": None, + "user_id": None, + "username": None, + "first_name": None, + "last_name": None, + "email": None, + "organisation": None, + "kvk": None, + } + assert response.data == expected_data + +@pytest.mark.django_db +def test_importtask_view_set_list_not_logged_in(api_client): + """Test the importtask list endpoint""" + url = "/api/importtasks/" + response = api_client.get(url) + + assert response.status_code == status.HTTP_403_FORBIDDEN + +@pytest.mark.django_db +def test_importtask_view_set_list_logged_in(api_client, user, userprofile): + """Test the importtask list endpoint + Note: userprofile needs to be used as fixture for this test + """ + api_client.force_authenticate(user=user) + url = "/api/importtasks/" + response = api_client.get(url) + + assert response.status_code == status.HTTP_200_OK + +@pytest.mark.django_db +def test_importtask_view_post_valid_data(api_client, user, userprofile, organisation): + """Test posting on the importtask enpoint + Note: userprofile needs to be used as fixture for this test + """ + api_client.force_authenticate(user=user) + url = "/api/importtasks/" + + data = { + "bro_domain": "GMN", + "kvk_number": organisation.kvk_number, + "data_owner": organisation.uuid + } + + response = api_client.post(url, data, format='json') + + assert response.status_code == status.HTTP_201_CREATED + +@pytest.mark.django_db +def test_importtask_view_post_invalid_data(api_client, user, userprofile, organisation): + """Test posting on the importtask enpoint + Note: userprofile needs to be used as fixture for this test + """ + api_client.force_authenticate(user=user) + url = "/api/importtasks/" + + data = { + "bro_domain": "non-existing", + "kvk_number": organisation.kvk_number, + "data_owner": organisation.uuid + } + + response = api_client.post(url, data, format='json') + + assert response.status_code == status.HTTP_400_BAD_REQUEST + + +@pytest.mark.django_db +def test_uploadtask_view_set_list_not_logged_in(api_client): + """Test the uploadtask list endpoint""" + url = "/api/uploadtasks/" + response = api_client.get(url) + + assert response.status_code == status.HTTP_403_FORBIDDEN + +@pytest.mark.django_db +def test_uploadtask_view_set_list_logged_in(api_client, user, userprofile): + """Test the uploadtask list endpoint + Note: userprofile needs to be used as fixture for this test + """ + api_client.force_authenticate(user=user) + url = "/api/uploadtasks/" + response = api_client.get(url) + + assert response.status_code == status.HTTP_200_OK + +@pytest.mark.django_db +def test_uploadtask_view_post_valid_data(api_client, user, userprofile, organisation): + """Test posting on the uploadtask enpoint + Note: userprofile needs to be used as fixture for this test + """ + api_client.force_authenticate(user=user) + url = "/api/uploadtasks/" + + data = { + "bro_domain": "GMN", + "project_number": "1", + "registration_type": "GMN_StartRegistration", + "request_type": "registration", + "metadata": {}, + "sourcedocument_data": {}, + "data_owner": organisation.uuid + } + + response = api_client.post(url, data, format='json') + + assert response.status_code == status.HTTP_201_CREATED + +@pytest.mark.django_db +def test_uploadtask_view_post_invalid_data(api_client, user, userprofile, organisation): + """Test posting on the uploadtasks enpoint + Note: userprofile needs to be used as fixture for this test + """ + api_client.force_authenticate(user=user) + url = "/api/uploadtasks/" + + data = { + "bro_domain": "non-existing", + "project_number": "1", + "registration_type": "GMN_StartRegistration", + "request_type": "non-existing", + "metadata": {}, + "sourcedocument_data": {}, + "data_owner": organisation.uuid + } + + response = api_client.post(url, data, format='json') + + assert response.status_code == status.HTTP_400_BAD_REQUEST + +@pytest.mark.django_db +@patch('api.bro_upload.utils.check_delivery_status') +def test_uploadtask_check_status(mock_check_delivery_status, api_client, user, userprofile, organisation): + """Test post on uploadtasks/check-status endpoint + Note: userprofile needs to be used as fixture for this test + """ + api_client.force_authenticate(user=user) + + upload_task_instance = api_models.UploadTask.objects.create( + bro_domain = "GMN", + project_number = "1", + registration_type = "GMN_StartRegistration", + request_type = "registration", + metadata = {}, + sourcedocument_data = {}, + data_owner = organisation, + status="PENDING" + ) + + url = reverse("api:uploadtask-check-status", kwargs={'uuid': upload_task_instance.uuid}) + + # Check 201 response for status = PENDING + response = api_client.post(url) + assert response.status_code == status.HTTP_201_CREATED + + # Check 303 response for status = PROCESSING + upload_task_instance.status = "PROCESSING" + upload_task_instance.save() + + response = api_client.post(url) + assert response.status_code == status.HTTP_303_SEE_OTHER + + # Check 303 response for status = COMPLETED + upload_task_instance.status = "COMPLETED" + upload_task_instance.save() + + response = api_client.post(url) + assert response.status_code == status.HTTP_303_SEE_OTHER + + # Check 303 response for status = FAILED + upload_task_instance.status = "FAILED" + upload_task_instance.save() + + response = api_client.post(url) + assert response.status_code == status.HTTP_303_SEE_OTHER + + # Check 303 response for status = UNFINISHED -> FAILED + upload_task_instance.status = "UNFINISHED" + upload_task_instance.save() + + mock_check_delivery_status.return_value = { + "brondocuments": [ + { + "errors": ["ERROR!!!"], + "status": "OPGENOMEN_LVBRO", + "broId":"GMN1234", + } + ], + "status": "DOORGELEVERD" + } + + response = api_client.post(url) + assert response.status_code == status.HTTP_303_SEE_OTHER + + # Check 200 response for status = UNFINISHED -> FINISHED + mock_check_delivery_status.return_value = { + "brondocuments": [ + { + "errors": [], + "status": "OPGENOMEN_LVBRO", + "broId":"GMN1234", + } + ], + "status": "DOORGELEVERD" + } + + response = api_client.post(url) + assert response.status_code == status.HTTP_200_OK + + # Check 200 response for status = UNFINISHED -> UNFINISHED + mock_check_delivery_status.return_value = { + "brondocuments": [ + { + "errors": [], + "status": "NOTFINISHEDYET", + "broId":"GMN1234", + } + ], + "status": "DOORGELEVERD" + } + + response = api_client.post(url) + assert response.status_code == status.HTTP_304_NOT_MODIFIED \ No newline at end of file diff --git a/api/urls.py b/api/urls.py index 305b993..6b84f14 100644 --- a/api/urls.py +++ b/api/urls.py @@ -8,7 +8,7 @@ router = routers.DefaultRouter() router.register(r"users", views.UserViewSet, basename="user") router.register(r"uploadtasks", views.UploadTaskViewSet, basename="uploadtask") -router.register(r"ImportTaskViewSet", views.ImportTaskViewSet, basename="importtask") +router.register(r"importtasks", views.ImportTaskViewSet, basename="importtask") urlpatterns = [ From d737beace7824ba659e0318e119bc92e8797dd72 Mon Sep 17 00:00:00 2001 From: Florian Knappers <73856313+JJFlorian@users.noreply.github.com> Date: Wed, 10 Apr 2024 11:35:24 +0200 Subject: [PATCH 3/3] precommit --- api/tests/fixtures.py | 9 ++--- api/tests/test_views.py | 85 ++++++++++++++++++++++++----------------- 2 files changed, 55 insertions(+), 39 deletions(-) diff --git a/api/tests/fixtures.py b/api/tests/fixtures.py index c63efb3..42814d4 100644 --- a/api/tests/fixtures.py +++ b/api/tests/fixtures.py @@ -1,8 +1,6 @@ import pytest - from django.contrib.auth.models import User - from api import models as api_models from gmn import models as gmn_models from gmw import models as gmw_models @@ -18,15 +16,15 @@ def organisation(): ) return organisation + @pytest.fixture def user(): user = User.objects.create_user( - username='test_user', - email='test@example.com', - password='test_password' + username="test_user", email="test@example.com", password="test_password" ) return user + @pytest.fixture def userprofile(user, organisation): userprofile = api_models.UserProfile.objects.create( @@ -35,6 +33,7 @@ def userprofile(user, organisation): ) return userprofile + @pytest.fixture def gmn(organisation): return gmn_models.GMN( diff --git a/api/tests/test_views.py b/api/tests/test_views.py index 7333a69..12355f7 100644 --- a/api/tests/test_views.py +++ b/api/tests/test_views.py @@ -1,13 +1,15 @@ -from rest_framework import status +from unittest.mock import patch + +import pytest from django.urls import reverse +from rest_framework import status from rest_framework.test import APIClient -import pytest -from api.tests import fixtures + from api import models as api_models -from unittest.mock import patch +from api.tests import fixtures user = fixtures.user -organisation = fixtures.organisation # imported, even though not used in this file, because required for userprofile fixture +organisation = fixtures.organisation # imported, even though not used in this file, because required for userprofile fixture userprofile = fixtures.userprofile @@ -24,6 +26,7 @@ def test_host_redirect_view(api_client): assert r.status_code == status.HTTP_302_FOUND + @pytest.mark.django_db def test_user_view_set_list(api_client, user): """Test the UserViewSet listview""" @@ -34,6 +37,7 @@ def test_user_view_set_list(api_client, user): assert response.status_code == status.HTTP_200_OK + @pytest.mark.django_db def test_user_view_set_logged_in(api_client, user, userprofile): """Test the logged_in action of UserViewSet with a logged in user""" @@ -59,6 +63,7 @@ def test_user_view_set_logged_in(api_client, user, userprofile): } assert response.data == expected_data + @pytest.mark.django_db def test_user_view_set_not_logged_in(api_client): """Test the logged_in action of UserViewSet with no logged in user""" @@ -81,6 +86,7 @@ def test_user_view_set_not_logged_in(api_client): } assert response.data == expected_data + @pytest.mark.django_db def test_importtask_view_set_list_not_logged_in(api_client): """Test the importtask list endpoint""" @@ -89,6 +95,7 @@ def test_importtask_view_set_list_not_logged_in(api_client): assert response.status_code == status.HTTP_403_FORBIDDEN + @pytest.mark.django_db def test_importtask_view_set_list_logged_in(api_client, user, userprofile): """Test the importtask list endpoint @@ -100,6 +107,7 @@ def test_importtask_view_set_list_logged_in(api_client, user, userprofile): assert response.status_code == status.HTTP_200_OK + @pytest.mark.django_db def test_importtask_view_post_valid_data(api_client, user, userprofile, organisation): """Test posting on the importtask enpoint @@ -111,13 +119,14 @@ def test_importtask_view_post_valid_data(api_client, user, userprofile, organisa data = { "bro_domain": "GMN", "kvk_number": organisation.kvk_number, - "data_owner": organisation.uuid + "data_owner": organisation.uuid, } - response = api_client.post(url, data, format='json') + response = api_client.post(url, data, format="json") assert response.status_code == status.HTTP_201_CREATED + @pytest.mark.django_db def test_importtask_view_post_invalid_data(api_client, user, userprofile, organisation): """Test posting on the importtask enpoint @@ -129,10 +138,10 @@ def test_importtask_view_post_invalid_data(api_client, user, userprofile, organi data = { "bro_domain": "non-existing", "kvk_number": organisation.kvk_number, - "data_owner": organisation.uuid + "data_owner": organisation.uuid, } - response = api_client.post(url, data, format='json') + response = api_client.post(url, data, format="json") assert response.status_code == status.HTTP_400_BAD_REQUEST @@ -145,6 +154,7 @@ def test_uploadtask_view_set_list_not_logged_in(api_client): assert response.status_code == status.HTTP_403_FORBIDDEN + @pytest.mark.django_db def test_uploadtask_view_set_list_logged_in(api_client, user, userprofile): """Test the uploadtask list endpoint @@ -156,6 +166,7 @@ def test_uploadtask_view_set_list_logged_in(api_client, user, userprofile): assert response.status_code == status.HTTP_200_OK + @pytest.mark.django_db def test_uploadtask_view_post_valid_data(api_client, user, userprofile, organisation): """Test posting on the uploadtask enpoint @@ -171,13 +182,14 @@ def test_uploadtask_view_post_valid_data(api_client, user, userprofile, organisa "request_type": "registration", "metadata": {}, "sourcedocument_data": {}, - "data_owner": organisation.uuid + "data_owner": organisation.uuid, } - response = api_client.post(url, data, format='json') + response = api_client.post(url, data, format="json") assert response.status_code == status.HTTP_201_CREATED + @pytest.mark.django_db def test_uploadtask_view_post_invalid_data(api_client, user, userprofile, organisation): """Test posting on the uploadtasks enpoint @@ -193,33 +205,38 @@ def test_uploadtask_view_post_invalid_data(api_client, user, userprofile, organi "request_type": "non-existing", "metadata": {}, "sourcedocument_data": {}, - "data_owner": organisation.uuid + "data_owner": organisation.uuid, } - response = api_client.post(url, data, format='json') + response = api_client.post(url, data, format="json") assert response.status_code == status.HTTP_400_BAD_REQUEST + @pytest.mark.django_db -@patch('api.bro_upload.utils.check_delivery_status') -def test_uploadtask_check_status(mock_check_delivery_status, api_client, user, userprofile, organisation): +@patch("api.bro_upload.utils.check_delivery_status") +def test_uploadtask_check_status( + mock_check_delivery_status, api_client, user, userprofile, organisation +): """Test post on uploadtasks/check-status endpoint Note: userprofile needs to be used as fixture for this test """ api_client.force_authenticate(user=user) upload_task_instance = api_models.UploadTask.objects.create( - bro_domain = "GMN", - project_number = "1", - registration_type = "GMN_StartRegistration", - request_type = "registration", - metadata = {}, - sourcedocument_data = {}, - data_owner = organisation, - status="PENDING" + bro_domain="GMN", + project_number="1", + registration_type="GMN_StartRegistration", + request_type="registration", + metadata={}, + sourcedocument_data={}, + data_owner=organisation, + status="PENDING", ) - url = reverse("api:uploadtask-check-status", kwargs={'uuid': upload_task_instance.uuid}) + url = reverse( + "api:uploadtask-check-status", kwargs={"uuid": upload_task_instance.uuid} + ) # Check 201 response for status = PENDING response = api_client.post(url) @@ -253,12 +270,12 @@ def test_uploadtask_check_status(mock_check_delivery_status, api_client, user, u mock_check_delivery_status.return_value = { "brondocuments": [ { - "errors": ["ERROR!!!"], + "errors": ["ERROR!!!"], "status": "OPGENOMEN_LVBRO", - "broId":"GMN1234", + "broId": "GMN1234", } ], - "status": "DOORGELEVERD" + "status": "DOORGELEVERD", } response = api_client.post(url) @@ -268,12 +285,12 @@ def test_uploadtask_check_status(mock_check_delivery_status, api_client, user, u mock_check_delivery_status.return_value = { "brondocuments": [ { - "errors": [], + "errors": [], "status": "OPGENOMEN_LVBRO", - "broId":"GMN1234", + "broId": "GMN1234", } ], - "status": "DOORGELEVERD" + "status": "DOORGELEVERD", } response = api_client.post(url) @@ -283,13 +300,13 @@ def test_uploadtask_check_status(mock_check_delivery_status, api_client, user, u mock_check_delivery_status.return_value = { "brondocuments": [ { - "errors": [], + "errors": [], "status": "NOTFINISHEDYET", - "broId":"GMN1234", + "broId": "GMN1234", } ], - "status": "DOORGELEVERD" + "status": "DOORGELEVERD", } response = api_client.post(url) - assert response.status_code == status.HTTP_304_NOT_MODIFIED \ No newline at end of file + assert response.status_code == status.HTTP_304_NOT_MODIFIED