diff --git a/api/tests/test_response_file.py b/api/tests/test_response_file.py index d82120f..8cd6777 100644 --- a/api/tests/test_response_file.py +++ b/api/tests/test_response_file.py @@ -1,63 +1,110 @@ import os +import json from django.conf import settings import tempfile from uuid import uuid4 from django.urls import reverse from rest_framework import status from rest_framework.test import APITestCase -from api.models import Order +from api.models import Order, OrderItem from api.tests.factories import BaseObjectsFactory -UUID_EXISTS = str(uuid4()) -UUID_FILE_NOTFOUND = str(uuid4()) -UUID_ORDER_NOTFOUND = str(uuid4()) +# Order +ORDER_EXISTS_UUID = str(uuid4()) +ORDER_FILE_NOTFOUND_UUID = str(uuid4()) +ORDER_NOTFOUND_UUID = str(uuid4()) + +# Order item +ITEM_EXISTS_UUID = str(uuid4()) +ITEM_FILE_NOTFOUND_UUID = str(uuid4()) +ITEM_NOTFOUND_UUID = str(uuid4()) + TMP_CONTENT="Hello world" + class TestResponseFile(APITestCase): """ Test sending extract result files """ + order_data = { + "order_type": "Privé", + "items": [ + {"product": "Maquette 3D"}, + {"product": "Maquette 3D"}, + {"product": "Maquette 3D"}, + ], + "title": "Test file exists", + "description": "Nice order", + "geom": {"type": "Polygon", "coordinates": [[[0,0], [0, 1], [1, 1], [0, 0]]]}, + } + + def addOrder(self, updates) -> Order: + data = self.order_data.copy() + data.update(updates) + id = json.loads(self.client.post(reverse("order-list"), data, format="json").content)["id"] + return Order.objects.get(id=id) def setUp(self): self.config = BaseObjectsFactory(self.client) settings.MEDIA_ROOT = tempfile.mkdtemp() with open(os.path.join(settings.MEDIA_ROOT, "demo_file"), "w") as tmpfile: tmpfile.write(TMP_CONTENT) - order_data = { - "order_type": "Privé", - "items": [], - "title": "Test file exists", - "description": "Nice order", - "geom": {"type": "Polygon", "coordinates": [[[0,0], [0, 1], [1, 1], [0, 0]]]}, - } + with open(os.path.join(settings.MEDIA_ROOT, "another_demo_file"), "w") as tmpfile: + tmpfile.write(TMP_CONTENT[::-1]) self.client.credentials(HTTP_AUTHORIZATION="Bearer " + self.config.client_token) - self.client.post(reverse("order-list"), order_data, format="json").content - order_data["title"] = "Test file not found" - self.client.post(reverse("order-list"), order_data, format="json").content - obj = Order.objects.filter(title="Test file exists")[0] - obj.download_guid = UUID_EXISTS + obj = self.addOrder({"title": "Test file exists"}) + obj.download_guid = ORDER_EXISTS_UUID obj.extract_result.name = "demo_file" obj.save() - obj = Order.objects.filter(title="Test file not found")[0] - obj.download_guid = UUID_FILE_NOTFOUND + obj = self.addOrder({"title": "Test file not found"}) + obj.download_guid = ORDER_FILE_NOTFOUND_UUID obj.extract_result.name = "missing_demo_file" obj.save() - def testSendFileSuccess(self): - url = reverse("download_by_uuid", kwargs={"guid": UUID_EXISTS}) + obj = self.addOrder({"title": "Order with tokened items"}) + items = obj.items.all() + item = OrderItem.objects.get(id=items[0].id) + item.token = ITEM_EXISTS_UUID + item.extract_result.name = "another_demo_file" + item.save() + + item = OrderItem.objects.get(id=items[1].id) + item.token = ITEM_FILE_NOTFOUND_UUID + item.extract_result.name = "missing_another_demo_file" + item.save() + + def testSendOrderFileSuccess(self): + url = reverse("download_by_uuid", kwargs={"guid": ORDER_EXISTS_UUID}) resp = self.client.get(url) self.assertEqual(TMP_CONTENT, str(resp.content, "utf8")) def testSendOrderNotFound(self): - url = reverse("download_by_uuid", kwargs={"guid": UUID_ORDER_NOTFOUND}) + url = reverse("download_by_uuid", kwargs={"guid": ORDER_NOTFOUND_UUID}) resp = self.client.get(url) - self.assertTrue("No Order matches" in str(resp.content)) + self.assertTrue("No object matches" in str(resp.content)) self.assertEqual(resp.status_code, status.HTTP_404_NOT_FOUND) def testSendFileNotFound(self): - url = reverse("download_by_uuid", kwargs={"guid": UUID_FILE_NOTFOUND}) + url = reverse("download_by_uuid", kwargs={"guid": ORDER_FILE_NOTFOUND_UUID}) + resp = self.client.get(url) + self.assertTrue("file not found" in str(resp.content)) + self.assertEqual(resp.status_code, status.HTTP_404_NOT_FOUND) + + def testSendItemFileSuccess(self): + url = reverse("download_by_uuid", kwargs={"guid": ITEM_EXISTS_UUID}) + resp = self.client.get(url) + self.assertEqual(TMP_CONTENT[::-1], str(resp.content, "utf8")) + + def testSendItemNotFound(self): + url = reverse("download_by_uuid", kwargs={"guid": ITEM_NOTFOUND_UUID}) + resp = self.client.get(url) + self.assertTrue("No object matches" in str(resp.content)) + self.assertEqual(resp.status_code, status.HTTP_404_NOT_FOUND) + + def testSendItemFileNotFound(self): + url = reverse("download_by_uuid", kwargs={"guid": ITEM_FILE_NOTFOUND_UUID}) resp = self.client.get(url) self.assertTrue("file not found" in str(resp.content)) self.assertEqual(resp.status_code, status.HTTP_404_NOT_FOUND) diff --git a/api/views.py b/api/views.py index 77432f4..ea502df 100644 --- a/api/views.py +++ b/api/views.py @@ -591,14 +591,19 @@ class DownloadView(generics.RetrieveAPIView): """ Returns the download link based on order UUID """ - queryset = Order.objects.all() serializer_class = OrderSerializer permission_classes = [permissions.AllowAny] authentication_classes = [] def get(self, request, guid): - queryset = self.get_queryset() - instance = get_object_or_404(queryset, download_guid=guid) + queryset = Order.objects.filter(download_guid=guid) + if not len(queryset): + queryset = OrderItem.objects.filter(token=guid) + if not len(queryset): + return Response( + {"detail": _("No object matches given id")}, status=status.HTTP_404_NOT_FOUND) + instance = queryset[0] + if instance.extract_result: file = Path(settings.MEDIA_ROOT, instance.extract_result.name) if file.is_file(): diff --git a/urls.py b/urls.py index 898a750..440bd03 100644 --- a/urls.py +++ b/urls.py @@ -69,7 +69,7 @@ path(f'{ROOTURL}auth/change/', views.UserChangeView.as_view(), name='auth_change_user'), path(f'{ROOTURL}auth/current/', views.CurrentUserView.as_view(), name='auth_current_user'), path(f'{ROOTURL}download/', views.OrderByUUIDView.as_view(), name='order_uuid'), - path(f'{ROOTURL}download//extract_result', views.DownloadView.as_view(), name='download_by_uuid'), + path(f'{ROOTURL}download//result', views.DownloadView.as_view(), name='download_by_uuid'), path(f'{ROOTURL}auth/password/', views.PasswordResetView.as_view(),name='auth_password'), path(f'{ROOTURL}auth/password/confirm', views.PasswordResetConfirmView.as_view(), name='auth_password_confirm'), path(f'{ROOTURL}auth/verify-email/', views.VerifyEmailView.as_view(), name='auth_verify_email'), @@ -84,7 +84,7 @@ path(f'{ROOTURL}token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), path(f'{ROOTURL}token/verify/', TokenVerifyView.as_view(), name='token_verify'), path(f'{ROOTURL}session-auth/', include('rest_framework.urls', namespace='rest_framework')), - re_path(rf'^{ROOTURL}validate/orderitem/(?P[a-zA-Z0-9_-]+)$', + path(f'{ROOTURL}validate/orderitem/', views.OrderItemByTokenView.as_view(), name='orderitem_validate'), path(f'{ROOTURL}admin/', admin.site.urls, name='admin'), path(f'{ROOTURL}', include(router.urls)),