From 0df91c31f18ceaa9a37e475828aa9bf92f4a15c7 Mon Sep 17 00:00:00 2001 From: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sun, 19 Feb 2023 18:00:45 -0800 Subject: [PATCH] Creates a mix-in for asserting file system states --- src/documents/tests/test_barcodes.py | 16 +- src/documents/tests/test_consumer.py | 43 ++-- src/documents/tests/test_file_handling.py | 200 +++++++++--------- src/documents/tests/test_management.py | 29 +-- .../tests/test_management_exporter.py | 71 +++---- .../tests/test_management_thumbnails.py | 23 +- .../tests/test_migration_archive_files.py | 17 +- src/documents/tests/test_tasks.py | 17 +- src/documents/tests/utils.py | 21 ++ src/paperless_mail/tests/test_mail.py | 9 +- src/paperless_mail/tests/test_parsers.py | 11 +- src/paperless_mail/tests/test_parsers_live.py | 11 +- src/paperless_tesseract/tests/test_parser.py | 55 ++--- src/paperless_text/tests/test_parser.py | 5 +- 14 files changed, 275 insertions(+), 253 deletions(-) diff --git a/src/documents/tests/test_barcodes.py b/src/documents/tests/test_barcodes.py index 86c53755b..7019c07b3 100644 --- a/src/documents/tests/test_barcodes.py +++ b/src/documents/tests/test_barcodes.py @@ -9,10 +9,11 @@ from documents import barcodes from documents import tasks from documents.consumer import ConsumerError from documents.tests.utils import DirectoriesMixin +from documents.tests.utils import FileSystemAssertsMixin from PIL import Image -class TestBarcode(DirectoriesMixin, TestCase): +class TestBarcode(DirectoriesMixin, FileSystemAssertsMixin, TestCase): SAMPLE_DIR = os.path.join( os.path.dirname(__file__), @@ -253,7 +254,7 @@ class TestBarcode(DirectoriesMixin, TestCase): shutil.copy(test_file, dst) target_file = barcodes.convert_from_tiff_to_pdf(dst) file_extension = os.path.splitext(os.path.basename(target_file))[1] - self.assertTrue(os.path.isfile(target_file)) + self.assertIsFile(target_file) self.assertEqual(file_extension, ".pdf") def test_convert_error_from_pdf_to_pdf(self): @@ -634,7 +635,7 @@ class TestBarcode(DirectoriesMixin, TestCase): ) barcodes.save_to_dir(test_file, target_dir=settings.SCRATCH_DIR) target_file = os.path.join(settings.SCRATCH_DIR, "patch-code-t.pdf") - self.assertTrue(os.path.isfile(target_file)) + self.assertIsFile(target_file) def test_save_to_dir_not_existing(self): """ @@ -651,8 +652,7 @@ class TestBarcode(DirectoriesMixin, TestCase): "patch-code-t.pdf", ) nonexistingdir = "/nowhere" - if os.path.isdir(nonexistingdir): - self.fail("non-existing dir exists") + self.assertIsNotDir(nonexistingdir) with self.assertLogs("paperless.barcodes", level="WARNING") as cm: barcodes.save_to_dir(test_file, target_dir=nonexistingdir) @@ -683,7 +683,7 @@ class TestBarcode(DirectoriesMixin, TestCase): target_dir=settings.SCRATCH_DIR, ) target_file = os.path.join(settings.SCRATCH_DIR, "newname.pdf") - self.assertTrue(os.path.isfile(target_file)) + self.assertIsFile(target_file) def test_barcode_splitter(self): """ @@ -724,8 +724,8 @@ class TestBarcode(DirectoriesMixin, TestCase): "patch-code-t-middle_document_1.pdf", ) - self.assertTrue(os.path.isfile(target_file1)) - self.assertTrue(os.path.isfile(target_file2)) + self.assertIsFile(target_file1) + self.assertIsFile(target_file2) @override_settings(CONSUMER_ENABLE_BARCODES=True) def test_consume_barcode_file(self): diff --git a/src/documents/tests/test_consumer.py b/src/documents/tests/test_consumer.py index 8aaefa242..b22870780 100644 --- a/src/documents/tests/test_consumer.py +++ b/src/documents/tests/test_consumer.py @@ -30,6 +30,7 @@ from ..parsers import DocumentParser from ..parsers import ParseError from ..tasks import sanity_check from .utils import DirectoriesMixin +from documents.tests.utils import FileSystemAssertsMixin class TestAttributes(TestCase): @@ -241,7 +242,7 @@ def fake_magic_from_file(file, mime=False): @mock.patch("documents.consumer.magic.from_file", fake_magic_from_file) -class TestConsumer(DirectoriesMixin, TestCase): +class TestConsumer(DirectoriesMixin, FileSystemAssertsMixin, TestCase): def _assert_first_last_send_progress( self, first_status="STARTING", @@ -346,16 +347,16 @@ class TestConsumer(DirectoriesMixin, TestCase): self.assertEqual(document.filename, "0000001.pdf") self.assertEqual(document.archive_filename, "0000001.pdf") - self.assertTrue(os.path.isfile(document.source_path)) + self.assertIsFile(document.source_path) - self.assertTrue(os.path.isfile(document.thumbnail_path)) + self.assertIsFile(document.thumbnail_path) - self.assertTrue(os.path.isfile(document.archive_path)) + self.assertIsFile(document.archive_path) self.assertEqual(document.checksum, "42995833e01aea9b3edee44bbfdd7ce1") self.assertEqual(document.archive_checksum, "62acb0bcbfbcaa62ca6ad3668e4e404b") - self.assertFalse(os.path.isfile(filename)) + self.assertIsNotFile(filename) self._assert_first_last_send_progress() @@ -383,14 +384,14 @@ class TestConsumer(DirectoriesMixin, TestCase): shutil.copy(filename, shadow_file) - self.assertTrue(os.path.isfile(shadow_file)) + self.assertIsFile(shadow_file) document = self.consumer.try_consume_file(filename) - self.assertTrue(os.path.isfile(document.source_path)) + self.assertIsFile(document.source_path) - self.assertFalse(os.path.isfile(shadow_file)) - self.assertFalse(os.path.isfile(filename)) + self.assertIsNotFile(shadow_file) + self.assertIsNotFile(filename) def testOverrideFilename(self): filename = self.get_test_file() @@ -536,7 +537,7 @@ class TestConsumer(DirectoriesMixin, TestCase): self._assert_first_last_send_progress(last_status="FAILED") # file not deleted - self.assertTrue(os.path.isfile(filename)) + self.assertIsFile(filename) # Database empty self.assertEqual(len(Document.objects.all()), 0) @@ -573,9 +574,9 @@ class TestConsumer(DirectoriesMixin, TestCase): document = self.consumer.try_consume_file(filename, override_title="new docs") self.assertEqual(document.title, "new docs") - self.assertIsNotNone(os.path.isfile(document.title)) - self.assertTrue(os.path.isfile(document.source_path)) - self.assertTrue(os.path.isfile(document.archive_path)) + self.assertIsNotNone(document.title) + self.assertIsFile(document.source_path) + self.assertIsFile(document.archive_path) self._assert_first_last_send_progress() @@ -603,35 +604,35 @@ class TestConsumer(DirectoriesMixin, TestCase): @override_settings(CONSUMER_DELETE_DUPLICATES=True) def test_delete_duplicate(self): dst = self.get_test_file() - self.assertTrue(os.path.isfile(dst)) + self.assertIsFile(dst) doc = self.consumer.try_consume_file(dst) self._assert_first_last_send_progress() - self.assertFalse(os.path.isfile(dst)) + self.assertIsNotFile(dst) self.assertIsNotNone(doc) self._send_progress.reset_mock() dst = self.get_test_file() - self.assertTrue(os.path.isfile(dst)) + self.assertIsFile(dst) self.assertRaises(ConsumerError, self.consumer.try_consume_file, dst) - self.assertFalse(os.path.isfile(dst)) + self.assertIsNotFile(dst) self._assert_first_last_send_progress(last_status="FAILED") @override_settings(CONSUMER_DELETE_DUPLICATES=False) def test_no_delete_duplicate(self): dst = self.get_test_file() - self.assertTrue(os.path.isfile(dst)) + self.assertIsFile(dst) doc = self.consumer.try_consume_file(dst) - self.assertFalse(os.path.isfile(dst)) + self.assertIsNotFile(dst) self.assertIsNotNone(doc) dst = self.get_test_file() - self.assertTrue(os.path.isfile(dst)) + self.assertIsFile(dst) self.assertRaises(ConsumerError, self.consumer.try_consume_file, dst) - self.assertTrue(os.path.isfile(dst)) + self.assertIsFile(dst) self._assert_first_last_send_progress(last_status="FAILED") diff --git a/src/documents/tests/test_file_handling.py b/src/documents/tests/test_file_handling.py index 2c91f2e0d..3f1dabdcb 100644 --- a/src/documents/tests/test_file_handling.py +++ b/src/documents/tests/test_file_handling.py @@ -9,8 +9,8 @@ from django.db import DatabaseError from django.test import override_settings from django.test import TestCase from django.utils import timezone +from documents.tests.utils import FileSystemAssertsMixin -from ..bulk_edit import bulk_update_documents from ..file_handling import create_source_path_directory from ..file_handling import delete_empty_directories from ..file_handling import generate_filename @@ -21,7 +21,7 @@ from ..models import StoragePath from .utils import DirectoriesMixin -class TestFileHandling(DirectoriesMixin, TestCase): +class TestFileHandling(DirectoriesMixin, FileSystemAssertsMixin, TestCase): @override_settings(FILENAME_FORMAT="") def test_generate_source_filename(self): document = Document() @@ -47,7 +47,7 @@ class TestFileHandling(DirectoriesMixin, TestCase): # Test default source_path self.assertEqual( document.source_path, - settings.ORIGINALS_DIR + f"/{document.pk:07d}.pdf", + os.path.join(settings.ORIGINALS_DIR, f"{document.pk:07d}.pdf"), ) document.filename = generate_filename(document) @@ -65,18 +65,17 @@ class TestFileHandling(DirectoriesMixin, TestCase): # test that creating dirs for the source_path creates the correct directory create_source_path_directory(document.source_path) Path(document.source_path).touch() - self.assertEqual(os.path.isdir(settings.ORIGINALS_DIR + "/none"), True) + self.assertIsDir(os.path.join(settings.ORIGINALS_DIR, "none")) # Set a correspondent and save the document document.correspondent = Correspondent.objects.get_or_create(name="test")[0] document.save() # Check proper handling of files - self.assertEqual(os.path.isdir(settings.ORIGINALS_DIR + "/test"), True) - self.assertEqual(os.path.isdir(settings.ORIGINALS_DIR + "/none"), False) - self.assertEqual( - os.path.isfile(settings.ORIGINALS_DIR + "/test/test.pdf.gpg"), - True, + self.assertIsDir(os.path.join(settings.ORIGINALS_DIR, "test")) + self.assertIsNotDir(os.path.join(settings.ORIGINALS_DIR, "none")) + self.assertIsFile( + os.path.join(settings.ORIGINALS_DIR, "test/test.pdf.gpg"), ) @override_settings(FILENAME_FORMAT="{correspondent}/{correspondent}") @@ -95,24 +94,23 @@ class TestFileHandling(DirectoriesMixin, TestCase): # Test source_path self.assertEqual( document.source_path, - settings.ORIGINALS_DIR + "/none/none.pdf", + os.path.join(settings.ORIGINALS_DIR, "none/none.pdf"), ) # Make the folder read- and execute-only (no writing and no renaming) - os.chmod(settings.ORIGINALS_DIR + "/none", 0o555) + os.chmod(os.path.join(settings.ORIGINALS_DIR, "none"), 0o555) # Set a correspondent and save the document document.correspondent = Correspondent.objects.get_or_create(name="test")[0] document.save() # Check proper handling of files - self.assertEqual( - os.path.isfile(settings.ORIGINALS_DIR + "/none/none.pdf"), - True, + self.assertIsFile( + os.path.join(settings.ORIGINALS_DIR, "none/none.pdf"), ) self.assertEqual(document.filename, "none/none.pdf") - os.chmod(settings.ORIGINALS_DIR + "/none", 0o777) + os.chmod(os.path.join(settings.ORIGINALS_DIR, "none"), 0o777) @override_settings(FILENAME_FORMAT="{correspondent}/{correspondent}") def test_file_renaming_database_error(self): @@ -136,7 +134,7 @@ class TestFileHandling(DirectoriesMixin, TestCase): Path(document.source_path).touch() # Test source_path - self.assertTrue(os.path.isfile(document.source_path)) + self.assertIsFile(document.source_path) # Set a correspondent and save the document document.correspondent = Correspondent.objects.get_or_create(name="test")[0] @@ -146,10 +144,9 @@ class TestFileHandling(DirectoriesMixin, TestCase): document.save() # Check proper handling of files - self.assertTrue(os.path.isfile(document.source_path)) - self.assertEqual( - os.path.isfile(settings.ORIGINALS_DIR + "/none/none.pdf"), - True, + self.assertIsFile(document.source_path) + self.assertIsFile( + os.path.join(settings.ORIGINALS_DIR, "none/none.pdf"), ) self.assertEqual(document.filename, "none/none.pdf") @@ -170,11 +167,10 @@ class TestFileHandling(DirectoriesMixin, TestCase): # Ensure file deletion after delete pk = document.pk document.delete() - self.assertEqual( - os.path.isfile(settings.ORIGINALS_DIR + "/none/none.pdf"), - False, + self.assertIsNotFile( + os.path.join(settings.ORIGINALS_DIR, "none", "none.pdf"), ) - self.assertEqual(os.path.isdir(settings.ORIGINALS_DIR + "/none"), False) + self.assertIsNotDir(os.path.join(settings.ORIGINALS_DIR, "none")) @override_settings( FILENAME_FORMAT="{correspondent}/{correspondent}", @@ -194,15 +190,14 @@ class TestFileHandling(DirectoriesMixin, TestCase): Path(document.source_path).touch() # Ensure file was moved to trash after delete - self.assertEqual(os.path.isfile(settings.TRASH_DIR + "/none/none.pdf"), False) + self.assertIsNotFile(os.path.join(settings.TRASH_DIR, "none", "none.pdf")) document.delete() - self.assertEqual( - os.path.isfile(settings.ORIGINALS_DIR + "/none/none.pdf"), - False, + self.assertIsNotFile( + os.path.join(settings.ORIGINALS_DIR, "none", "none.pdf"), ) - self.assertEqual(os.path.isdir(settings.ORIGINALS_DIR + "/none"), False) - self.assertEqual(os.path.isfile(settings.TRASH_DIR + "/none.pdf"), True) - self.assertEqual(os.path.isfile(settings.TRASH_DIR + "/none_01.pdf"), False) + self.assertIsNotDir(os.path.join(settings.ORIGINALS_DIR, "none")) + self.assertIsFile(os.path.join(settings.TRASH_DIR, "none.pdf")) + self.assertIsNotFile(os.path.join(settings.TRASH_DIR, "none_01.pdf")) # Create an identical document and ensure it is trashed under a new name document = Document() @@ -213,7 +208,7 @@ class TestFileHandling(DirectoriesMixin, TestCase): create_source_path_directory(document.source_path) Path(document.source_path).touch() document.delete() - self.assertEqual(os.path.isfile(settings.TRASH_DIR + "/none_01.pdf"), True) + self.assertIsFile(os.path.join(settings.TRASH_DIR, "none_01.pdf")) @override_settings(FILENAME_FORMAT="{correspondent}/{correspondent}") def test_document_delete_nofile(self): @@ -246,9 +241,9 @@ class TestFileHandling(DirectoriesMixin, TestCase): document.save() # Check proper handling of files - self.assertEqual(os.path.isdir(settings.ORIGINALS_DIR + "/test"), True) - self.assertEqual(os.path.isdir(settings.ORIGINALS_DIR + "/none"), True) - self.assertTrue(os.path.isfile(important_file)) + self.assertIsDir(os.path.join(settings.ORIGINALS_DIR, "test")) + self.assertIsDir(os.path.join(settings.ORIGINALS_DIR, "none")) + self.assertIsFile(important_file) @override_settings(FILENAME_FORMAT="{document_type} - {title}") def test_document_type(self): @@ -437,18 +432,17 @@ class TestFileHandling(DirectoriesMixin, TestCase): Path(document.source_path).touch() # Check proper handling of files - self.assertEqual(os.path.isdir(settings.ORIGINALS_DIR + "/none/none"), True) + self.assertIsDir(os.path.join(settings.ORIGINALS_DIR, "none/none")) pk = document.pk document.delete() - self.assertEqual( - os.path.isfile(settings.ORIGINALS_DIR + "/none/none/none.pdf"), - False, + self.assertIsNotFile( + os.path.join(settings.ORIGINALS_DIR, "none/none/none.pdf"), ) - self.assertEqual(os.path.isdir(settings.ORIGINALS_DIR + "/none/none"), False) - self.assertEqual(os.path.isdir(settings.ORIGINALS_DIR + "/none"), False) - self.assertEqual(os.path.isdir(settings.ORIGINALS_DIR), True) + self.assertIsNotDir(os.path.join(settings.ORIGINALS_DIR, "none/none")) + self.assertIsNotDir(os.path.join(settings.ORIGINALS_DIR, "none")) + self.assertIsDir(settings.ORIGINALS_DIR) @override_settings(FILENAME_FORMAT=None) def test_format_none(self): @@ -472,9 +466,9 @@ class TestFileHandling(DirectoriesMixin, TestCase): os.path.join(tmp, "notempty", "empty"), root=settings.ORIGINALS_DIR, ) - self.assertEqual(os.path.isdir(os.path.join(tmp, "notempty")), True) - self.assertEqual(os.path.isfile(os.path.join(tmp, "notempty", "file")), True) - self.assertEqual(os.path.isdir(os.path.join(tmp, "notempty", "empty")), False) + self.assertIsDir(os.path.join(tmp, "notempty")) + self.assertIsFile(os.path.join(tmp, "notempty", "file")) + self.assertIsNotDir(os.path.join(tmp, "notempty", "empty")) @override_settings(FILENAME_FORMAT="{created/[title]") def test_invalid_format(self): @@ -513,36 +507,36 @@ class TestFileHandling(DirectoriesMixin, TestCase): document.filename = "0000001.pdf" document.save() - self.assertTrue(os.path.isfile(document.source_path)) + self.assertIsFile(document.source_path) self.assertEqual(document.filename, "qwe.pdf") document2.filename = "0000002.pdf" document2.save() - self.assertTrue(os.path.isfile(document.source_path)) + self.assertIsFile(document.source_path) self.assertEqual(document2.filename, "qwe_01.pdf") # saving should not change the file names. document.save() - self.assertTrue(os.path.isfile(document.source_path)) + self.assertIsFile(document.source_path) self.assertEqual(document.filename, "qwe.pdf") document2.save() - self.assertTrue(os.path.isfile(document.source_path)) + self.assertIsFile(document.source_path) self.assertEqual(document2.filename, "qwe_01.pdf") document.delete() - self.assertFalse(os.path.isfile(document.source_path)) + self.assertIsNotFile(document.source_path) # filename free, should remove _01 suffix document2.save() - self.assertTrue(os.path.isfile(document.source_path)) + self.assertIsFile(document.source_path) self.assertEqual(document2.filename, "qwe.pdf") @override_settings(FILENAME_FORMAT="{title}") @@ -564,7 +558,7 @@ class TestFileHandling(DirectoriesMixin, TestCase): m.assert_not_called() -class TestFileHandlingWithArchive(DirectoriesMixin, TestCase): +class TestFileHandlingWithArchive(DirectoriesMixin, FileSystemAssertsMixin, TestCase): @override_settings(FILENAME_FORMAT=None) def test_create_no_format(self): original = os.path.join(settings.ORIGINALS_DIR, "0000001.pdf") @@ -579,10 +573,10 @@ class TestFileHandlingWithArchive(DirectoriesMixin, TestCase): archive_checksum="B", ) - self.assertTrue(os.path.isfile(original)) - self.assertTrue(os.path.isfile(archive)) - self.assertTrue(os.path.isfile(doc.source_path)) - self.assertTrue(os.path.isfile(doc.archive_path)) + self.assertIsFile(original) + self.assertIsFile(archive) + self.assertIsFile(doc.source_path) + self.assertIsFile(doc.archive_path) @override_settings(FILENAME_FORMAT="{correspondent}/{title}") def test_create_with_format(self): @@ -599,10 +593,10 @@ class TestFileHandlingWithArchive(DirectoriesMixin, TestCase): archive_filename="0000001.pdf", ) - self.assertFalse(os.path.isfile(original)) - self.assertFalse(os.path.isfile(archive)) - self.assertTrue(os.path.isfile(doc.source_path)) - self.assertTrue(os.path.isfile(doc.archive_path)) + self.assertIsNotFile(original) + self.assertIsNotFile(archive) + self.assertIsFile(doc.source_path) + self.assertIsFile(doc.archive_path) self.assertEqual( doc.source_path, os.path.join(settings.ORIGINALS_DIR, "none", "my_doc.pdf"), @@ -626,10 +620,10 @@ class TestFileHandlingWithArchive(DirectoriesMixin, TestCase): archive_filename="0000001.pdf", ) - self.assertTrue(os.path.isfile(original)) - self.assertFalse(os.path.isfile(archive)) - self.assertTrue(os.path.isfile(doc.source_path)) - self.assertFalse(os.path.isfile(doc.archive_path)) + self.assertIsFile(original) + self.assertIsNotFile(archive) + self.assertIsFile(doc.source_path) + self.assertIsNotFile(doc.archive_path) @override_settings(FILENAME_FORMAT="{correspondent}/{title}") def test_move_archive_exists(self): @@ -649,11 +643,11 @@ class TestFileHandlingWithArchive(DirectoriesMixin, TestCase): archive_filename="0000001.pdf", ) - self.assertFalse(os.path.isfile(original)) - self.assertFalse(os.path.isfile(archive)) - self.assertTrue(os.path.isfile(doc.source_path)) - self.assertTrue(os.path.isfile(doc.archive_path)) - self.assertTrue(os.path.isfile(existing_archive_file)) + self.assertIsNotFile(original) + self.assertIsNotFile(archive) + self.assertIsFile(doc.source_path) + self.assertIsFile(doc.archive_path) + self.assertIsFile(existing_archive_file) self.assertEqual(doc.archive_filename, "none/my_doc_01.pdf") @override_settings(FILENAME_FORMAT="{title}") @@ -675,8 +669,8 @@ class TestFileHandlingWithArchive(DirectoriesMixin, TestCase): self.assertEqual(doc.filename, "document.pdf") self.assertEqual(doc.archive_filename, "document.pdf") - self.assertTrue(os.path.isfile(doc.source_path)) - self.assertTrue(os.path.isfile(doc.archive_path)) + self.assertIsFile(doc.source_path) + self.assertIsFile(doc.archive_path) @override_settings(FILENAME_FORMAT="{title}") def test_move_archive_only(self): @@ -697,8 +691,8 @@ class TestFileHandlingWithArchive(DirectoriesMixin, TestCase): self.assertEqual(doc.filename, "document.pdf") self.assertEqual(doc.archive_filename, "document.pdf") - self.assertTrue(os.path.isfile(doc.source_path)) - self.assertTrue(os.path.isfile(doc.archive_path)) + self.assertIsFile(doc.source_path) + self.assertIsFile(doc.archive_path) @override_settings(FILENAME_FORMAT="{correspondent}/{title}") @mock.patch("documents.signals.handlers.os.rename") @@ -726,10 +720,10 @@ class TestFileHandlingWithArchive(DirectoriesMixin, TestCase): ) m.assert_called() - self.assertTrue(os.path.isfile(original)) - self.assertTrue(os.path.isfile(archive)) - self.assertTrue(os.path.isfile(doc.source_path)) - self.assertTrue(os.path.isfile(doc.archive_path)) + self.assertIsFile(original) + self.assertIsFile(archive) + self.assertIsFile(doc.source_path) + self.assertIsFile(doc.archive_path) @override_settings(FILENAME_FORMAT="{correspondent}/{title}") def test_move_file_gone(self): @@ -746,10 +740,10 @@ class TestFileHandlingWithArchive(DirectoriesMixin, TestCase): archive_checksum="B", ) - self.assertFalse(os.path.isfile(original)) - self.assertTrue(os.path.isfile(archive)) - self.assertFalse(os.path.isfile(doc.source_path)) - self.assertTrue(os.path.isfile(doc.archive_path)) + self.assertIsNotFile(original) + self.assertIsFile(archive) + self.assertIsNotFile(doc.source_path) + self.assertIsFile(doc.archive_path) @override_settings(FILENAME_FORMAT="{correspondent}/{title}") @mock.patch("documents.signals.handlers.os.rename") @@ -777,10 +771,10 @@ class TestFileHandlingWithArchive(DirectoriesMixin, TestCase): ) m.assert_called() - self.assertTrue(os.path.isfile(original)) - self.assertTrue(os.path.isfile(archive)) - self.assertTrue(os.path.isfile(doc.source_path)) - self.assertTrue(os.path.isfile(doc.archive_path)) + self.assertIsFile(original) + self.assertIsFile(archive) + self.assertIsFile(doc.source_path) + self.assertIsFile(doc.archive_path) @override_settings(FILENAME_FORMAT="") def test_archive_deleted(self): @@ -797,17 +791,17 @@ class TestFileHandlingWithArchive(DirectoriesMixin, TestCase): archive_filename="0000001.pdf", ) - self.assertTrue(os.path.isfile(original)) - self.assertTrue(os.path.isfile(archive)) - self.assertTrue(os.path.isfile(doc.source_path)) - self.assertTrue(os.path.isfile(doc.archive_path)) + self.assertIsFile(original) + self.assertIsFile(archive) + self.assertIsFile(doc.source_path) + self.assertIsFile(doc.archive_path) doc.delete() - self.assertFalse(os.path.isfile(original)) - self.assertFalse(os.path.isfile(archive)) - self.assertFalse(os.path.isfile(doc.source_path)) - self.assertFalse(os.path.isfile(doc.archive_path)) + self.assertIsNotFile(original) + self.assertIsNotFile(archive) + self.assertIsNotFile(doc.source_path) + self.assertIsNotFile(doc.archive_path) @override_settings(FILENAME_FORMAT="{title}") def test_archive_deleted2(self): @@ -833,15 +827,15 @@ class TestFileHandlingWithArchive(DirectoriesMixin, TestCase): checksum="C", ) - self.assertTrue(os.path.isfile(doc1.source_path)) - self.assertTrue(os.path.isfile(doc1.archive_path)) - self.assertTrue(os.path.isfile(doc2.source_path)) + self.assertIsFile(doc1.source_path) + self.assertIsFile(doc1.archive_path) + self.assertIsFile(doc2.source_path) doc2.delete() - self.assertTrue(os.path.isfile(doc1.source_path)) - self.assertTrue(os.path.isfile(doc1.archive_path)) - self.assertFalse(os.path.isfile(doc2.source_path)) + self.assertIsFile(doc1.source_path) + self.assertIsFile(doc1.archive_path) + self.assertIsNotFile(doc2.source_path) @override_settings(FILENAME_FORMAT="{correspondent}/{title}") def test_database_error(self): @@ -862,10 +856,10 @@ class TestFileHandlingWithArchive(DirectoriesMixin, TestCase): m.side_effect = DatabaseError() doc.save() - self.assertTrue(os.path.isfile(original)) - self.assertTrue(os.path.isfile(archive)) - self.assertTrue(os.path.isfile(doc.source_path)) - self.assertTrue(os.path.isfile(doc.archive_path)) + self.assertIsFile(original) + self.assertIsFile(archive) + self.assertIsFile(doc.source_path) + self.assertIsFile(doc.archive_path) class TestFilenameGeneration(DirectoriesMixin, TestCase): diff --git a/src/documents/tests/test_management.py b/src/documents/tests/test_management.py index 2844a0a30..d5b81a5e1 100644 --- a/src/documents/tests/test_management.py +++ b/src/documents/tests/test_management.py @@ -13,13 +13,14 @@ from documents.file_handling import generate_filename from documents.models import Document from documents.tasks import update_document_archive_file from documents.tests.utils import DirectoriesMixin +from documents.tests.utils import FileSystemAssertsMixin sample_file = os.path.join(os.path.dirname(__file__), "samples", "simple.pdf") @override_settings(FILENAME_FORMAT="{correspondent}/{title}") -class TestArchiver(DirectoriesMixin, TestCase): +class TestArchiver(DirectoriesMixin, FileSystemAssertsMixin, TestCase): def make_models(self): return Document.objects.create( checksum="A", @@ -52,8 +53,8 @@ class TestArchiver(DirectoriesMixin, TestCase): self.assertIsNotNone(doc.checksum) self.assertIsNotNone(doc.archive_checksum) - self.assertTrue(os.path.isfile(doc.archive_path)) - self.assertTrue(os.path.isfile(doc.source_path)) + self.assertIsFile(doc.archive_path) + self.assertIsFile(doc.source_path) self.assertTrue(filecmp.cmp(sample_file, doc.source_path)) self.assertEqual(doc.archive_filename, "none/A.pdf") @@ -70,7 +71,7 @@ class TestArchiver(DirectoriesMixin, TestCase): self.assertIsNotNone(doc.checksum) self.assertIsNone(doc.archive_checksum) self.assertIsNone(doc.archive_filename) - self.assertTrue(os.path.isfile(doc.source_path)) + self.assertIsFile(doc.source_path) @override_settings(FILENAME_FORMAT="{title}") def test_naming_priorities(self): @@ -104,7 +105,7 @@ class TestArchiver(DirectoriesMixin, TestCase): self.assertEqual(doc2.archive_filename, "document_01.pdf") -class TestDecryptDocuments(TestCase): +class TestDecryptDocuments(FileSystemAssertsMixin, TestCase): @override_settings( ORIGINALS_DIR=os.path.join(os.path.dirname(__file__), "samples", "originals"), THUMBNAIL_DIR=os.path.join(os.path.dirname(__file__), "samples", "thumb"), @@ -161,10 +162,10 @@ class TestDecryptDocuments(TestCase): self.assertEqual(doc.storage_type, Document.STORAGE_TYPE_UNENCRYPTED) 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}.webp"))) - self.assertTrue(os.path.isfile(doc.thumbnail_path)) + self.assertIsFile(os.path.join(originals_dir, "0000004.pdf")) + self.assertIsFile(doc.source_path) + self.assertIsFile(os.path.join(thumb_dir, f"{doc.id:07}.webp")) + self.assertIsFile(doc.thumbnail_path) with doc.source_file as f: checksum = hashlib.md5(f.read()).hexdigest() @@ -183,7 +184,7 @@ class TestMakeIndex(TestCase): m.assert_called_once() -class TestRenamer(DirectoriesMixin, TestCase): +class TestRenamer(DirectoriesMixin, FileSystemAssertsMixin, TestCase): @override_settings(FILENAME_FORMAT="") def test_rename(self): doc = Document.objects.create(title="test", mime_type="image/jpeg") @@ -201,10 +202,10 @@ class TestRenamer(DirectoriesMixin, TestCase): self.assertEqual(doc2.filename, "none/test.jpg") self.assertEqual(doc2.archive_filename, "none/test.pdf") - self.assertFalse(os.path.isfile(doc.source_path)) - self.assertFalse(os.path.isfile(doc.archive_path)) - self.assertTrue(os.path.isfile(doc2.source_path)) - self.assertTrue(os.path.isfile(doc2.archive_path)) + self.assertIsNotFile(doc.source_path) + self.assertIsNotFile(doc.archive_path) + self.assertIsFile(doc2.source_path) + self.assertIsFile(doc2.archive_path) class TestCreateClassifier(TestCase): diff --git a/src/documents/tests/test_management_exporter.py b/src/documents/tests/test_management_exporter.py index 484065810..42f544f55 100644 --- a/src/documents/tests/test_management_exporter.py +++ b/src/documents/tests/test_management_exporter.py @@ -23,10 +23,11 @@ from documents.models import User from documents.sanity_checker import check_sanity from documents.settings import EXPORTER_FILE_NAME from documents.tests.utils import DirectoriesMixin +from documents.tests.utils import FileSystemAssertsMixin from documents.tests.utils import paperless_environment -class TestExportImport(DirectoriesMixin, TestCase): +class TestExportImport(DirectoriesMixin, FileSystemAssertsMixin, TestCase): def setUp(self) -> None: self.target = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, self.target) @@ -145,7 +146,7 @@ class TestExportImport(DirectoriesMixin, TestCase): 4, ) - self.assertTrue(os.path.exists(os.path.join(self.target, "manifest.json"))) + self.assertIsFile(os.path.join(self.target, "manifest.json")) self.assertEqual( self._get_document_from_manifest(manifest, self.d1.id)["fields"]["title"], @@ -170,13 +171,11 @@ class TestExportImport(DirectoriesMixin, TestCase): self.target, element[document_exporter.EXPORTER_FILE_NAME], ) - self.assertTrue(os.path.exists(fname)) - self.assertTrue( - os.path.exists( - os.path.join( - self.target, - element[document_exporter.EXPORTER_THUMBNAIL_NAME], - ), + self.assertIsFile(fname) + self.assertIsFile( + os.path.join( + self.target, + element[document_exporter.EXPORTER_THUMBNAIL_NAME], ), ) @@ -194,7 +193,7 @@ class TestExportImport(DirectoriesMixin, TestCase): self.target, element[document_exporter.EXPORTER_ARCHIVE_NAME], ) - self.assertTrue(os.path.exists(fname)) + self.assertIsFile(fname) with open(fname, "rb") as f: checksum = hashlib.md5(f.read()).hexdigest() @@ -247,7 +246,7 @@ class TestExportImport(DirectoriesMixin, TestCase): ) self._do_export() - self.assertTrue(os.path.exists(os.path.join(self.target, "manifest.json"))) + self.assertIsFile(os.path.join(self.target, "manifest.json")) st_mtime_1 = os.stat(os.path.join(self.target, "manifest.json")).st_mtime @@ -257,7 +256,7 @@ class TestExportImport(DirectoriesMixin, TestCase): self._do_export() m.assert_not_called() - self.assertTrue(os.path.exists(os.path.join(self.target, "manifest.json"))) + self.assertIsFile(os.path.join(self.target, "manifest.json")) st_mtime_2 = os.stat(os.path.join(self.target, "manifest.json")).st_mtime Path(self.d1.source_path).touch() @@ -269,7 +268,7 @@ class TestExportImport(DirectoriesMixin, TestCase): self.assertEqual(m.call_count, 1) st_mtime_3 = os.stat(os.path.join(self.target, "manifest.json")).st_mtime - self.assertTrue(os.path.exists(os.path.join(self.target, "manifest.json"))) + self.assertIsFile(os.path.join(self.target, "manifest.json")) self.assertNotEqual(st_mtime_1, st_mtime_2) self.assertNotEqual(st_mtime_2, st_mtime_3) @@ -283,7 +282,7 @@ class TestExportImport(DirectoriesMixin, TestCase): self._do_export() - self.assertTrue(os.path.exists(os.path.join(self.target, "manifest.json"))) + self.assertIsFile(os.path.join(self.target, "manifest.json")) with mock.patch( "documents.management.commands.document_exporter.shutil.copy2", @@ -291,7 +290,7 @@ class TestExportImport(DirectoriesMixin, TestCase): self._do_export() m.assert_not_called() - self.assertTrue(os.path.exists(os.path.join(self.target, "manifest.json"))) + self.assertIsFile(os.path.join(self.target, "manifest.json")) self.d2.checksum = "asdfasdgf3" self.d2.save() @@ -302,7 +301,7 @@ class TestExportImport(DirectoriesMixin, TestCase): self._do_export(compare_checksums=True) self.assertEqual(m.call_count, 1) - self.assertTrue(os.path.exists(os.path.join(self.target, "manifest.json"))) + self.assertIsFile(os.path.join(self.target, "manifest.json")) def test_update_export_deleted_document(self): shutil.rmtree(os.path.join(self.dirs.media_dir, "documents")) @@ -315,10 +314,8 @@ class TestExportImport(DirectoriesMixin, TestCase): self.assertTrue(len(manifest), 7) doc_from_manifest = self._get_document_from_manifest(manifest, self.d3.id) - self.assertTrue( - os.path.isfile( - os.path.join(self.target, doc_from_manifest[EXPORTER_FILE_NAME]), - ), + self.assertIsFile( + os.path.join(self.target, doc_from_manifest[EXPORTER_FILE_NAME]), ) self.d3.delete() @@ -329,17 +326,13 @@ class TestExportImport(DirectoriesMixin, TestCase): manifest, self.d3.id, ) - self.assertTrue( - os.path.isfile( - os.path.join(self.target, doc_from_manifest[EXPORTER_FILE_NAME]), - ), + self.assertIsFile( + os.path.join(self.target, doc_from_manifest[EXPORTER_FILE_NAME]), ) manifest = self._do_export(delete=True) - self.assertFalse( - os.path.isfile( - os.path.join(self.target, doc_from_manifest[EXPORTER_FILE_NAME]), - ), + self.assertIsNotFile( + os.path.join(self.target, doc_from_manifest[EXPORTER_FILE_NAME]), ) self.assertTrue(len(manifest), 6) @@ -353,20 +346,20 @@ class TestExportImport(DirectoriesMixin, TestCase): ) m = self._do_export(use_filename_format=True) - self.assertTrue(os.path.isfile(os.path.join(self.target, "wow1", "c.pdf"))) + self.assertIsFile(os.path.join(self.target, "wow1", "c.pdf")) - self.assertTrue(os.path.exists(os.path.join(self.target, "manifest.json"))) + self.assertIsFile(os.path.join(self.target, "manifest.json")) self.d1.title = "new_title" self.d1.save() self._do_export(use_filename_format=True, delete=True) - self.assertFalse(os.path.isfile(os.path.join(self.target, "wow1", "c.pdf"))) - self.assertFalse(os.path.isdir(os.path.join(self.target, "wow1"))) - self.assertTrue(os.path.isfile(os.path.join(self.target, "new_title", "c.pdf"))) - self.assertTrue(os.path.exists(os.path.join(self.target, "manifest.json"))) - self.assertTrue(os.path.isfile(os.path.join(self.target, "wow2", "none.pdf"))) - self.assertTrue( - os.path.isfile(os.path.join(self.target, "wow2", "none_01.pdf")), + self.assertIsNotFile(os.path.join(self.target, "wow1", "c.pdf")) + self.assertIsNotDir(os.path.join(self.target, "wow1")) + self.assertIsFile(os.path.join(self.target, "new_title", "c.pdf")) + self.assertIsFile(os.path.join(self.target, "manifest.json")) + self.assertIsFile(os.path.join(self.target, "wow2", "none.pdf")) + self.assertIsFile( + (os.path.join(self.target, "wow2", "none_01.pdf")), ) def test_export_missing_files(self): @@ -407,7 +400,7 @@ class TestExportImport(DirectoriesMixin, TestCase): f"export-{timezone.localdate().isoformat()}.zip", ) - self.assertTrue(os.path.isfile(expected_file)) + self.assertIsFile(expected_file) with ZipFile(expected_file) as zip: self.assertEqual(len(zip.namelist()), 11) @@ -444,7 +437,7 @@ class TestExportImport(DirectoriesMixin, TestCase): f"export-{timezone.localdate().isoformat()}.zip", ) - self.assertTrue(os.path.isfile(expected_file)) + self.assertIsFile(expected_file) with ZipFile(expected_file) as zip: # Extras are from the directories, which also appear in the listing diff --git a/src/documents/tests/test_management_thumbnails.py b/src/documents/tests/test_management_thumbnails.py index 48821725b..c66e0aa0a 100644 --- a/src/documents/tests/test_management_thumbnails.py +++ b/src/documents/tests/test_management_thumbnails.py @@ -7,9 +7,10 @@ from django.test import TestCase from documents.management.commands.document_thumbnails import _process_document from documents.models import Document from documents.tests.utils import DirectoriesMixin +from documents.tests.utils import FileSystemAssertsMixin -class TestMakeThumbnails(DirectoriesMixin, TestCase): +class TestMakeThumbnails(DirectoriesMixin, FileSystemAssertsMixin, TestCase): def make_models(self): self.d1 = Document.objects.create( checksum="A", @@ -40,9 +41,9 @@ class TestMakeThumbnails(DirectoriesMixin, TestCase): self.make_models() def test_process_document(self): - self.assertFalse(os.path.isfile(self.d1.thumbnail_path)) + self.assertIsNotFile(self.d1.thumbnail_path) _process_document(self.d1.id) - self.assertTrue(os.path.isfile(self.d1.thumbnail_path)) + self.assertIsFile(self.d1.thumbnail_path) @mock.patch("documents.management.commands.document_thumbnails.shutil.move") def test_process_document_invalid_mime_type(self, m): @@ -54,15 +55,15 @@ class TestMakeThumbnails(DirectoriesMixin, TestCase): m.assert_not_called() def test_command(self): - self.assertFalse(os.path.isfile(self.d1.thumbnail_path)) - self.assertFalse(os.path.isfile(self.d2.thumbnail_path)) + self.assertIsNotFile(self.d1.thumbnail_path) + self.assertIsNotFile(self.d2.thumbnail_path) call_command("document_thumbnails") - self.assertTrue(os.path.isfile(self.d1.thumbnail_path)) - self.assertTrue(os.path.isfile(self.d2.thumbnail_path)) + self.assertTrue(self.d1.thumbnail_path) + self.assertTrue(self.d2.thumbnail_path) def test_command_documentid(self): - self.assertFalse(os.path.isfile(self.d1.thumbnail_path)) - self.assertFalse(os.path.isfile(self.d2.thumbnail_path)) + self.assertIsNotFile(self.d1.thumbnail_path) + self.assertIsNotFile(self.d2.thumbnail_path) call_command("document_thumbnails", "-d", f"{self.d1.id}") - self.assertTrue(os.path.isfile(self.d1.thumbnail_path)) - self.assertFalse(os.path.isfile(self.d2.thumbnail_path)) + self.assertIsFile(self.d1.thumbnail_path) + self.assertIsNotFile(self.d2.thumbnail_path) diff --git a/src/documents/tests/test_migration_archive_files.py b/src/documents/tests/test_migration_archive_files.py index fb9b9e1e3..acf8761c7 100644 --- a/src/documents/tests/test_migration_archive_files.py +++ b/src/documents/tests/test_migration_archive_files.py @@ -8,6 +8,7 @@ from django.conf import settings from django.test import override_settings from documents.parsers import ParseError from documents.tests.utils import DirectoriesMixin +from documents.tests.utils import FileSystemAssertsMixin from documents.tests.utils import TestMigrations @@ -112,7 +113,7 @@ simple_png2 = os.path.join(os.path.dirname(__file__), "examples", "no-text.png") @override_settings(FILENAME_FORMAT="") -class TestMigrateArchiveFiles(DirectoriesMixin, TestMigrations): +class TestMigrateArchiveFiles(DirectoriesMixin, FileSystemAssertsMixin, TestMigrations): migrate_from = "1011_auto_20210101_2340" migrate_to = "1012_fix_archive_files" @@ -189,7 +190,7 @@ class TestMigrateArchiveFiles(DirectoriesMixin, TestMigrations): for doc in Document.objects.all(): if doc.archive_checksum: self.assertIsNotNone(doc.archive_filename) - self.assertTrue(os.path.isfile(archive_path_new(doc))) + self.assertIsFile(archive_path_new(doc)) else: self.assertIsNone(doc.archive_filename) @@ -198,7 +199,7 @@ class TestMigrateArchiveFiles(DirectoriesMixin, TestMigrations): self.assertEqual(original_checksum, doc.checksum) if doc.archive_checksum: - self.assertTrue(os.path.isfile(archive_path_new(doc))) + self.assertIsFile(archive_path_new(doc)) with open(archive_path_new(doc), "rb") as f: archive_checksum = hashlib.md5(f.read()).hexdigest() self.assertEqual(archive_checksum, doc.archive_checksum) @@ -448,7 +449,11 @@ class TestMigrateArchiveFilesErrors(DirectoriesMixin, TestMigrations): @override_settings(FILENAME_FORMAT="") -class TestMigrateArchiveFilesBackwards(DirectoriesMixin, TestMigrations): +class TestMigrateArchiveFilesBackwards( + DirectoriesMixin, + FileSystemAssertsMixin, + TestMigrations, +): migrate_from = "1012_fix_archive_files" migrate_to = "1011_auto_20210101_2340" @@ -488,13 +493,13 @@ class TestMigrateArchiveFilesBackwards(DirectoriesMixin, TestMigrations): for doc in Document.objects.all(): if doc.archive_checksum: - self.assertTrue(os.path.isfile(archive_path_old(doc))) + self.assertIsFile(archive_path_old(doc)) with open(source_path(doc), "rb") as f: original_checksum = hashlib.md5(f.read()).hexdigest() self.assertEqual(original_checksum, doc.checksum) if doc.archive_checksum: - self.assertTrue(os.path.isfile(archive_path_old(doc))) + self.assertIsFile(archive_path_old(doc)) with open(archive_path_old(doc), "rb") as f: archive_checksum = hashlib.md5(f.read()).hexdigest() self.assertEqual(archive_checksum, doc.archive_checksum) diff --git a/src/documents/tests/test_tasks.py b/src/documents/tests/test_tasks.py index 8b104ab1d..2d27f93ec 100644 --- a/src/documents/tests/test_tasks.py +++ b/src/documents/tests/test_tasks.py @@ -13,6 +13,7 @@ from documents.sanity_checker import SanityCheckFailedException from documents.sanity_checker import SanityCheckMessages from documents.tests.test_classifier import dummy_preprocess from documents.tests.utils import DirectoriesMixin +from documents.tests.utils import FileSystemAssertsMixin class TestIndexReindex(DirectoriesMixin, TestCase): @@ -41,7 +42,7 @@ class TestIndexReindex(DirectoriesMixin, TestCase): tasks.index_optimize() -class TestClassifier(DirectoriesMixin, TestCase): +class TestClassifier(DirectoriesMixin, FileSystemAssertsMixin, TestCase): @mock.patch("documents.tasks.load_classifier") def test_train_classifier_no_auto_matching(self, load_classifier): tasks.train_classifier() @@ -53,7 +54,7 @@ class TestClassifier(DirectoriesMixin, TestCase): Tag.objects.create(matching_algorithm=Tag.MATCH_AUTO, name="test") tasks.train_classifier() load_classifier.assert_called_once() - self.assertFalse(os.path.isfile(settings.MODEL_FILE)) + self.assertIsNotFile(settings.MODEL_FILE) @mock.patch("documents.tasks.load_classifier") def test_train_classifier_with_auto_type(self, load_classifier): @@ -61,7 +62,7 @@ class TestClassifier(DirectoriesMixin, TestCase): DocumentType.objects.create(matching_algorithm=Tag.MATCH_AUTO, name="test") tasks.train_classifier() load_classifier.assert_called_once() - self.assertFalse(os.path.isfile(settings.MODEL_FILE)) + self.assertIsNotFile(settings.MODEL_FILE) @mock.patch("documents.tasks.load_classifier") def test_train_classifier_with_auto_correspondent(self, load_classifier): @@ -69,12 +70,12 @@ class TestClassifier(DirectoriesMixin, TestCase): Correspondent.objects.create(matching_algorithm=Tag.MATCH_AUTO, name="test") tasks.train_classifier() load_classifier.assert_called_once() - self.assertFalse(os.path.isfile(settings.MODEL_FILE)) + self.assertIsNotFile(settings.MODEL_FILE) def test_train_classifier(self): c = Correspondent.objects.create(matching_algorithm=Tag.MATCH_AUTO, name="test") doc = Document.objects.create(correspondent=c, content="test", title="test") - self.assertFalse(os.path.isfile(settings.MODEL_FILE)) + self.assertIsNotFile(settings.MODEL_FILE) with mock.patch( "documents.classifier.DocumentClassifier.preprocess_content", @@ -82,18 +83,18 @@ class TestClassifier(DirectoriesMixin, TestCase): pre_proc_mock.side_effect = dummy_preprocess tasks.train_classifier() - self.assertTrue(os.path.isfile(settings.MODEL_FILE)) + self.assertIsFile(settings.MODEL_FILE) mtime = os.stat(settings.MODEL_FILE).st_mtime tasks.train_classifier() - self.assertTrue(os.path.isfile(settings.MODEL_FILE)) + self.assertIsFile(settings.MODEL_FILE) mtime2 = os.stat(settings.MODEL_FILE).st_mtime self.assertEqual(mtime, mtime2) doc.content = "test2" doc.save() tasks.train_classifier() - self.assertTrue(os.path.isfile(settings.MODEL_FILE)) + self.assertIsFile(settings.MODEL_FILE) mtime3 = os.stat(settings.MODEL_FILE).st_mtime self.assertNotEqual(mtime2, mtime3) diff --git a/src/documents/tests/utils.py b/src/documents/tests/utils.py index b2ec0d024..59e21c774 100644 --- a/src/documents/tests/utils.py +++ b/src/documents/tests/utils.py @@ -3,6 +3,9 @@ import shutil import tempfile from collections import namedtuple from contextlib import contextmanager +from os import PathLike +from pathlib import Path +from typing import Union from unittest import mock from django.apps import apps @@ -87,6 +90,24 @@ class DirectoriesMixin: remove_dirs(self.dirs) +class FileSystemAssertsMixin: + def assertIsFile(self, path: Union[PathLike, str]): + if not Path(path).resolve().is_file(): + raise AssertionError(f"File does not exist: {path}") + + def assertIsNotFile(self, path: Union[PathLike, str]): + if Path(path).resolve().is_file(): + raise AssertionError(f"File does exist: {path}") + + def assertIsDir(self, path: Union[PathLike, str]): + if not Path(path).resolve().is_dir(): + raise AssertionError(f"Dir does not exist: {path}") + + def assertIsNotDir(self, path: Union[PathLike, str]): + if Path(path).resolve().is_dir(): + raise AssertionError(f"Dir does exist: {path}") + + class ConsumerProgressMixin: def setUp(self) -> None: self.send_progress_patcher = mock.patch( diff --git a/src/paperless_mail/tests/test_mail.py b/src/paperless_mail/tests/test_mail.py index cd1001861..fb3a8e071 100644 --- a/src/paperless_mail/tests/test_mail.py +++ b/src/paperless_mail/tests/test_mail.py @@ -14,6 +14,7 @@ from django.db import DatabaseError from django.test import TestCase from documents.models import Correspondent from documents.tests.utils import DirectoriesMixin +from documents.tests.utils import FileSystemAssertsMixin from imap_tools import EmailAddress from imap_tools import FolderInfo from imap_tools import MailboxFolderSelectError @@ -241,7 +242,7 @@ def fake_magic_from_buffer(buffer, mime=False): @mock.patch("paperless_mail.mail.magic.from_buffer", fake_magic_from_buffer) -class TestMail(DirectoriesMixin, TestCase): +class TestMail(DirectoriesMixin, FileSystemAssertsMixin, TestCase): def setUp(self): patcher = mock.patch("paperless_mail.mail.MailBox") m = patcher.start() @@ -389,12 +390,12 @@ class TestMail(DirectoriesMixin, TestCase): args1, kwargs1 = self.async_task.call_args_list[0] args2, kwargs2 = self.async_task.call_args_list[1] - self.assertTrue(os.path.isfile(kwargs1["path"]), kwargs1["path"]) + self.assertIsFile(kwargs1["path"]) self.assertEqual(kwargs1["override_title"], "file_0") self.assertEqual(kwargs1["override_filename"], "file_0.pdf") - self.assertTrue(os.path.isfile(kwargs2["path"]), kwargs1["path"]) + self.assertIsFile(kwargs2["path"]) self.assertEqual(kwargs2["override_title"], "file_1") self.assertEqual(kwargs2["override_filename"], "file_1.pdf") @@ -435,7 +436,7 @@ class TestMail(DirectoriesMixin, TestCase): self.assertEqual(self.async_task.call_count, 1) args, kwargs = self.async_task.call_args - self.assertTrue(os.path.isfile(kwargs["path"]), kwargs["path"]) + self.assertIsFile(kwargs["path"]) self.assertEqual(kwargs["override_filename"], "f1.pdf") def test_handle_disposition(self): diff --git a/src/paperless_mail/tests/test_parsers.py b/src/paperless_mail/tests/test_parsers.py index 809a1192f..3515cfbf4 100644 --- a/src/paperless_mail/tests/test_parsers.py +++ b/src/paperless_mail/tests/test_parsers.py @@ -4,10 +4,11 @@ from unittest import mock from django.test import TestCase from documents.parsers import ParseError +from documents.tests.utils import FileSystemAssertsMixin from paperless_mail.parsers import MailDocumentParser -class TestParser(TestCase): +class TestParser(FileSystemAssertsMixin, TestCase): SAMPLE_FILES = os.path.join(os.path.dirname(__file__), "samples") def setUp(self) -> None: @@ -331,7 +332,7 @@ class TestParser(TestCase): ) @mock.patch("paperless_mail.parsers.MailDocumentParser.generate_pdf") - def test_parse_simple_eml(self, n): + def test_parse_simple_eml(self, m: mock.MagicMock): """ GIVEN: - Fresh start @@ -361,8 +362,8 @@ class TestParser(TestCase): self.parser.date, ) - # Just check if file exists, the unittest for generate_pdf() goes deeper. - self.assertTrue(os.path.isfile(self.parser.archive_path)) + # Just check if tried to generate archive, the unittest for generate_pdf() goes deeper. + m.assert_called() @mock.patch("paperless_mail.parsers.parser.from_buffer") def test_tika_parse_unsuccessful(self, mock_from_buffer: mock.MagicMock): @@ -494,7 +495,7 @@ class TestParser(TestCase): mock_response.content = b"Content" mock_post.return_value = mock_response pdf_path = self.parser.generate_pdf(os.path.join(self.SAMPLE_FILES, "html.eml")) - self.assertTrue(os.path.isfile(pdf_path)) + self.assertIsFile(pdf_path) mock_generate_pdf_from_mail.assert_called_once_with( self.parser.get_parsed(None), diff --git a/src/paperless_mail/tests/test_parsers_live.py b/src/paperless_mail/tests/test_parsers_live.py index 90c172d07..1ff42b6dd 100644 --- a/src/paperless_mail/tests/test_parsers_live.py +++ b/src/paperless_mail/tests/test_parsers_live.py @@ -7,13 +7,14 @@ from urllib.request import urlopen import pytest from django.test import TestCase from documents.parsers import run_convert +from documents.tests.utils import FileSystemAssertsMixin from imagehash import average_hash from paperless_mail.parsers import MailDocumentParser from pdfminer.high_level import extract_text from PIL import Image -class TestParserLive(TestCase): +class TestParserLive(FileSystemAssertsMixin, TestCase): SAMPLE_FILES = os.path.join(os.path.dirname(__file__), "samples") def setUp(self) -> None: @@ -85,7 +86,7 @@ class TestParserLive(TestCase): os.path.join(self.SAMPLE_FILES, "simple_text.eml"), "message/rfc822", ) - self.assertTrue(os.path.isfile(thumb)) + self.assertIsFile(thumb) expected = os.path.join(self.SAMPLE_FILES, "simple_text.eml.pdf.webp") @@ -161,7 +162,7 @@ class TestParserLive(TestCase): self.parser.generate_pdf, [os.path.join(self.SAMPLE_FILES, "html.eml")], ) - self.assertTrue(os.path.isfile(pdf_path)) + self.assertIsFile(pdf_path) extracted = extract_text(pdf_path) expected = ( @@ -232,7 +233,7 @@ class TestParserLive(TestCase): output_file=converted, logging_group=None, ) - self.assertTrue(os.path.isfile(converted)) + self.assertIsFile(converted) thumb_hash = self.imagehash(converted) # The created pdf is not reproducible. But the converted image should always look the same. @@ -337,7 +338,7 @@ class TestParserLive(TestCase): output_file=converted, logging_group=None, ) - self.assertTrue(os.path.isfile(converted)) + self.assertIsFile(converted) thumb_hash = self.imagehash(converted) # The created pdf is not reproducible. But the converted image should always look the same. diff --git a/src/paperless_tesseract/tests/test_parser.py b/src/paperless_tesseract/tests/test_parser.py index d22ce26a7..94b72a0ee 100644 --- a/src/paperless_tesseract/tests/test_parser.py +++ b/src/paperless_tesseract/tests/test_parser.py @@ -10,6 +10,7 @@ from django.test import TestCase from documents.parsers import ParseError from documents.parsers import run_convert from documents.tests.utils import DirectoriesMixin +from documents.tests.utils import FileSystemAssertsMixin from paperless_tesseract.parsers import post_process_text from paperless_tesseract.parsers import RasterisedDocumentParser @@ -36,7 +37,7 @@ class FakeImageFile(ContextManager): return os.path.basename(self.fname) -class TestParser(DirectoriesMixin, TestCase): +class TestParser(DirectoriesMixin, FileSystemAssertsMixin, TestCase): SAMPLE_FILES = os.path.join(os.path.dirname(__file__), "samples") @@ -88,7 +89,7 @@ class TestParser(DirectoriesMixin, TestCase): os.path.join(self.SAMPLE_FILES, "simple-digital.pdf"), "application/pdf", ) - self.assertTrue(os.path.isfile(thumb)) + self.assertIsFile(thumb) @mock.patch("documents.parsers.run_convert") def test_thumbnail_fallback(self, m): @@ -105,7 +106,7 @@ class TestParser(DirectoriesMixin, TestCase): os.path.join(self.SAMPLE_FILES, "simple-digital.pdf"), "application/pdf", ) - self.assertTrue(os.path.isfile(thumb)) + self.assertIsFile(thumb) def test_thumbnail_encrypted(self): parser = RasterisedDocumentParser(uuid.uuid4()) @@ -113,7 +114,7 @@ class TestParser(DirectoriesMixin, TestCase): os.path.join(self.SAMPLE_FILES, "encrypted.pdf"), "application/pdf", ) - self.assertTrue(os.path.isfile(thumb)) + self.assertIsFile(thumb) def test_get_dpi(self): parser = RasterisedDocumentParser(None) @@ -132,7 +133,7 @@ class TestParser(DirectoriesMixin, TestCase): "application/pdf", ) - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertContainsStrings(parser.get_text(), ["This is a test document."]) @@ -144,7 +145,7 @@ class TestParser(DirectoriesMixin, TestCase): "application/pdf", ) - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertContainsStrings( parser.get_text(), @@ -225,7 +226,7 @@ class TestParser(DirectoriesMixin, TestCase): parser.parse(os.path.join(self.SAMPLE_FILES, "simple.png"), "image/png") - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertContainsStrings(parser.get_text(), ["This is a test document."]) @@ -241,7 +242,7 @@ class TestParser(DirectoriesMixin, TestCase): parser.parse(dest_file, "image/png") - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertContainsStrings(parser.get_text(), ["This is a test document."]) @@ -273,7 +274,7 @@ class TestParser(DirectoriesMixin, TestCase): parser.parse(os.path.join(self.SAMPLE_FILES, "simple-no-dpi.png"), "image/png") - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertContainsStrings( parser.get_text().lower(), @@ -286,7 +287,7 @@ class TestParser(DirectoriesMixin, TestCase): os.path.join(self.SAMPLE_FILES, "multi-page-digital.pdf"), "application/pdf", ) - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertContainsStrings( parser.get_text().lower(), ["page 1", "page 2", "page 3"], @@ -299,7 +300,7 @@ class TestParser(DirectoriesMixin, TestCase): os.path.join(self.SAMPLE_FILES, "multi-page-digital.pdf"), "application/pdf", ) - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertContainsStrings( parser.get_text().lower(), ["page 1", "page 2", "page 3"], @@ -312,7 +313,7 @@ class TestParser(DirectoriesMixin, TestCase): os.path.join(self.SAMPLE_FILES, "multi-page-digital.pdf"), "application/pdf", ) - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertContainsStrings( parser.get_text().lower(), ["page 1", "page 2", "page 3"], @@ -325,7 +326,7 @@ class TestParser(DirectoriesMixin, TestCase): os.path.join(self.SAMPLE_FILES, "multi-page-digital.pdf"), "application/pdf", ) - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertContainsStrings( parser.get_text().lower(), ["page 1", "page 2", "page 3"], @@ -338,7 +339,7 @@ class TestParser(DirectoriesMixin, TestCase): os.path.join(self.SAMPLE_FILES, "multi-page-images.pdf"), "application/pdf", ) - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertContainsStrings( parser.get_text().lower(), ["page 1", "page 2", "page 3"], @@ -362,7 +363,7 @@ class TestParser(DirectoriesMixin, TestCase): os.path.join(self.SAMPLE_FILES, "multi-page-images.pdf"), "application/pdf", ) - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertContainsStrings(parser.get_text().lower(), ["page 1", "page 2"]) self.assertNotIn("page 3", parser.get_text().lower()) @@ -384,7 +385,7 @@ class TestParser(DirectoriesMixin, TestCase): os.path.join(self.SAMPLE_FILES, "multi-page-images.pdf"), "application/pdf", ) - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertContainsStrings(parser.get_text().lower(), ["page 1"]) self.assertNotIn("page 2", parser.get_text().lower()) self.assertNotIn("page 3", parser.get_text().lower()) @@ -455,7 +456,7 @@ class TestParser(DirectoriesMixin, TestCase): "application/pdf", ) self.assertIsNotNone(parser.archive_path) - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertContainsStrings( parser.get_text().lower(), ["page 1", "page 2", "page 3", "page 4", "page 5", "page 6"], @@ -486,7 +487,7 @@ class TestParser(DirectoriesMixin, TestCase): "application/pdf", ) self.assertIsNotNone(parser.archive_path) - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertContainsStrings( parser.get_text().lower(), [ @@ -556,7 +557,7 @@ class TestParser(DirectoriesMixin, TestCase): os.path.join(self.SAMPLE_FILES, "multi-page-images.tiff"), "image/tiff", ) - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertContainsStrings( parser.get_text().lower(), ["page 1", "page 2", "page 3"], @@ -580,7 +581,7 @@ class TestParser(DirectoriesMixin, TestCase): tmp_file.name, "image/tiff", ) - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertContainsStrings( parser.get_text().lower(), ["page 1", "page 2", "page 3"], @@ -608,7 +609,7 @@ class TestParser(DirectoriesMixin, TestCase): tmp_file.name, "image/tiff", ) - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertContainsStrings( parser.get_text().lower(), ["page 1", "page 2", "page 3"], @@ -689,40 +690,40 @@ class TestParser(DirectoriesMixin, TestCase): self.assertIn("ةﯾﻠﺧﺎدﻻ ةرازو", parser.get_text()) -class TestParserFileTypes(DirectoriesMixin, TestCase): +class TestParserFileTypes(DirectoriesMixin, FileSystemAssertsMixin, TestCase): SAMPLE_FILES = os.path.join(os.path.dirname(__file__), "samples") def test_bmp(self): parser = RasterisedDocumentParser(None) parser.parse(os.path.join(self.SAMPLE_FILES, "simple.bmp"), "image/bmp") - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertIn("this is a test document", parser.get_text().lower()) def test_jpg(self): parser = RasterisedDocumentParser(None) parser.parse(os.path.join(self.SAMPLE_FILES, "simple.jpg"), "image/jpeg") - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertIn("this is a test document", parser.get_text().lower()) @override_settings(OCR_IMAGE_DPI=200) def test_gif(self): parser = RasterisedDocumentParser(None) parser.parse(os.path.join(self.SAMPLE_FILES, "simple.gif"), "image/gif") - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertIn("this is a test document", parser.get_text().lower()) def test_tiff(self): parser = RasterisedDocumentParser(None) parser.parse(os.path.join(self.SAMPLE_FILES, "simple.tif"), "image/tiff") - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) self.assertIn("this is a test document", parser.get_text().lower()) @override_settings(OCR_IMAGE_DPI=72) def test_webp(self): parser = RasterisedDocumentParser(None) parser.parse(os.path.join(self.SAMPLE_FILES, "document.webp"), "image/webp") - self.assertTrue(os.path.isfile(parser.archive_path)) + self.assertIsFile(parser.archive_path) # OCR consistent mangles this space, oh well self.assertIn( "this is awebp document, created 11/14/2022.", diff --git a/src/paperless_text/tests/test_parser.py b/src/paperless_text/tests/test_parser.py index d952ceb9a..76a8b8498 100644 --- a/src/paperless_text/tests/test_parser.py +++ b/src/paperless_text/tests/test_parser.py @@ -2,10 +2,11 @@ import os from django.test import TestCase from documents.tests.utils import DirectoriesMixin +from documents.tests.utils import FileSystemAssertsMixin from paperless_text.parsers import TextDocumentParser -class TestTextParser(DirectoriesMixin, TestCase): +class TestTextParser(DirectoriesMixin, FileSystemAssertsMixin, TestCase): def test_thumbnail(self): parser = TextDocumentParser(None) @@ -15,7 +16,7 @@ class TestTextParser(DirectoriesMixin, TestCase): os.path.join(os.path.dirname(__file__), "samples", "test.txt"), "text/plain", ) - self.assertTrue(os.path.isfile(f)) + self.assertIsFile(f) def test_parse(self):