115 lines
3.2 KiB
Python
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
|