Skip to content

Commit

Permalink
Make it possible to download OrderItem results by token UUID
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrey Rusakov committed Nov 6, 2024
1 parent b92140e commit b0b6b0e
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 28 deletions.
93 changes: 70 additions & 23 deletions api/tests/test_response_file.py
Original file line number Diff line number Diff line change
@@ -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)
11 changes: 8 additions & 3 deletions api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand Down
4 changes: 2 additions & 2 deletions urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -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/<uuid:guid>', views.OrderByUUIDView.as_view(), name='order_uuid'),
path(f'{ROOTURL}download/<uuid:guid>/extract_result', views.DownloadView.as_view(), name='download_by_uuid'),
path(f'{ROOTURL}download/<uuid:guid>/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'),
Expand All @@ -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<token>[a-zA-Z0-9_-]+)$',
path(f'{ROOTURL}validate/orderitem/<uuid:token>',
views.OrderItemByTokenView.as_view(), name='orderitem_validate'),
path(f'{ROOTURL}admin/', admin.site.urls, name='admin'),
path(f'{ROOTURL}', include(router.urls)),
Expand Down

0 comments on commit b0b6b0e

Please sign in to comment.