Thumbnails for images and videos #87

Merged
Anna Sirota merged 28 commits from thumbnails into main 2024-04-25 17:50:58 +02:00
2 changed files with 83 additions and 1 deletions
Showing only changes of commit 3f824d8b0a - Show all commits

66
files/tests/test_tasks.py Normal file
View File

@ -0,0 +1,66 @@
from unittest.mock import patch
from pathlib import Path
from django.test import TestCase, override_settings
from common.tests.factories.files import FileFactory
from files.tasks import make_thumbnails
import files.models
TEST_MEDIA_DIR = Path(__file__).resolve().parent / 'media'
# Media file are physically deleted when files records are deleted, hence the override
@override_settings(MEDIA_ROOT=TEST_MEDIA_DIR)
class TasksTest(TestCase):
@patch('files.utils.resize_image')
@patch('files.utils.Image')
def test_make_thumbnails_for_image(self, mock_image, mock_resize_image):
file = FileFactory(original_hash='foobar', source='file/original_image_source.jpg')
files.models.FileValidation.objects.create(file=file, is_ok=True, results={})
make_thumbnails.task_function(file_id=file.pk)
mock_image.open.assert_called_once_with(
str(TEST_MEDIA_DIR / 'file' / 'original_image_source.jpg')
)
mock_image.open.return_value.close.assert_called_once()
file.refresh_from_db()
self.assertEqual(
file.metadata,
{
'thumbnails': {
'l': {'path': 'thumbnails/fo/foobar_1920x1080.png', 'size': [1920, 1080]},
's': {'path': 'thumbnails/fo/foobar_640x360.png', 'size': [640, 360]},
},
},
)
self.assertEqual(file.thumbnail.name, 'thumbnails/fo/foobar_1920x1080.png')
@patch('files.utils.resize_image')
@patch('files.utils.Image')
@patch('files.utils.FFmpeg')
def test_make_thumbnails_for_video(self, mock_ffmpeg, mock_image, mock_resize_image):
file = FileFactory(
original_hash='deadbeef', source='file/path.mp4', type=files.models.File.TYPES.VIDEO
)
files.models.FileValidation.objects.create(file=file, is_ok=True, results={})
make_thumbnails.task_function(file_id=file.pk)
mock_ffmpeg.assert_called_once_with()
mock_image.open.assert_called_once_with(
str(TEST_MEDIA_DIR / 'thumbnails' / 'de' / 'deadbeef.png')
)
mock_image.open.return_value.close.assert_called_once()
file.refresh_from_db()
self.assertEqual(
file.metadata,
{
'thumbnails': {
'l': {'path': 'thumbnails/de/deadbeef_1920x1080.png', 'size': [1920, 1080]},
's': {'path': 'thumbnails/de/deadbeef_640x360.png', 'size': [640, 360]},
},
},
)
self.assertEqual(file.thumbnail.name, 'thumbnails/de/deadbeef_1920x1080.png')

View File

@ -1,9 +1,11 @@
from unittest.mock import patch, ANY
from pathlib import Path
from unittest.mock import patch, ANY
import tempfile
from django.test import TestCase
from files.utils import (
extract_frame,
filter_paths_by_ext,
find_exact_path,
find_path_by_name,
@ -142,3 +144,17 @@ class UtilsTest(TestCase):
optimize=True,
progressive=True,
)
@patch('files.utils.FFmpeg')
def test_extract_frame(self, mock_ffmpeg):
with tempfile.TemporaryDirectory() as output_dir:
extract_frame('path/to/source/video.mp4', output_dir + '/frame.png')
mock_ffmpeg.return_value.option.return_value.input.return_value.output.assert_any_call(
output_dir + '/frame.png', {'ss': '00:00:00.01', 'frames:v': 1, 'update': 'true'}
)
self.assertEqual(len(mock_ffmpeg.mock_calls), 5)
mock_ffmpeg.assert_any_call()
mock_ffmpeg.return_value.option.return_value.input.assert_any_call(
'path/to/source/video.mp4'
)