From ae8e31624c929cec5586fbf438abecb978474943 Mon Sep 17 00:00:00 2001 From: Benjamin Monjoie Date: Thu, 30 May 2024 15:45:56 +0200 Subject: [PATCH] Display a QRCode in the project configuration popup IA-3004 --- .../projects/components/ProjectInfos.tsx | 11 ++++++++++ iaso/api/projects/viewsets.py | 20 ++++++++++++++++++- iaso/tests/api/test_projects.py | 18 +++++++++++++++++ requirements.txt | 1 + 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/hat/assets/js/apps/Iaso/domains/projects/components/ProjectInfos.tsx b/hat/assets/js/apps/Iaso/domains/projects/components/ProjectInfos.tsx index 7b6198e0c2..6a2e4fc2d2 100644 --- a/hat/assets/js/apps/Iaso/domains/projects/components/ProjectInfos.tsx +++ b/hat/assets/js/apps/Iaso/domains/projects/components/ProjectInfos.tsx @@ -10,6 +10,7 @@ type Form = { }; type ProjectForm = { + id?: Form; app_id: Form; name: Form; }; @@ -43,6 +44,16 @@ const ProjectInfos: FunctionComponent = ({ label={MESSAGES.appId} required /> + {currentProject.id?.value && ( +
+ QRCode +
+ )} ); diff --git a/iaso/api/projects/viewsets.py b/iaso/api/projects/viewsets.py index 66d6a92712..0b1bacbcca 100644 --- a/iaso/api/projects/viewsets.py +++ b/iaso/api/projects/viewsets.py @@ -1,4 +1,9 @@ -from rest_framework import filters, permissions +from django.http import HttpResponse +from qr_code.qrcode.maker import make_qr_code_image +from qr_code.qrcode.utils import QRCodeOptions +from rest_framework import filters, permissions, status +from rest_framework.decorators import action + from iaso.models import Project from .serializers import ProjectSerializer @@ -25,3 +30,16 @@ def get_queryset(self): """Always filter the base queryset by account""" return Project.objects.filter(account=self.request.user.iaso_profile.account) + + @action(detail=True, methods=["get"]) + def qr_code(self, request, *args, **kwargs): + """Returns the qrcode image to configure the mobile application.""" + project = self.get_object() + return HttpResponse( + status=status.HTTP_200_OK, + content_type="image/png", + content=make_qr_code_image( + data='{"url": "' + request.build_absolute_uri("/") + '", "app_id": "' + project.app_id + '"}', + qr_code_options=QRCodeOptions(size="S", image_format="png", error_correction="L"), + ), + ) diff --git a/iaso/tests/api/test_projects.py b/iaso/tests/api/test_projects.py index 10b0c68873..9b75240f28 100644 --- a/iaso/tests/api/test_projects.py +++ b/iaso/tests/api/test_projects.py @@ -155,6 +155,24 @@ def test_projects_delete(self): response = self.client.delete(f"/api/projects/{self.project_1.id}/", format="json") self.assertJSONResponse(response, 405) + def test_qr_code_unauthenticated(self): + """GET /projects//qr_code/: return the proper QR code""" + response = self.client.get(f"/api/projects/{self.project_1.id}/qr_code/") + self.assertEqual(401, response.status_code) + + def test_qr_code(self): + """GET /projects//qr_code/: return the proper QR code""" + self.client.force_authenticate(self.jane) + response = self.client.get(f"/api/projects/{self.project_1.id}/qr_code/") + self.assertEqual(200, response.status_code) + self.assertEqual("image/png", response["Content-Type"]) + + def test_qr_code_not_found(self): + """GET /projects//qr_code/: return 404""" + self.client.force_authenticate(self.jane) + response = self.client.get(f"/api/projects/WRONG/qr_code/") + self.assertEqual(404, response.status_code) + def assertValidProjectListData(self, list_data: typing.Mapping, expected_length: int, paginated: bool = False): self.assertValidListData( list_data=list_data, expected_length=expected_length, results_key="projects", paginated=paginated diff --git a/requirements.txt b/requirements.txt index e22e6d5488..42167d966d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,6 +10,7 @@ django-sql-dashboard==1.2 # https://github.com/simonw/django-sql-dashboard/tags django-storages==1.14.2 # https://github.com/jschneier/django-storages/tags django-translated-fields==0.12.0 # https://github.com/matthiask/django-translated-fields/tags django-phonenumber-field[phonenumberslite]==7.3.0 # https://django-phonenumber-field.readthedocs.io/en/latest/ +django-qr-code==4.0.1 # https://django-qr-code.readthedocs.io/en/latest/ # Django REST Framework. # ------------------------------------------------------------------------------