# 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