81 lines
2.6 KiB
Python
81 lines
2.6 KiB
Python
import pytest
|
|
from mjr_am_backend.adapters.tools.ffprobe import FFProbe
|
|
from mjr_am_backend.shared import ErrorCode
|
|
|
|
|
|
def _new_probe() -> FFProbe:
|
|
probe = FFProbe.__new__(FFProbe)
|
|
probe.bin = "ffprobe"
|
|
probe.timeout = 1.0
|
|
probe._resolved_bin = "ffprobe"
|
|
probe._available = True
|
|
probe._max_workers = 1
|
|
return probe
|
|
|
|
|
|
def test_validate_probe_path_rejects_invalid_inputs() -> None:
|
|
probe = _new_probe()
|
|
|
|
bad_inputs = ["", " ", "-show_streams", "a\x00b", "a\nb", "a\rb"]
|
|
for value in bad_inputs:
|
|
out = FFProbe._validate_probe_path(probe, value)
|
|
assert out.ok is False
|
|
assert out.code == ErrorCode.INVALID_INPUT
|
|
|
|
|
|
def test_validate_probe_path_accepts_normal_file_path() -> None:
|
|
probe = _new_probe()
|
|
out = FFProbe._validate_probe_path(probe, " ./video.mp4 ")
|
|
assert out.ok is True
|
|
assert out.data == "./video.mp4"
|
|
|
|
|
|
def test_ffprobe_executable_resolution_helpers(monkeypatch, tmp_path) -> None:
|
|
exep = tmp_path / "ffprobe.exe"
|
|
exep.write_text("x")
|
|
|
|
monkeypatch.setattr("mjr_am_backend.adapters.tools.ffprobe.shutil.which", lambda raw: str(exep) if raw in {"ffprobe", "ffprobe.exe"} else None)
|
|
assert FFProbe._resolve_executable_path("ffprobe") == str(exep)
|
|
assert FFProbe._resolve_executable_path('"ffprobe"') == str(exep)
|
|
assert FFProbe._is_ffprobe_name(str(exep)) is True
|
|
|
|
|
|
def test_ffprobe_resolve_executable_path_uses_sibling_alias(monkeypatch, tmp_path) -> None:
|
|
exep = tmp_path / "ffprobe.exe"
|
|
exep.write_text("x")
|
|
|
|
monkeypatch.setattr("mjr_am_backend.adapters.tools.ffprobe.shutil.which", lambda _raw: None)
|
|
configured = tmp_path / "ffprobe"
|
|
assert FFProbe._resolve_executable_path(str(configured)) == str(exep)
|
|
|
|
|
|
def test_read_rejects_invalid_path_before_subprocess(monkeypatch) -> None:
|
|
probe = _new_probe()
|
|
calls = {"run": 0}
|
|
|
|
def _run(_cmd):
|
|
calls["run"] += 1
|
|
raise AssertionError("subprocess should not run for invalid paths")
|
|
|
|
monkeypatch.setattr(probe, "_run_ffprobe_cmd", _run)
|
|
out = probe.read("-bad")
|
|
assert out.ok is False
|
|
assert out.code == ErrorCode.INVALID_INPUT
|
|
assert calls["run"] == 0
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_aread_rejects_invalid_path_before_subprocess(monkeypatch) -> None:
|
|
probe = _new_probe()
|
|
calls = {"spawn": 0}
|
|
|
|
async def _spawn(_cmd):
|
|
calls["spawn"] += 1
|
|
raise AssertionError("subprocess should not run for invalid paths")
|
|
|
|
monkeypatch.setattr(probe, "_spawn_ffprobe_process", _spawn)
|
|
out = await probe.aread("-bad")
|
|
assert out.ok is False
|
|
assert out.code == ErrorCode.INVALID_INPUT
|
|
assert calls["spawn"] == 0
|