1a2a120da1
Generates 400px-max thumbnails: PNG with alpha preserved when source has
transparency, JPEG (q=85, progressive) otherwise. Storage layout is
/images/thumbs/{sha[:3]}/{sha}.{jpg|png} so each prefix bucket holds at
most ~4k files (16^3 buckets across all possible SHAs).
Video path uses ffmpeg's first-frame snapshot at ~5% offset; we have a
1-second floor for short clips. ffmpeg call has a 60s timeout. Video
tests are deferred to FC-2e's integration suite where transcoding is
also wired up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
67 lines
2.1 KiB
Python
67 lines
2.1 KiB
Python
"""Image-thumbnailer smoke tests. Video tests are not included here because
|
|
they require a real ffmpeg + a real video on disk; FC-2e's integration suite
|
|
will cover those end-to-end against the running container.
|
|
"""
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from PIL import Image
|
|
|
|
from backend.app.services.thumbnailer import (
|
|
THUMB_MAX_PX,
|
|
Thumbnailer,
|
|
thumbnail_path_for,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def thumbnailer(tmp_path):
|
|
return Thumbnailer(images_root=tmp_path)
|
|
|
|
|
|
def _make_image(path: Path, size: tuple[int, int], mode: str = "RGB"):
|
|
im = Image.new(mode, size, color=(200, 100, 50, 255) if mode == "RGBA" else (200, 100, 50))
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
im.save(path)
|
|
|
|
|
|
def test_thumbnail_path_for_jpeg():
|
|
p = thumbnail_path_for("abcdef" + "0" * 58, alpha=False, root=Path("/images"))
|
|
assert p == Path("/images/thumbs/abc/" + "abcdef" + "0" * 58 + ".jpg")
|
|
|
|
|
|
def test_thumbnail_path_for_png():
|
|
p = thumbnail_path_for("abcdef" + "0" * 58, alpha=True, root=Path("/images"))
|
|
assert p.suffix == ".png"
|
|
|
|
|
|
def test_generate_thumbnail_rgb(thumbnailer, tmp_path):
|
|
src = tmp_path / "src.jpg"
|
|
_make_image(src, (1600, 1200), mode="RGB")
|
|
sha = "deadbeef" + "0" * 56
|
|
result = thumbnailer.generate_image_thumbnail(src, sha)
|
|
assert result.mime == "image/jpeg"
|
|
assert result.path.suffix == ".jpg"
|
|
assert result.path.exists()
|
|
assert max(result.width, result.height) == THUMB_MAX_PX
|
|
|
|
|
|
def test_generate_thumbnail_rgba_preserves_alpha(thumbnailer, tmp_path):
|
|
src = tmp_path / "src.png"
|
|
_make_image(src, (1200, 800), mode="RGBA")
|
|
sha = "feedface" + "0" * 56
|
|
result = thumbnailer.generate_image_thumbnail(src, sha)
|
|
assert result.mime == "image/png"
|
|
assert result.path.suffix == ".png"
|
|
|
|
|
|
def test_generate_thumbnail_tall_image(thumbnailer, tmp_path):
|
|
src = tmp_path / "src.jpg"
|
|
_make_image(src, (200, 2000), mode="RGB")
|
|
sha = "cafef00d" + "0" * 56
|
|
result = thumbnailer.generate_image_thumbnail(src, sha)
|
|
assert result.height == THUMB_MAX_PX
|
|
# tall image: width scales down proportionally
|
|
assert result.width < THUMB_MAX_PX
|