From 51a0f03c710511dfba5c66303679082454acab55 Mon Sep 17 00:00:00 2001 From: Lymar Volodymyr Date: Wed, 19 Jun 2024 10:33:12 +0200 Subject: [PATCH 1/5] feat: add download documet url and view --- makedoc/urls.py | 3 ++- makedoc/views.py | 39 +++++++++++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/makedoc/urls.py b/makedoc/urls.py index 17de741..4e480fd 100644 --- a/makedoc/urls.py +++ b/makedoc/urls.py @@ -1,8 +1,9 @@ from django.urls import path -from .views import DataDocView, CreateDocsView +from .views import DataDocView, CreateDocsView, DownloadDocView urlpatterns = [ path("filemake/", CreateDocsView.as_view(), name="file"), + path("downloadxls/", DownloadDocView.as_view(), name="downloadxls"), path("data/", DataDocView.as_view(), name="data"), ] diff --git a/makedoc/views.py b/makedoc/views.py index f1d83b0..4019b5f 100644 --- a/makedoc/views.py +++ b/makedoc/views.py @@ -1,7 +1,9 @@ import json +import os from typing import Any from django.core.cache import cache +from django.http import FileResponse from rest_framework import generics, status from rest_framework.exceptions import ValidationError from rest_framework.permissions import IsAuthenticated @@ -9,7 +11,6 @@ from rest_framework.views import APIView from makedoc.services import Documents - from .serializers import DataDocSerializer, DocumentsSimpleSerializer @@ -42,9 +43,36 @@ def get(self, request, *args, **kwargs): if docs.transport_sheet: docs.form_transport_sheet(request) - return Response( - {"message": "Документы сохранены", "data": validated_data}, status=status.HTTP_200_OK - ) + cache_key = f"last_created_file_user:{request.user.id}" + cache.set(cache_key, docs.archive_name, 300) + + return Response({"message": "Documents saved"}, status=status.HTTP_200_OK) + + +class DownloadDocView(APIView): + permission_classes = [IsAuthenticated] + + def get(self, request, *args, **kwargs): + cache_key = f"last_created_file_user:{request.user.id}" + file_name = cache.get(cache_key) + + if not file_name: + return Response({"error": "No file found"}, status=status.HTTP_404_NOT_FOUND) + + file_path = os.path.join("makedoc", "tempdoc", str(request.user.id), file_name) + + if not os.path.exists(file_path): + return Response({"error": "File path not found!"}, status=status.HTTP_404_NOT_FOUND) + + response = FileResponse(open(file_path, "rb")) + response["Content-Disposition"] = f'attachment; filename="{os.path.basename(file_name)}"' + + cache.delete(cache_key) + + response["message"] = "File successfully downloaded" + response.status_code = status.HTTP_200_OK + + return response class DataDocView(generics.GenericAPIView[Any]): @@ -60,8 +88,7 @@ def post(self, request, *args, **kwargs): validated_data = serializer.validated_data - # Use a more unique cache key cache_key = f"validated_data_{request.user.id}" cache.set(cache_key, json.dumps(validated_data), 120) - return Response({"success": True, "data": validated_data}, status=status.HTTP_200_OK) + return Response({"Success": True}, status=status.HTTP_200_OK) From 59225d1a0af344efe41cea5acd3d28ec6c4fc677 Mon Sep 17 00:00:00 2001 From: Lymar Volodymyr Date: Wed, 19 Jun 2024 10:38:08 +0200 Subject: [PATCH 2/5] test: add tests for document download view and create docs view --- makedoc/tests/conftest.py | 1 + makedoc/tests/test_views_makedoc.py | 44 ++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/makedoc/tests/conftest.py b/makedoc/tests/conftest.py index 0debfc0..e1dcc06 100644 --- a/makedoc/tests/conftest.py +++ b/makedoc/tests/conftest.py @@ -17,4 +17,5 @@ def authorized_client(user): client = APIClient() refresh = RefreshToken.for_user(user) client.credentials(HTTP_AUTHORIZATION=f"Bearer {str(refresh.access_token)}") + client.user = user return client diff --git a/makedoc/tests/test_views_makedoc.py b/makedoc/tests/test_views_makedoc.py index 698e905..d482fb2 100644 --- a/makedoc/tests/test_views_makedoc.py +++ b/makedoc/tests/test_views_makedoc.py @@ -1,4 +1,7 @@ +import json + import pytest +from django.core.cache import cache from django.urls import reverse from rest_framework.test import APIClient @@ -55,4 +58,43 @@ def test__data_doc_view__authorized_user_post_data_response_is_correct(authorize "delivery_cost": 1500, } response = authorized_client.post(url, data, format="json") - assert response.json() == {"success": True, "data": data} + assert response.status_code == 200 + assert response.json() == {"Success": True} + + +@pytest.mark.django_db +def test_create_docs_view_get_valid_data(authorized_client): + url = reverse("file") + cache_key = f"validated_data_{authorized_client.user.id}" + data = { + "delivery_type": "auto", + "client_id": 1, + "items": [ + {"product_id": 1, "quantity": 2, "discount": 10}, + {"product_id": 2, "quantity": 5, "discount": 4}, + ], + "factory_id": 1, + "destination": "New York", + "delivery_cost": 1500, + } + cache.set(cache_key, json.dumps(data), timeout=120) + response = authorized_client.get(url) + assert response.status_code == 200 + assert response.json() == {"message": "Documents saved"} + cache.delete(cache_key) + + +@pytest.mark.django_db +def test_create_docs_view_get_no_data(authorized_client): + url = reverse("file") + response = authorized_client.get(url) + assert response.status_code == 400 + assert response.json() == {"error": "No data found in cache"} + + +@pytest.mark.django_db +def test_download_doc_view(authorized_client): + url = reverse("downloadxls") + response = authorized_client.get(url) + assert response.status_code == 404 + assert response.json() == {"error": "No file found"} From 0b932a80aec240e84df160f732570ab5ba56e1e8 Mon Sep 17 00:00:00 2001 From: Lymar Volodymyr Date: Thu, 20 Jun 2024 10:35:11 +0200 Subject: [PATCH 3/5] test: corrected comments on tests --- makedoc/tests/conftest.py | 22 +++++++++ makedoc/tests/test_views_makedoc.py | 69 ++++++----------------------- makedoc/urls.py | 2 +- 3 files changed, 36 insertions(+), 57 deletions(-) diff --git a/makedoc/tests/conftest.py b/makedoc/tests/conftest.py index e1dcc06..b4200a7 100644 --- a/makedoc/tests/conftest.py +++ b/makedoc/tests/conftest.py @@ -1,9 +1,12 @@ import pytest +from faker import Faker from rest_framework.test import APIClient from rest_framework_simplejwt.tokens import RefreshToken from users.models import CustomUser +fake = Faker() + @pytest.fixture def user(django_user_model): @@ -19,3 +22,22 @@ def authorized_client(user): client.credentials(HTTP_AUTHORIZATION=f"Bearer {str(refresh.access_token)}") client.user = user return client + + +@pytest.fixture +def test_data(): + return { + "delivery_type": fake.random_element(elements=("auto", "manual")), + "client_id": fake.random_int(min=1, max=100), + "items": [ + {"product_id": fake.random_int(min=1, max=100), + "quantity": fake.random_int(min=1, max=10), + "discount": fake.random_int(min=0, max=50)}, + {"product_id": fake.random_int(min=1, max=100), + "quantity": fake.random_int(min=1, max=10), + "discount": fake.random_int(min=0, max=50)}, + ], + "factory_id": fake.random_int(min=1, max=100), + "destination": fake.city(), + "delivery_cost": fake.random_int(min=100, max=2000), + } diff --git a/makedoc/tests/test_views_makedoc.py b/makedoc/tests/test_views_makedoc.py index d482fb2..20f8dda 100644 --- a/makedoc/tests/test_views_makedoc.py +++ b/makedoc/tests/test_views_makedoc.py @@ -7,77 +7,34 @@ @pytest.mark.django_db -def test__data_doc_view__unauthorized_user_cannot_post_data() -> None: +def test__data_doc_view__unauthorized_user_cannot_post_data(test_data): client = APIClient() url = reverse("data") - data = { - "delivery_type": "auto", - "client_id": 1, - "items": [ - {"product_id": 1, "quantity": 2, "discount": 10}, - {"product_id": 2, "quantity": 5, "discount": 4}, - ], - "factory_id": 1, - "destination": "New York", - "delivery_cost": 1500, - } - response = client.post(url, data, format="json") - assert response.status_code == 401 # Unauthorized + response = client.post(url, test_data, format="json") + assert response.status_code == 401 @pytest.mark.django_db -def test__data_doc_view__authorized_user_can_post_data(authorized_client) -> None: +def test__data_doc_view__authorized_user_can_post_data(authorized_client, test_data): url = reverse("data") - data = { - "delivery_type": "auto", - "client_id": 1, - "items": [ - {"product_id": 1, "quantity": 2, "discount": 10}, - {"product_id": 2, "quantity": 5, "discount": 4}, - ], - "factory_id": 1, - "destination": "New York", - "delivery_cost": 1500, - } - response = authorized_client.post(url, data, format="json") + response = authorized_client.post(url, test_data, format="json") assert response.status_code == 200 @pytest.mark.django_db -def test__data_doc_view__authorized_user_post_data_response_is_correct(authorized_client) -> None: +def test__data_doc_view__authorized_user_post_data_response_is_correct(authorized_client, + test_data): url = reverse("data") - data = { - "delivery_type": "auto", - "client_id": 1, - "items": [ - {"product_id": 1, "quantity": 2, "discount": 10}, - {"product_id": 2, "quantity": 5, "discount": 4}, - ], - "factory_id": 1, - "destination": "New York", - "delivery_cost": 1500, - } - response = authorized_client.post(url, data, format="json") + response = authorized_client.post(url, test_data, format="json") assert response.status_code == 200 assert response.json() == {"Success": True} @pytest.mark.django_db -def test_create_docs_view_get_valid_data(authorized_client): +def test__create_docs_view__get_valid_data(authorized_client, test_data): url = reverse("file") cache_key = f"validated_data_{authorized_client.user.id}" - data = { - "delivery_type": "auto", - "client_id": 1, - "items": [ - {"product_id": 1, "quantity": 2, "discount": 10}, - {"product_id": 2, "quantity": 5, "discount": 4}, - ], - "factory_id": 1, - "destination": "New York", - "delivery_cost": 1500, - } - cache.set(cache_key, json.dumps(data), timeout=120) + cache.set(cache_key, json.dumps(test_data), timeout=120) response = authorized_client.get(url) assert response.status_code == 200 assert response.json() == {"message": "Documents saved"} @@ -85,7 +42,7 @@ def test_create_docs_view_get_valid_data(authorized_client): @pytest.mark.django_db -def test_create_docs_view_get_no_data(authorized_client): +def test__create_docs_view__get_no_data(authorized_client): url = reverse("file") response = authorized_client.get(url) assert response.status_code == 400 @@ -93,8 +50,8 @@ def test_create_docs_view_get_no_data(authorized_client): @pytest.mark.django_db -def test_download_doc_view(authorized_client): - url = reverse("downloadxls") +def test__download_doc_view__returns_404_when_no_file_exists(authorized_client): + url = reverse("downloadfile") response = authorized_client.get(url) assert response.status_code == 404 assert response.json() == {"error": "No file found"} diff --git a/makedoc/urls.py b/makedoc/urls.py index 4e480fd..ce10cec 100644 --- a/makedoc/urls.py +++ b/makedoc/urls.py @@ -4,6 +4,6 @@ urlpatterns = [ path("filemake/", CreateDocsView.as_view(), name="file"), - path("downloadxls/", DownloadDocView.as_view(), name="downloadxls"), + path("downloadfile/", DownloadDocView.as_view(), name="downloadfile"), path("data/", DataDocView.as_view(), name="data"), ] From 763e7afb9632d34ffd09810118ad9d0601eb7c17 Mon Sep 17 00:00:00 2001 From: Lymar Volodymyr Date: Thu, 20 Jun 2024 10:39:50 +0200 Subject: [PATCH 4/5] test: Fix tests name --- makedoc/tests/test_views_makedoc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/makedoc/tests/test_views_makedoc.py b/makedoc/tests/test_views_makedoc.py index 20f8dda..a912ae7 100644 --- a/makedoc/tests/test_views_makedoc.py +++ b/makedoc/tests/test_views_makedoc.py @@ -31,7 +31,7 @@ def test__data_doc_view__authorized_user_post_data_response_is_correct(authorize @pytest.mark.django_db -def test__create_docs_view__get_valid_data(authorized_client, test_data): +def test__create_docs_view__authorized_user_get_valid_data(authorized_client, test_data): url = reverse("file") cache_key = f"validated_data_{authorized_client.user.id}" cache.set(cache_key, json.dumps(test_data), timeout=120) @@ -42,7 +42,7 @@ def test__create_docs_view__get_valid_data(authorized_client, test_data): @pytest.mark.django_db -def test__create_docs_view__get_no_data(authorized_client): +def test__create_docs_view__authorized_user_get_no_data(authorized_client): url = reverse("file") response = authorized_client.get(url) assert response.status_code == 400 From 2ae707458dd22bcb2e3c41d0893d6f11ce5f9190 Mon Sep 17 00:00:00 2001 From: Lymar Volodymyr Date: Fri, 21 Jun 2024 08:44:56 +0200 Subject: [PATCH 5/5] test: corrected comments --- makedoc/tests/conftest.py | 27 ++++++++++++--------------- makedoc/tests/test_views_makedoc.py | 16 ++++++++-------- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/makedoc/tests/conftest.py b/makedoc/tests/conftest.py index b4200a7..ff0c90d 100644 --- a/makedoc/tests/conftest.py +++ b/makedoc/tests/conftest.py @@ -1,12 +1,9 @@ import pytest -from faker import Faker from rest_framework.test import APIClient from rest_framework_simplejwt.tokens import RefreshToken from users.models import CustomUser -fake = Faker() - @pytest.fixture def user(django_user_model): @@ -25,19 +22,19 @@ def authorized_client(user): @pytest.fixture -def test_data(): +def make_test_data(faker): return { - "delivery_type": fake.random_element(elements=("auto", "manual")), - "client_id": fake.random_int(min=1, max=100), + "delivery_type": faker.random_element(elements=("auto", "rw", "self-delivery")), + "client_id": faker.random_int(min=1, max=100), "items": [ - {"product_id": fake.random_int(min=1, max=100), - "quantity": fake.random_int(min=1, max=10), - "discount": fake.random_int(min=0, max=50)}, - {"product_id": fake.random_int(min=1, max=100), - "quantity": fake.random_int(min=1, max=10), - "discount": fake.random_int(min=0, max=50)}, + {"product_id": faker.random_int(min=1, max=100), + "quantity": faker.random_int(min=1, max=10), + "discount": faker.random_int(min=0, max=100)}, + {"product_id": faker.random_int(min=1, max=100), + "quantity": faker.random_int(min=1, max=10), + "discount": faker.random_int(min=0, max=100)}, ], - "factory_id": fake.random_int(min=1, max=100), - "destination": fake.city(), - "delivery_cost": fake.random_int(min=100, max=2000), + "factory_id": faker.random_int(min=1, max=100), + "destination": faker.city(), + "delivery_cost": faker.random_int(min=0, max=5000), } diff --git a/makedoc/tests/test_views_makedoc.py b/makedoc/tests/test_views_makedoc.py index a912ae7..6b74bef 100644 --- a/makedoc/tests/test_views_makedoc.py +++ b/makedoc/tests/test_views_makedoc.py @@ -7,34 +7,34 @@ @pytest.mark.django_db -def test__data_doc_view__unauthorized_user_cannot_post_data(test_data): +def test__data_doc_view__unauthorized_user_cannot_post_data(make_test_data): client = APIClient() url = reverse("data") - response = client.post(url, test_data, format="json") + response = client.post(url, make_test_data, format="json") assert response.status_code == 401 @pytest.mark.django_db -def test__data_doc_view__authorized_user_can_post_data(authorized_client, test_data): +def test__data_doc_view__authorized_user_can_post_data(authorized_client, make_test_data): url = reverse("data") - response = authorized_client.post(url, test_data, format="json") + response = authorized_client.post(url, make_test_data, format="json") assert response.status_code == 200 @pytest.mark.django_db def test__data_doc_view__authorized_user_post_data_response_is_correct(authorized_client, - test_data): + make_test_data): url = reverse("data") - response = authorized_client.post(url, test_data, format="json") + response = authorized_client.post(url, make_test_data, format="json") assert response.status_code == 200 assert response.json() == {"Success": True} @pytest.mark.django_db -def test__create_docs_view__authorized_user_get_valid_data(authorized_client, test_data): +def test__create_docs_view__authorized_user_get_valid_data(authorized_client, make_test_data): url = reverse("file") cache_key = f"validated_data_{authorized_client.user.id}" - cache.set(cache_key, json.dumps(test_data), timeout=120) + cache.set(cache_key, json.dumps(make_test_data), timeout=120) response = authorized_client.get(url) assert response.status_code == 200 assert response.json() == {"message": "Documents saved"}