aboutsummaryrefslogtreecommitdiffstats
path: root/pyblackbird_cc/resources/tests/test_file_processing.py
diff options
context:
space:
mode:
authorMatthew Lemon <y@yulqen.org>2024-05-15 19:09:26 +0100
committerMatthew Lemon <y@yulqen.org>2024-05-15 19:09:26 +0100
commitae42defca04b78516712c64be27ee5f91e1da03d (patch)
treee5a5b32993432668845b2e9675b728eb7a5e604e /pyblackbird_cc/resources/tests/test_file_processing.py
parenta3826ecdf0bcb097446e97ecc88166a5606ce471 (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.py144
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)