"""`thumbnail_to_jpg`: robustly turn a downloaded thumbnail into a real JPEG poster/og:image. This replaced yt-dlp's `FFmpegThumbnailsConvertor`, whose `-bsf:v mjpeg2jpeg` path crashed on some already-JPEG thumbnails (Reddit serves a JPEG under a `.png` name) — and because a postprocessor error is fatal, it used to fail the WHOLE download. The key regression property here is that a bad thumbnail returns None (poster falls back to a cut frame) instead of raising. """ import shutil import subprocess from pathlib import Path import pytest from app.downloads import edit _ffmpeg_missing = shutil.which("ffmpeg") is None needs_ffmpeg = pytest.mark.skipif(_ffmpeg_missing, reason="ffmpeg not available") def _is_jpeg(p: Path) -> bool: return p.exists() and p.read_bytes()[:3] == b"\xff\xd8\xff" @needs_ffmpeg def test_converts_a_png_to_a_real_jpeg(tmp_path): src = tmp_path / "thumb.png" subprocess.run( ["ffmpeg", "-y", "-loglevel", "error", "-f", "lavfi", "-i", "color=c=red:s=64x64", "-frames:v", "1", str(src)], check=True, ) out = edit.thumbnail_to_jpg(src, tmp_path / "poster.jpg") assert out is not None and _is_jpeg(out) def test_returns_none_for_a_missing_source(tmp_path): assert edit.thumbnail_to_jpg(None, tmp_path / "p.jpg") is None assert edit.thumbnail_to_jpg(tmp_path / "nope.png", tmp_path / "p.jpg") is None @needs_ffmpeg def test_returns_none_on_garbage_input_instead_of_raising(tmp_path): # The whole point: a thumbnail ffmpeg can't decode must NOT crash the download. bad = tmp_path / "bad.png" bad.write_bytes(b"this is definitely not an image") assert edit.thumbnail_to_jpg(bad, tmp_path / "p.jpg") is None