Files
feedmill-recounter/tests/test_preview.py
T

115 lines
3.2 KiB
Python

# tests/test_preview.py
"""Tests for video preview utilities and routes."""
import os
import tempfile
import cv2
import numpy as np
import pytest
from src.preview import probe_video, extract_thumbnail, extract_sample_frames
@pytest.fixture
def sample_video(tmp_path):
"""Create a small test video (10 frames, 25 fps, 320x240)."""
video_path = str(tmp_path / "test.mp4")
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
writer = cv2.VideoWriter(video_path, fourcc, 25.0, (320, 240))
for i in range(10):
frame = np.full((240, 320, 3), [(i * 25) % 256, 100, 200], dtype=np.uint8)
writer.write(frame)
writer.release()
return video_path
# --- Unit tests for preview.py ---
def test_probe_video(sample_video, tmp_path):
info = probe_video(sample_video)
assert info["width"] == 320
assert info["height"] == 240
assert info["fps"] == 25.0
assert info["frame_count"] == 10
assert info["duration"] == pytest.approx(0.4, abs=0.05)
def test_probe_video_not_found():
with pytest.raises(FileNotFoundError):
probe_video("/nonexistent/video.mp4")
def test_extract_thumbnail(sample_video, tmp_path):
out = str(tmp_path / "thumb.jpg")
result = extract_thumbnail(sample_video, out, time_sec=0.1)
assert result == out
assert os.path.isfile(out)
assert os.path.getsize(out) > 0
def test_extract_thumbnail_custom_time(sample_video, tmp_path):
out = str(tmp_path / "thumb.jpg")
result = extract_thumbnail(sample_video, out, time_sec=0.0)
assert os.path.isfile(result)
def test_extract_thumbnail_not_found():
with pytest.raises(FileNotFoundError):
extract_thumbnail("/nonexistent/video.mp4", "/tmp/thumb.jpg")
def test_extract_sample_frames(sample_video, tmp_path):
out_dir = str(tmp_path / "samples")
paths = extract_sample_frames(sample_video, out_dir, count=3)
assert len(paths) == 3
for p in paths:
assert os.path.isfile(p)
assert p.endswith(".jpg")
def test_extract_sample_frames_default(sample_video, tmp_path):
out_dir = str(tmp_path / "samples")
paths = extract_sample_frames(sample_video, out_dir)
assert len(paths) == 6
def test_extract_sample_frames_not_found():
with pytest.raises(FileNotFoundError):
extract_sample_frames("/nonexistent/video.mp4", "/tmp/samples")
# --- Route tests ---
@pytest.fixture
def client():
from app import app
app.config["TESTING"] = True
with app.test_client() as c:
yield c
def test_preview_thumb_nonexistent(client):
resp = client.get("/preview/thumb/nonexistent")
assert resp.status_code == 404
def test_api_job_samples_nonexistent(client):
resp = client.get("/api/jobs/nonexistent/samples")
assert resp.status_code == 404
data = resp.get_json()
assert "error" in data
def test_api_job_frame_nonexistent(client):
resp = client.get("/api/jobs/nonexistent/frame")
assert resp.status_code == 404
def test_api_job_frame_no_latest_frame(client):
"""Frame route returns 404 when no latest_frame is set (Task 5 TBD)."""
from app import job_queue
job = job_queue.add_job(video_path="/tmp/test.mp4", model_configs=[])
resp = client.get(f"/api/jobs/{job.job_id}/frame")
assert resp.status_code == 404