diff options
author | Matthew Lemon <y@yulqen.org> | 2024-05-15 19:09:26 +0100 |
---|---|---|
committer | Matthew Lemon <y@yulqen.org> | 2024-05-15 19:09:26 +0100 |
commit | ae42defca04b78516712c64be27ee5f91e1da03d (patch) | |
tree | e5a5b32993432668845b2e9675b728eb7a5e604e /pyblackbird_cc/resources/tests/test_file_processing.py | |
parent | a3826ecdf0bcb097446e97ecc88166a5606ce471 (diff) |
Migrates tests over from old project
Diffstat (limited to 'pyblackbird_cc/resources/tests/test_file_processing.py')
-rw-r--r-- | pyblackbird_cc/resources/tests/test_file_processing.py | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/pyblackbird_cc/resources/tests/test_file_processing.py b/pyblackbird_cc/resources/tests/test_file_processing.py new file mode 100644 index 0000000..40cc5eb --- /dev/null +++ b/pyblackbird_cc/resources/tests/test_file_processing.py @@ -0,0 +1,144 @@ +from django.contrib.auth import get_user_model +from django.core.files.uploadedfile import InMemoryUploadedFile +from django.core.files.uploadedfile import SimpleUploadedFile +from django.core.files.uploadedfile import TemporaryUploadedFile +from django.test import TestCase +from django.urls import reverse + +from .. import services + +""" Explanation: +The type of uploaded file object (InMemoryUploadedFile, TemporaryUploadedFile, or SimpleUploadedFile) is determined by the size of +the uploaded file and the value of the FILE_UPLOAD_MAX_MEMORY_SIZE setting in Django. + +By default, FILE_UPLOAD_MAX_MEMORY_SIZE is set to 2.5 MB (2621440 bytes). This means that if the size of the uploaded file +is less than or equal to 2.5 MB, Django will use the MemoryFileUploadHandler to handle the file upload, and the resulting uploaded +file object will be an instance of InMemoryUploadedFile. + +If the size of the uploaded file exceeds the FILE_UPLOAD_MAX_MEMORY_SIZE threshold, Django will use the TemporaryFileUploadHandler to +handle the file upload, and the resulting uploaded file object will be an instance of TemporaryUploadedFile. In this case, the uploaded +file is temporarily stored on disk instead of being kept in memory. + +The SimpleUploadedFile is used when you manually create an uploaded file object in your code, such as in tests or when handling file +uploads programmatically. + +To test the behavior with different file sizes, you can try the following: + +Create a test file that is smaller than 2.5 MB and run the test. The uploaded file should be an instance of InMemoryUploadedFile. +Create a test file that is larger than 2.5 MB and run the test. The uploaded file should be an instance of TemporaryUploadedFile. +If you want to change the threshold size for using InMemoryUploadedFile, you can modify the FILE_UPLOAD_MAX_MEMORY_SIZE setting in your Django settings file. For example: +FILE_UPLOAD_MAX_MEMORY_SIZE = 5 * 1024 * 1024 # 5 MB + +With this setting, files up to 5 MB will be handled as InMemoryUploadedFile, and files larger than 5 MB will be handled as TemporaryUploadedFile. +Remember to test with files of different sizes to ensure that your application handles file uploads correctly based on your specific requirements and settings. + +We also test the integrity of the uploaded PDF file here by checking the number of pages in the file and whether it is a valid PDF file. +""" + + +class PDFFileUploadTestCase(TestCase): + def setUp(self): + self.url = reverse("resources:create_resource") + self.test_file_path = "pyblackbird_cc/resources/tests/testdata/test_small_file.pdf" + + # Create a test user + self.email = "testuser@example.com" + self.password = "testpassword" + self.user = get_user_model().objects.create_user( + email=self.email, + password=self.password, + ) + + def test_file_upload(self): + """ + Test that a file can be uploaded successfully using our create_resource view. + """ + self.client.login( + email=self.email, + password=self.password, + ) # Log in the test user + + with open(self.test_file_path, "rb") as file: + uploaded_file = SimpleUploadedFile( + "test_file.pdf", + file.read(), + content_type="application/pdf", + ) + + response = self.client.post(self.url, {"pdf_files": [uploaded_file]}) + + # Check if the response is OK + self.assertEqual(response.status_code, 200) + + def test_file_upload_with_upload_handlers(self): + """ + This test does not test my code but the behavior of the Django file upload handlers. + """ + self.client.login( + email=self.email, + password=self.password, + ) # Log in the test user + + with open(self.test_file_path, "rb") as file: + uploaded_file = SimpleUploadedFile( + "test_file.pdf", + file.read(), + content_type="application/pdf", + ) + + response = self.client.post(self.url, {"pdf_files": [uploaded_file]}) + + self.assertEqual(response.status_code, 200) + + # Check if the uploaded file was handled by MemoryFileUploadHandler or TemporaryFileUploadHandler + uploaded_files = response.wsgi_request.FILES.getlist("pdf_files") + self.assertEqual(len(uploaded_files), 1) + + # We should expect an instance of InMemoryUploadedFile here because test_small_file.pdf is less than 2.5 MB + self.assertIsInstance( + uploaded_files[0], + (SimpleUploadedFile, TemporaryUploadedFile, InMemoryUploadedFile), + ) + + def test_uploaded_pdf_file_metadata(self): + """ + This test does not test my application code, but rather tests the + behavior of the Django file upload handlers. + """ + self.client.login( + email=self.email, + password=self.password, + ) # Log in the test user + + with open(self.test_file_path, "rb") as file: + uploaded_file = SimpleUploadedFile( + "test_file.pdf", + file.read(), + content_type="application/pdf", + ) + + response = self.client.post(self.url, {"pdf_files": [uploaded_file]}) + + self.assertEqual( + response.status_code, + 200, + ) + + # Extract metadata from the uploaded file + pdf_metadata_from_path = services.get_pdf_metadata_from_path(self.test_file_path) + + # Get the number of pages in the PDF - is 4 + self.assertEqual(pdf_metadata_from_path.n_pages, 4) + + # Get the file size in bytes + self.assertGreater(pdf_metadata_from_path.file_size, 0) + + self.assertLess( + pdf_metadata_from_path.file_size, + 5 * 1024 * 1024, + ) # Assuming a maximum file size of 5 MB + + # self.assertTrue(services.export_pdf_pages_as_images_temp_dir(self.test_file_path)) + # capture the output of the export_pdf_pages_as_images_temp_dir function coroutine + files = list(services.export_pages_as_images(self.test_file_path)) + self.assertEqual(len(files), 4) |