From 08c3d6e84b17da2acfb10250438fe357398e5e0e Mon Sep 17 00:00:00 2001 From: Trenton Holmes Date: Fri, 10 Jun 2022 10:12:01 -0700 Subject: [PATCH] Fixes existing testing, adds test coverage of new command --- src/documents/tests/test_management.py | 2 +- .../test_management_convert_thumbnail.py | 168 ++++++++++++++++++ 2 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 src/documents/tests/test_management_convert_thumbnail.py diff --git a/src/documents/tests/test_management.py b/src/documents/tests/test_management.py index 5e45086fe..65ed36ff9 100644 --- a/src/documents/tests/test_management.py +++ b/src/documents/tests/test_management.py @@ -163,7 +163,7 @@ class TestDecryptDocuments(TestCase): self.assertEqual(doc.filename, "0000004.pdf") self.assertTrue(os.path.isfile(os.path.join(originals_dir, "0000004.pdf"))) self.assertTrue(os.path.isfile(doc.source_path)) - self.assertTrue(os.path.isfile(os.path.join(thumb_dir, f"{doc.id:07}.png"))) + self.assertTrue(os.path.isfile(os.path.join(thumb_dir, f"{doc.id:07}.webp"))) self.assertTrue(os.path.isfile(doc.thumbnail_path)) with doc.source_file as f: diff --git a/src/documents/tests/test_management_convert_thumbnail.py b/src/documents/tests/test_management_convert_thumbnail.py new file mode 100644 index 000000000..162f05cfe --- /dev/null +++ b/src/documents/tests/test_management_convert_thumbnail.py @@ -0,0 +1,168 @@ +import filecmp +import shutil +import tempfile +from io import StringIO +from pathlib import Path +from unittest import mock + +from django.core.management import call_command +from django.test import override_settings +from django.test import TestCase +from documents.models import Document + + +class TestConvertThumbnails(TestCase): + def call_command(self): + stdout = StringIO() + stderr = StringIO() + call_command( + "convert_thumbnails", + "--no-color", + stdout=stdout, + stderr=stderr, + ) + return stdout.getvalue(), stderr.getvalue() + + def setUp(self): + """ + Creates a document in the database + """ + super().setUp() + + self.doc = Document.objects.create( + pk=1, + checksum="A", + title="A", + content="first document", + mime_type="application/pdf", + ) + self.doc.save() + + def pretend_convert_output(self, *args, **kwargs): + """ + Pretends to do the conversion, by copying the input file + to the output file + """ + shutil.copy2( + Path(kwargs["input_file"].rstrip("[0]")), + Path(kwargs["output_file"]), + ) + + def create_webp_thumbnail_file(self, thumb_dir): + """ + Creates a dummy WebP thumbnail file in the given directory, based on + the database Document + """ + thumb_file = Path(thumb_dir) / Path(f"{self.doc.pk:07}.webp") + thumb_file.write_text("this is a dummy webp file") + return thumb_file + + def create_png_thumbnail_file(self, thumb_dir): + """ + Creates a dummy PNG thumbnail file in the given directory, based on + the database Document + """ + thumb_file = Path(thumb_dir) / Path(f"{self.doc.pk:07}.png") + thumb_file.write_text("this is a dummy png file") + return thumb_file + + @mock.patch("documents.management.commands.convert_thumbnails.run_convert") + def test_do_nothing_if_converted(self, run_convert_mock): + """ + GIVEN: + - Document exists with default WebP thumbnail path + WHEN: + - Thumbnail conversion is attempted + THEN: + - Nothing is converted + """ + + stdout, _ = self.call_command() + run_convert_mock.assert_not_called() + self.assertIn("Converting all PNG thumbnails to WebP", stdout) + + @mock.patch("documents.management.commands.convert_thumbnails.run_convert") + def test_convert_single_thumbnail(self, run_convert_mock): + """ + GIVEN: + - Document exists with PNG thumbnail + WHEN: + - Thumbnail conversion is attempted + THEN: + - Single thumbnail is converted + """ + + run_convert_mock.side_effect = self.pretend_convert_output + + with tempfile.TemporaryDirectory() as thumbnail_dir: + + with override_settings( + THUMBNAIL_DIR=thumbnail_dir, + ): + + thumb_file = self.create_png_thumbnail_file(thumbnail_dir) + + stdout, _ = self.call_command() + + run_convert_mock.assert_called_once() + self.assertIn(f"{thumb_file}", stdout) + self.assertIn("Conversion to WebP completed", stdout) + + self.assertFalse(thumb_file.exists()) + self.assertTrue(thumb_file.with_suffix(".webp").exists()) + + @mock.patch("documents.management.commands.convert_thumbnails.run_convert") + def test_convert_errors_out(self, run_convert_mock): + """ + GIVEN: + - Document exists with PNG thumbnail + WHEN: + - Thumbnail conversion is attempted, but raises an exception + THEN: + - Single thumbnail is converted + """ + + run_convert_mock.side_effect = OSError + + with tempfile.TemporaryDirectory() as thumbnail_dir: + + with override_settings( + THUMBNAIL_DIR=thumbnail_dir, + ): + + thumb_file = self.create_png_thumbnail_file(thumbnail_dir) + + _, stderr = self.call_command() + + run_convert_mock.assert_called_once() + self.assertIn("Error converting thumbnail", stderr) + self.assertTrue(thumb_file.exists()) + + @mock.patch("documents.management.commands.convert_thumbnails.run_convert") + def test_convert_single_thumbnail_no_output(self, run_convert_mock): + """ + GIVEN: + - Document exists with PNG thumbnail + WHEN: + - Thumbnail conversion is attempted, but there is no output WebP + THEN: + - Single thumbnail is converted + """ + + with tempfile.TemporaryDirectory() as thumbnail_dir: + + with override_settings( + THUMBNAIL_DIR=thumbnail_dir, + ): + + thumb_file = self.create_png_thumbnail_file(thumbnail_dir) + + stdout, stderr = self.call_command() + + run_convert_mock.assert_called_once() + self.assertIn(f"{thumb_file}", stdout) + self.assertNotIn("Conversion to WebP completed", stdout) + self.assertIn("Converted thumbnail doesn't exist", stderr) + + self.assertTrue(thumb_file.exists()) + self.assertFalse(thumb_file.with_suffix(".webp").exists())