mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
232 lines
6.7 KiB
Python
232 lines
6.7 KiB
Python
import shutil
|
|
import tempfile
|
|
from pathlib import Path
|
|
from typing import Callable
|
|
from typing import Iterable
|
|
from typing import Union
|
|
from unittest import mock
|
|
|
|
from django.test import override_settings
|
|
|
|
from documents.tests.utils import TestMigrations
|
|
|
|
|
|
@mock.patch(
|
|
"documents.migrations.1021_webp_thumbnail_conversion.multiprocessing.pool.Pool.map",
|
|
)
|
|
@mock.patch("documents.migrations.1021_webp_thumbnail_conversion.run_convert")
|
|
class TestMigrateWebPThumbnails(TestMigrations):
|
|
|
|
migrate_from = "1020_merge_20220518_1839"
|
|
migrate_to = "1021_webp_thumbnail_conversion"
|
|
auto_migrate = False
|
|
|
|
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 pretend_map(self, func: Callable, iterable: Iterable):
|
|
"""
|
|
Pretends to be the map of a multiprocessing.Pool, but secretly does
|
|
everything in series
|
|
"""
|
|
for item in iterable:
|
|
func(item)
|
|
|
|
def create_dummy_thumbnails(
|
|
self,
|
|
thumb_dir: Path,
|
|
ext: str,
|
|
count: int,
|
|
start_count: int = 0,
|
|
):
|
|
"""
|
|
Helper to create a certain count of files of given extension in a given directory
|
|
"""
|
|
for idx in range(count):
|
|
(Path(thumb_dir) / Path(f"{start_count + idx:07}.{ext}")).touch()
|
|
# Triple check expected files exist
|
|
self.assert_file_count_by_extension(ext, thumb_dir, count)
|
|
|
|
def create_webp_thumbnail_files(
|
|
self,
|
|
thumb_dir: Path,
|
|
count: int,
|
|
start_count: int = 0,
|
|
):
|
|
"""
|
|
Creates a dummy WebP thumbnail file in the given directory, based on
|
|
the database Document
|
|
"""
|
|
self.create_dummy_thumbnails(thumb_dir, "webp", count, start_count)
|
|
|
|
def create_png_thumbnail_file(
|
|
self,
|
|
thumb_dir: Path,
|
|
count: int,
|
|
start_count: int = 0,
|
|
):
|
|
"""
|
|
Creates a dummy PNG thumbnail file in the given directory, based on
|
|
the database Document
|
|
"""
|
|
self.create_dummy_thumbnails(thumb_dir, "png", count, start_count)
|
|
|
|
def assert_file_count_by_extension(
|
|
self,
|
|
ext: str,
|
|
dir: Union[str, Path],
|
|
expected_count: int,
|
|
):
|
|
"""
|
|
Helper to assert a certain count of given extension files in given directory
|
|
"""
|
|
if not isinstance(dir, Path):
|
|
dir = Path(dir)
|
|
matching_files = list(dir.glob(f"*.{ext}"))
|
|
self.assertEqual(len(matching_files), expected_count)
|
|
|
|
def assert_png_file_count(self, dir: Path, expected_count: int):
|
|
"""
|
|
Helper to assert a certain count of PNG extension files in given directory
|
|
"""
|
|
self.assert_file_count_by_extension("png", dir, expected_count)
|
|
|
|
def assert_webp_file_count(self, dir: Path, expected_count: int):
|
|
"""
|
|
Helper to assert a certain count of WebP extension files in given directory
|
|
"""
|
|
self.assert_file_count_by_extension("webp", dir, expected_count)
|
|
|
|
def setUp(self):
|
|
|
|
self.thumbnail_dir = Path(tempfile.mkdtemp()).resolve()
|
|
|
|
return super().setUp()
|
|
|
|
def tearDown(self) -> None:
|
|
|
|
shutil.rmtree(self.thumbnail_dir)
|
|
|
|
return super().tearDown()
|
|
|
|
def test_do_nothing_if_converted(
|
|
self,
|
|
run_convert_mock: mock.MagicMock,
|
|
map_mock: mock.MagicMock,
|
|
):
|
|
"""
|
|
GIVEN:
|
|
- Document exists with default WebP thumbnail path
|
|
WHEN:
|
|
- Thumbnail conversion is attempted
|
|
THEN:
|
|
- Nothing is converted
|
|
"""
|
|
map_mock.side_effect = self.pretend_map
|
|
|
|
with override_settings(
|
|
THUMBNAIL_DIR=self.thumbnail_dir,
|
|
):
|
|
|
|
self.create_webp_thumbnail_files(self.thumbnail_dir, 3)
|
|
|
|
self.performMigration()
|
|
run_convert_mock.assert_not_called()
|
|
|
|
self.assert_webp_file_count(self.thumbnail_dir, 3)
|
|
|
|
def test_convert_single_thumbnail(
|
|
self,
|
|
run_convert_mock: mock.MagicMock,
|
|
map_mock: mock.MagicMock,
|
|
):
|
|
"""
|
|
GIVEN:
|
|
- Document exists with PNG thumbnail
|
|
WHEN:
|
|
- Thumbnail conversion is attempted
|
|
THEN:
|
|
- Single thumbnail is converted
|
|
"""
|
|
map_mock.side_effect = self.pretend_map
|
|
run_convert_mock.side_effect = self.pretend_convert_output
|
|
|
|
with override_settings(
|
|
THUMBNAIL_DIR=self.thumbnail_dir,
|
|
):
|
|
self.create_png_thumbnail_file(self.thumbnail_dir, 3)
|
|
|
|
self.performMigration()
|
|
|
|
run_convert_mock.assert_called()
|
|
self.assertEqual(run_convert_mock.call_count, 3)
|
|
|
|
self.assert_webp_file_count(self.thumbnail_dir, 3)
|
|
|
|
def test_convert_errors_out(
|
|
self,
|
|
run_convert_mock: mock.MagicMock,
|
|
map_mock: mock.MagicMock,
|
|
):
|
|
"""
|
|
GIVEN:
|
|
- Document exists with PNG thumbnail
|
|
WHEN:
|
|
- Thumbnail conversion is attempted, but raises an exception
|
|
THEN:
|
|
- Single thumbnail is converted
|
|
"""
|
|
map_mock.side_effect = self.pretend_map
|
|
run_convert_mock.side_effect = OSError
|
|
|
|
with override_settings(
|
|
THUMBNAIL_DIR=self.thumbnail_dir,
|
|
):
|
|
|
|
self.create_png_thumbnail_file(self.thumbnail_dir, 3)
|
|
|
|
self.performMigration()
|
|
|
|
run_convert_mock.assert_called()
|
|
self.assertEqual(run_convert_mock.call_count, 3)
|
|
|
|
self.assert_png_file_count(self.thumbnail_dir, 3)
|
|
|
|
def test_convert_mixed(
|
|
self,
|
|
run_convert_mock: mock.MagicMock,
|
|
map_mock: mock.MagicMock,
|
|
):
|
|
"""
|
|
GIVEN:
|
|
- Document exists with PNG thumbnail
|
|
WHEN:
|
|
- Thumbnail conversion is attempted, but raises an exception
|
|
THEN:
|
|
- Single thumbnail is converted
|
|
"""
|
|
map_mock.side_effect = self.pretend_map
|
|
run_convert_mock.side_effect = self.pretend_convert_output
|
|
|
|
with override_settings(
|
|
THUMBNAIL_DIR=self.thumbnail_dir,
|
|
):
|
|
|
|
self.create_png_thumbnail_file(self.thumbnail_dir, 3)
|
|
self.create_webp_thumbnail_files(self.thumbnail_dir, 2, start_count=3)
|
|
|
|
self.performMigration()
|
|
|
|
run_convert_mock.assert_called()
|
|
self.assertEqual(run_convert_mock.call_count, 3)
|
|
|
|
self.assert_png_file_count(self.thumbnail_dir, 0)
|
|
self.assert_webp_file_count(self.thumbnail_dir, 5)
|