diff --git a/kpi/tests/api/v2/test_api_submissions.py b/kpi/tests/api/v2/test_api_submissions.py index 39b2082886..d76bd4edbe 100644 --- a/kpi/tests/api/v2/test_api_submissions.py +++ b/kpi/tests/api/v2/test_api_submissions.py @@ -1077,6 +1077,10 @@ def setUp(self): self.submission_url = self.submission_url_legacy.replace( 'edit', 'enketo/edit' ) + self.submission_redirect_url = self.submission_url_legacy.replace( + 'edit', 'enketo/redirect/edit' + ) + assert 'redirect' in self.submission_redirect_url @responses.activate def test_get_legacy_edit_link_submission_as_owner(self): @@ -1127,6 +1131,31 @@ def test_get_edit_link_submission_as_owner(self): } self.assertEqual(response.data, expected_response) + @responses.activate + def test_get_edit_submission_redirect_as_owner(self): + """ + someuser is the owner of the project. + someuser can retrieve enketo edit link + """ + ee_url = ( + f'{settings.ENKETO_URL}/{settings.ENKETO_EDIT_INSTANCE_ENDPOINT}' + ) + # Mock Enketo response + responses.add_callback( + responses.POST, ee_url, + callback=enketo_edit_instance_response, + content_type='application/json', + ) + + response = self.client.get( + self.submission_redirect_url, {'format': 'json'} + ) + assert response.status_code == status.HTTP_302_FOUND + assert ( + response.url + == f"{settings.ENKETO_URL}/edit/{self.submission['_uuid']}" + ) + def test_get_edit_link_submission_as_anonymous(self): """ someuser is the owner of the project. @@ -1602,6 +1631,12 @@ def setUp(self): 'pk': self.submission['_id'], }, ) + self.submission_view_redirect_url = ( + self.submission_view_link_url.replace( + '/enketo/view/', '/enketo/redirect/view/' + ) + ) + assert 'redirect' in self.submission_view_redirect_url @responses.activate def test_get_view_link_submission_as_owner(self): @@ -1629,6 +1664,32 @@ def test_get_view_link_submission_as_owner(self): } assert response.data == expected_response + @responses.activate + def test_get_view_submission_redirect_as_owner(self): + """ + someuser is the owner of the project. + someuser can get enketo view link + """ + ee_url = ( + f'{settings.ENKETO_URL}/{settings.ENKETO_VIEW_INSTANCE_ENDPOINT}' + ) + + # Mock Enketo response + responses.add_callback( + responses.POST, ee_url, + callback=enketo_view_instance_response, + content_type='application/json', + ) + + response = self.client.get( + self.submission_view_redirect_url, {'format': 'json'} + ) + assert response.status_code == status.HTTP_302_FOUND + assert ( + response.url + == f"{settings.ENKETO_URL}/view/{self.submission['_uuid']}" + ) + def test_get_view_link_submission_as_anonymous(self): """ someuser is the owner of the project. diff --git a/kpi/views/v2/data.py b/kpi/views/v2/data.py index 7917815f9b..2f3fffe585 100644 --- a/kpi/views/v2/data.py +++ b/kpi/views/v2/data.py @@ -5,7 +5,7 @@ import requests from django.conf import settings -from django.http import Http404 +from django.http import Http404, HttpResponseRedirect from django.utils.translation import gettext_lazy as t from pymongo.errors import OperationFailure from rest_framework import ( @@ -188,6 +188,16 @@ class DataViewSet(AssetNestedObjectViewsetMixin, NestedViewSetMixin, > > curl -X GET https://[kpi]/api/v2/assets/aSAvYreNzVEkrWg5Gdcvg/data/234/enketo/edit/?return_url=false + To redirect (HTTP 302) to the Enketo editing URL, use the `…/enketo/redirect/edit/` endpoint: + +
+    GET /api/v2/assets/{uid}/data/{id}/enketo/redirect/edit/?return_url=false
+    
+ + > Example + > + > curl -X GET https://[kpi]/api/v2/assets/aSAvYreNzVEkrWg5Gdcvg/data/234/enketo/redirect/edit/?return_url=false + View-only version of current submission Return a URL to display the filled submission in view-only mode in the Enketo UI. @@ -200,6 +210,16 @@ class DataViewSet(AssetNestedObjectViewsetMixin, NestedViewSetMixin, > > curl -X GET https://[kpi]/api/v2/assets/aSAvYreNzVEkrWg5Gdcvg/data/234/enketo/view/ + To redirect (HTTP 302) to the Enketo viewing URL, use the `…/enketo/redirect/view/` endpoint: + +
+    GET /api/v2/assets/{uid}/data/{id}/enketo/redirect/view/?return_url=false
+    
+ + > Example + > + > curl -X GET https://[kpi]/api/v2/assets/aSAvYreNzVEkrWg5Gdcvg/data/234/enketo/redirect/view/?return_url=false + ### Duplicate submission Duplicates the data of a submission @@ -435,7 +455,7 @@ def duplicate(self, request, pk, *args, **kwargs): methods=['GET'], renderer_classes=[renderers.JSONRenderer], permission_classes=[EditLinkSubmissionPermission], - url_path='(enketo/)?edit', + url_path='((enketo/)|(enketo/redirect/))?edit', ) def enketo_edit(self, request, pk, *args, **kwargs): submission_id = positive_int(pk) @@ -447,18 +467,19 @@ def enketo_edit(self, request, pk, *args, **kwargs): EnketoSessionAuthentication.prepare_response_with_csrf_cookie( request, enketo_response ) - return enketo_response + return self._handle_enketo_redirect(request, enketo_response, *args, **kwargs) @action( detail=True, methods=['GET'], renderer_classes=[renderers.JSONRenderer], permission_classes=[ViewSubmissionPermission], - url_path='enketo/view', + url_path='enketo/(redirect/)?view', ) def enketo_view(self, request, pk, *args, **kwargs): submission_id = positive_int(pk) - return self._get_enketo_link(request, submission_id, 'view') + enketo_response = self._get_enketo_link(request, submission_id, 'view') + return self._handle_enketo_redirect(request, enketo_response, *args, **kwargs) def get_queryset(self): # This method is needed when pagination is activated and renderer is @@ -796,3 +817,13 @@ def _get_enketo_link( 'version_uid': version_uid, } ) + + def _handle_enketo_redirect(self, request, enketo_response, *args, **kwargs): + if request.path.strip('/').split('/')[-2] == 'redirect': + try: + enketo_url = enketo_response.data['url'] + except KeyError: + pass + else: + return HttpResponseRedirect(enketo_url) + return enketo_response