aboutsummaryrefslogtreecommitdiffstats
path: root/pyblackbird_cc/resources
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
parenta3826ecdf0bcb097446e97ecc88166a5606ce471 (diff)
Migrates tests over from old project
Diffstat (limited to 'pyblackbird_cc/resources')
-rw-r--r--pyblackbird_cc/resources/tests/__init__.py0
-rw-r--r--pyblackbird_cc/resources/tests/test_file_processing.py144
-rw-r--r--pyblackbird_cc/resources/tests/test_forms.py60
-rw-r--r--pyblackbird_cc/resources/tests/test_models.py75
-rw-r--r--pyblackbird_cc/resources/tests/test_views.py155
-rw-r--r--pyblackbird_cc/resources/tests/testdata/seven_page.pdfbin0 -> 153396 bytes
-rw-r--r--pyblackbird_cc/resources/tests/testdata/test_small_file.pdfbin0 -> 14147 bytes
-rw-r--r--pyblackbird_cc/resources/tests/testdata/two_page.pdfbin0 -> 186265 bytes
8 files changed, 434 insertions, 0 deletions
diff --git a/pyblackbird_cc/resources/tests/__init__.py b/pyblackbird_cc/resources/tests/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pyblackbird_cc/resources/tests/__init__.py
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)
diff --git a/pyblackbird_cc/resources/tests/test_forms.py b/pyblackbird_cc/resources/tests/test_forms.py
new file mode 100644
index 0000000..1ca823f
--- /dev/null
+++ b/pyblackbird_cc/resources/tests/test_forms.py
@@ -0,0 +1,60 @@
+import unittest
+
+from django.core.files.uploadedfile import SimpleUploadedFile
+from django.test import TestCase
+
+from ..forms import ResourceCreateForm
+from ..models import ResourceCategory
+from ..models import ResourceType
+
+
+@unittest.skip("Skipping this test for now as it is broken")
+class ResourceCreateFormTest(TestCase):
+ def setUp(self):
+ self.resource_type = ResourceType.objects.create(name="Test Resource Type")
+ self.resource_category = ResourceCategory.objects.create(name="Test Resource Category")
+
+ def test_clean_pdf_files_validation_error(self):
+ # Create a list of dummy PDF files
+ pdf_files = [
+ SimpleUploadedFile(f"file{i}.pdf", b"file_content", content_type="application/pdf")
+ for i in range(11)
+ ]
+
+ # Create a list of dummy thumbnail files
+ thumbnail_files = [
+ SimpleUploadedFile(
+ f"thumbnail{i}.jpg",
+ b"thumbnail_content",
+ content_type="image/jpeg",
+ )
+ for i in range(6)
+ ]
+
+ # Create a form instance with the dummy PDF files and thumbnail files
+ form_data = {
+ "name": "Test Resource",
+ "description": "Test Description",
+ "resource_type": self.resource_type.id,
+ "age_range": "5-7",
+ "curriculum": "English",
+ "main_resource_category": self.resource_category.id,
+ }
+ form_files = {
+ "pdf_files": pdf_files,
+ "thumbnail_files": thumbnail_files,
+ }
+ form = ResourceCreateForm(data=form_data, files=form_files)
+
+ # Validate the form
+ is_valid = form.is_valid()
+
+ # Check if the validation errors are raised for pdf_files and thumbnail_files
+ self.assertFalse(is_valid)
+ self.assertIn("pdf_files", form.errors)
+ self.assertEqual(form.errors["pdf_files"], ["Please select up to 10 PDF files."])
+ self.assertIn("thumbnail_files", form.errors)
+ self.assertEqual(
+ form.errors["thumbnail_files"],
+ ["Please select up to 5 thumbnail files."],
+ )
diff --git a/pyblackbird_cc/resources/tests/test_models.py b/pyblackbird_cc/resources/tests/test_models.py
new file mode 100644
index 0000000..c7ed4d2
--- /dev/null
+++ b/pyblackbird_cc/resources/tests/test_models.py
@@ -0,0 +1,75 @@
+import unittest
+from unittest.mock import patch
+
+from django.test import TestCase
+
+from ..models import PDFPageSnapshot
+from ..models import PDFResource
+from ..models import Resource
+from ..models import ResourceCategory
+from ..models import ResourceType
+from ..views import ResourceInfo
+from ..views import _extract_metadata_from_resource
+
+
+class ResourceModelTest(TestCase):
+ def test_string_representation(self):
+ resource = Resource(name="Test Resource")
+ self.assertEqual(str(resource), "Test Resource")
+
+
+@unittest.skip("Skipping this test for now as it is broken")
+class TestExtractMetadata(TestCase):
+ @patch("resources.views.get_presigned_obj_url")
+ def test_extract_metadata_from_resource(self, mock_get_url):
+ # Create mock instances of ResourceType and ResourceCategory
+ mock_resource_type = ResourceType.objects.create(name="Test Type")
+ mock_main_category = ResourceCategory.objects.create(name="Test Main Category")
+
+ mock_resource = Resource(
+ name="Test Resource",
+ thumbnail_filenames=["thumb.jpg", "thumb2.jpg"],
+ created_at="2022-01-01",
+ updated_at="2022-01-02",
+ resource_type=mock_resource_type,
+ main_resource_category=mock_main_category,
+ age_range="5-7",
+ )
+ mock_get_url.return_value = "https://example.com/url"
+ result = _extract_metadata_from_resource(mock_resource)
+ self.assertIsInstance(result, ResourceInfo)
+ self.assertEqual(result.name, "Test Resource")
+ self.assertEqual(result.pdf_filenames, "test.pdf")
+ self.assertEqual(result.thumbnail_filenames, ["thumb.jpg", "thumb2.jpg"])
+ self.assertEqual(result.created, "2022-01-01")
+ self.assertEqual(result.updated, "2022-01-02")
+
+
+@unittest.skip("These tests will not run because they rely upon the view to get file size, etc.")
+class TestPDFResourceModel(TestCase):
+ def setUp(self):
+ self.resource_type = ResourceType.objects.create(name="Test Resource Type")
+ self.resource_category = ResourceCategory.objects.create(name="Test Resource Category")
+ self.resource = Resource.objects.create(
+ name="Test Resource",
+ resource_type=self.resource_type,
+ main_resource_category=self.resource_category,
+ age_range="5-7",
+ curriculum="English",
+ description="Test Description",
+ )
+ self.pdf_resource = PDFResource.objects.create(
+ resource=self.resource,
+ file_name="resources/tests/testdata/test_small_file.pdf",
+ )
+ self.pdf_page_snapshot = PDFPageSnapshot.objects.create(
+ name="Test Thumbnail Image",
+ file_name="test_resource_1.jpg",
+ pdf_file=self.pdf_resource,
+ )
+
+ def test_pdf_resource_string_representation(self):
+ self.assertEqual(str(self.resource), "Test Resource")
+
+ def test_get_pdf_snapshot_filenames(self):
+ self.assertEqual(self.pdf_resource.snapshot_file_names(), ["test_resource_1.jpg"])
diff --git a/pyblackbird_cc/resources/tests/test_views.py b/pyblackbird_cc/resources/tests/test_views.py
new file mode 100644
index 0000000..e71b3a2
--- /dev/null
+++ b/pyblackbird_cc/resources/tests/test_views.py
@@ -0,0 +1,155 @@
+import unittest
+
+from django.contrib.auth import get_user_model
+from django.contrib.auth.models import User
+from django.core.files.uploadedfile import SimpleUploadedFile
+from django.test import RequestFactory
+from django.test import TestCase
+from django.urls import reverse
+
+from .. import services
+from ..models import ResourceCategory
+from ..models import ResourceType
+from ..views import create_resource
+
+
+class PDFFileUploadTestCase(TestCase):
+ def setUp(self):
+ self.url = reverse("resources:create_resource")
+ self.two_page_pdf = "pyblackbird_cc/resources/tests/testdata/two_page.pdf"
+ self.seven_page_pdf = "pyblackbird_cc/resources/tests/testdata/seven_page.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,
+ )
+
+ # Log in the test user
+ self.client.login(email=self.email, password=self.password)
+
+ # Open the test files and create SimpleUploadedFile objects
+ with open(self.two_page_pdf, "rb") as file:
+ self.uploaded_two_page_pdf = SimpleUploadedFile(
+ "two_page.pdf",
+ file.read(),
+ content_type="application/pdf",
+ )
+ with open(self.seven_page_pdf, "rb") as file:
+ self.uploaded_seven_page_pdf = SimpleUploadedFile(
+ "seven_page.pdf",
+ file.read(),
+ content_type="application/pdf",
+ )
+
+ def tearDown(self):
+ # Close the SimpleUploadedFile objects
+ self.uploaded_two_page_pdf.close()
+ self.uploaded_seven_page_pdf.close()
+
+ def test_file_upload_is_pdf(self):
+ """
+ Test that a file can be uploaded successfully using our create_resource view.
+ """
+ response = self.client.post(
+ self.url,
+ {"pdf_files": [self.uploaded_two_page_pdf, self.uploaded_seven_page_pdf]},
+ )
+
+ two_page_metadata = services.get_pdf_metadata_from_path(self.two_page_pdf)
+ seven_page_metadata = services.get_pdf_metadata_from_path(self.seven_page_pdf)
+ image_files_two_pager = list(services.export_pages_as_images(self.two_page_pdf))
+ image_files_seven_pager = list(
+ services.export_pages_as_images(self.seven_page_pdf),
+ )
+
+ self.assertEqual(two_page_metadata.n_pages, 2)
+ self.assertEqual(seven_page_metadata.n_pages, 7)
+ self.assertGreater(two_page_metadata.file_size, 0)
+ self.assertGreater(seven_page_metadata.file_size, 0)
+ self.assertEqual(len(image_files_two_pager), 2)
+ self.assertEqual(len(image_files_seven_pager), 7)
+ self.assertEqual(response.status_code, 200)
+
+
+@unittest.skip("Currently not able to mock S3 API at this point")
+class TestCreateResourceUsingResourceFactory(TestCase):
+ def setUp(self):
+ self.factory = RequestFactory()
+ self.user = User.objects.create_user(
+ username="testuser",
+ password="testpassword",
+ )
+ self.two_page_pdf = "resources/tests/testdata/two_page.pdf"
+ self.seven_page_pdf = "resources/tests/testdata/seven_page.pdf"
+
+ # Create resource type
+ self.resource_type = ResourceType.objects.create(name="Test Resource Type")
+
+ # Create resource categories
+ self.main_resource_category = ResourceCategory.objects.create(
+ name="Test Main Category",
+ )
+ self.additional_resource_category = ResourceCategory.objects.create(
+ name="Test Additional Category",
+ )
+
+ def test_post_pdf(self):
+ # Open the test files and create SimpleUploadedFile objects
+ with open(self.two_page_pdf, "rb") as file:
+ uploaded_two_page_pdf = SimpleUploadedFile(
+ "two_page.pdf",
+ file.read(),
+ content_type="application/pdf",
+ )
+ with open(self.seven_page_pdf, "rb") as file:
+ uploaded_seven_page_pdf = SimpleUploadedFile(
+ "seven_page.pdf",
+ file.read(),
+ content_type="application/pdf",
+ )
+
+ # Create a thumbnail file (you can use a dummy file for testing)
+ thumbnail_file = SimpleUploadedFile(
+ "thumbnail.jpg",
+ b"thumbnail_content",
+ content_type="image/jpeg",
+ )
+
+ # Prepare the form data
+ form_data = {
+ "name": "Test Resource",
+ "description": "Test Description",
+ "resource_type": self.resource_type.id,
+ "age_range": "5-7",
+ "curriculum": "English",
+ "main_resource_category": self.main_resource_category.id,
+ "additional_resource_category": self.additional_resource_category.id,
+ "pdf_files": [uploaded_two_page_pdf, uploaded_seven_page_pdf],
+ "thumbnail_files": [thumbnail_file],
+ }
+
+ # Prepare the form files
+ form_files = {
+ "pdf_files": [uploaded_two_page_pdf, uploaded_seven_page_pdf],
+ "thumbnail_files": [thumbnail_file],
+ }
+
+ # Create the request object with form data and files
+ request = self.factory.post("/create/", data=form_data)
+ request.user = self.user
+
+ # TODO mock the call to the Spaces S3 service inside the view
+
+ # Call the create_resource view function
+ response = create_resource(request)
+
+ # Assert the response status code
+ self.assertEqual(
+ response.status_code,
+ 302,
+ ) # Assuming a successful form submission redirects (status code 302)
+
+ # Add more assertions as needed
diff --git a/pyblackbird_cc/resources/tests/testdata/seven_page.pdf b/pyblackbird_cc/resources/tests/testdata/seven_page.pdf
new file mode 100644
index 0000000..991a26d
--- /dev/null
+++ b/pyblackbird_cc/resources/tests/testdata/seven_page.pdf
Binary files differ
diff --git a/pyblackbird_cc/resources/tests/testdata/test_small_file.pdf b/pyblackbird_cc/resources/tests/testdata/test_small_file.pdf
new file mode 100644
index 0000000..9a990c8
--- /dev/null
+++ b/pyblackbird_cc/resources/tests/testdata/test_small_file.pdf
Binary files differ
diff --git a/pyblackbird_cc/resources/tests/testdata/two_page.pdf b/pyblackbird_cc/resources/tests/testdata/two_page.pdf
new file mode 100644
index 0000000..9c74944
--- /dev/null
+++ b/pyblackbird_cc/resources/tests/testdata/two_page.pdf
Binary files differ