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 pathlib import Path
from unittest.mock import patch, ANY
import tempfile
from django.test import TestCase from django.test import TestCase
from files.utils import ( from files.utils import (
extract_frame,
filter_paths_by_ext, filter_paths_by_ext,
find_exact_path, find_exact_path,
find_path_by_name, find_path_by_name,
@ -142,3 +144,17 @@ class UtilsTest(TestCase):
optimize=True, optimize=True,
progressive=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'
)