From 6c8ae45283b49ce08601c856333c1f91b0a70abe Mon Sep 17 00:00:00 2001 From: ariannedee Date: Thu, 1 Oct 2020 12:08:44 -0700 Subject: [PATCH] Add create document validation tests --- edivorce/apps/core/serializer.py | 16 ++++++++-- edivorce/apps/core/tests/test_api.py | 44 ++++++++++++++++++++++++++-- edivorce/apps/core/views/api.py | 2 +- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/edivorce/apps/core/serializer.py b/edivorce/apps/core/serializer.py index fa0dee2c..c19016f3 100644 --- a/edivorce/apps/core/serializer.py +++ b/edivorce/apps/core/serializer.py @@ -23,10 +23,22 @@ class UserResponseSerializer(serializers.ModelSerializer): instance.save() +def file_extension_accepted(file): + extension = file.name.split('.')[-1] + if extension.lower() not in ['pdf', 'png', 'gif', 'jpg', 'jpe', 'jpeg']: + raise ValidationError(f'File type not supported: {extension}') + + +def doc_type_accepted(value): + valid_codes = ['AAI', 'AFDO', 'AFTL', 'CSA', 'EFSS', 'MC', 'NCV', 'OFI', 'RDP'] + if value.upper() not in valid_codes: + raise ValidationError(f'Doc type not supported: {value}. Valid codes: {", ".join(valid_codes)}') + + class CreateDocumentSerializer(serializers.ModelSerializer): - doc_type = serializers.CharField(required=True) + doc_type = serializers.CharField(required=True, validators=[doc_type_accepted]) party_code = serializers.IntegerField(min_value=0, max_value=2, required=True) - file = serializers.FileField(required=True) + file = serializers.FileField(required=True, validators=[file_extension_accepted]) filename = serializers.CharField(read_only=True) size = serializers.IntegerField(read_only=True) rotation = serializers.IntegerField(read_only=True) diff --git a/edivorce/apps/core/tests/test_api.py b/edivorce/apps/core/tests/test_api.py index cd9e1999..39959184 100644 --- a/edivorce/apps/core/tests/test_api.py +++ b/edivorce/apps/core/tests/test_api.py @@ -54,6 +54,46 @@ class APITest(APITestCase): self.assertEqual(document.filename, file.name) self.assertEqual(document.size, file.size) + def test_post_duplicate_files_not_allowed(self): + url = reverse('documents') + + file = self._create_file() + data = { + 'file': file, + 'doc_type': 'AAI', + 'party_code': 1 + } + self.client.force_authenticate(self.user) + response = self.client.post(url, data) + + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertEqual(Document.objects.count(), 1) + + file.seek(0) # + response = self.client.post(url, data) + self.assertContains(response, + 'This file appears to have already been uploaded for this document.', + status_code=status.HTTP_400_BAD_REQUEST) + + def test_post_field_validation(self): + url = reverse('documents') + + file = self._create_file(extension='HEIC') + data = { + 'file': file, + 'doc_type': 'INVALID', + 'party_code': 3 + } + self.client.force_authenticate(self.user) + response = self.client.post(url, data) + self.assertEqual(Document.objects.count(), 0) + + json_response = json.loads(response.content) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertIn('File type not supported', json_response['file'][0]) + self.assertIn('Doc type not supported', json_response['doc_type'][0]) + self.assertIn('Ensure this value is less than or equal to 2', json_response['party_code'][0]) + def test_get_documents_meta_must_be_logged_in(self): url = reverse('documents-meta', kwargs={'doc_type': self.default_doc_type, 'party_code': self.default_party_code}) response = self.client.get(url) @@ -120,9 +160,9 @@ class APITest(APITestCase): return document @staticmethod - def _create_file(): + def _create_file(extension='jpg'): num_documents = Document.objects.count() - new_file = SimpleUploadedFile(f'test_file_{num_documents + 1}.jpg', b'test content') + new_file = SimpleUploadedFile(f'test_file_{num_documents + 1}.{extension}', b'test content') return new_file def _response_data_equals_document(self, response_doc, document_object): diff --git a/edivorce/apps/core/views/api.py b/edivorce/apps/core/views/api.py index 819e2c11..e9f901df 100644 --- a/edivorce/apps/core/views/api.py +++ b/edivorce/apps/core/views/api.py @@ -2,7 +2,7 @@ import re import graphene import graphene_django -from django.http import Http404, HttpResponse, HttpResponseGone +from django.http import Http404, HttpResponse, HttpResponseBadRequest, HttpResponseGone from graphql import GraphQLError from rest_framework import permissions, status from rest_framework.generics import CreateAPIView, ListAPIView, RetrieveUpdateDestroyAPIView