""" Encoder pipeline tests for ``EncoderWorker._validate_file``. QA finding: OTC-002 (pre-encode validation coverage). ``_validate_file`` runs ffprobe on a candidate input and returns a 4-tuple ``(skip, info, src_w, src_h)``. It must SKIP files that have no video stream or are too short (<0.5s) — otherwise the av1an/ffmpeg encode would crash mid-pipeline or hang on a degenerate input. The 3 cases here cover: - No video stream (audio-only file mistakenly placed in input dir). - Sub-0.5s duration (truncated / corrupted capture). - Valid 1080p video — should pass through with src_w/src_h extracted. All 3 mock ``subprocess.run`` so the tests run without a real ffprobe binary. The worker is instantiated via ``__new__`` (no QThread.start). """ from __future__ import annotations import json import subprocess from pathlib import Path from unittest.mock import MagicMock from conftest import make_minimal_worker def _ffprobe_completed_process(payload: dict) -> subprocess.CompletedProcess: """Wrap a dict as a ffprobe-style CompletedProcess (stdout=JSON).""" return subprocess.CompletedProcess( args=["ffprobe"], returncode=0, stdout=json.dumps(payload), stderr="", ) def test_validate_file_skips_no_video_stream(v3_module, mock_env, monkeypatch): """ffprobe returns JSON with no video stream -> skip=True.""" ffprobe_json = { "streams": [ {"index": 0, "codec_type": "audio", "codec_name": "aac"}, ], "format": {"duration": "10.0", "name": "mov,mp4,m4a,3gp,3g2,mj2"}, } monkeypatch.setattr( "subprocess.run", MagicMock(return_value=_ffprobe_completed_process(ffprobe_json)), ) worker = make_minimal_worker(v3_module, env=mock_env) skip, info, src_w, src_h = worker._validate_file(Path("/fake/audio-only.mkv")) assert skip is True assert info is None assert src_w is None assert src_h is None # The skip path increments fail_count so the queue summary is accurate. assert worker.fail_count == 1 def test_validate_file_skips_short_duration(v3_module, mock_env, monkeypatch): """ffprobe returns duration=0.3 (<0.5s threshold) -> skip=True.""" ffprobe_json = { "streams": [ {"index": 0, "codec_type": "video", "codec_name": "h264", "width": 1920, "height": 1080}, ], "format": {"duration": "0.3"}, } monkeypatch.setattr( "subprocess.run", MagicMock(return_value=_ffprobe_completed_process(ffprobe_json)), ) worker = make_minimal_worker(v3_module, env=mock_env) skip, info, src_w, src_h = worker._validate_file(Path("/fake/short.mkv")) assert skip is True assert info is None assert src_w is None assert src_h is None assert worker.fail_count == 1 def test_validate_file_accepts_valid_video(v3_module, mock_env, monkeypatch): """ffprobe returns a valid video stream + duration=10.0 -> skip=False, src_w=1920, src_h=1080. """ ffprobe_json = { "streams": [ {"index": 0, "codec_type": "video", "codec_name": "h264", "width": 1920, "height": 1080}, {"index": 1, "codec_type": "audio", "codec_name": "aac"}, ], "format": {"duration": "10.0"}, } monkeypatch.setattr( "subprocess.run", MagicMock(return_value=_ffprobe_completed_process(ffprobe_json)), ) worker = make_minimal_worker(v3_module, env=mock_env) skip, info, src_w, src_h = worker._validate_file(Path("/fake/valid.mkv")) assert skip is False assert info is not None assert src_w == 1920 assert src_h == 1080 assert worker.fail_count == 0