Exclude development-only content from Registry packages while retaining runtime docs and vendor assets. Centralize environment access and media process execution, validate filesystem inputs, and restrict nested media protocols. Route update checks through the backend GitHub boundary and read version metadata without spawning Git. Preserve annotated-tag priority over lightweight nightly tags, including packed refs, with regression coverage. Rebuild the frontend bundle. Validation: Python tests with coverage, JS tests, targeted media/version regression tests, and the canonical Python quality gate.
83 lines
2.7 KiB
Python
83 lines
2.7 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(tmp_path) -> None:
|
|
probe = _new_probe()
|
|
path = tmp_path / "video.mp4"
|
|
path.touch()
|
|
out = FFProbe._validate_probe_path(probe, f" {path} ")
|
|
assert out.ok is True
|
|
assert out.data == str(path.resolve())
|
|
|
|
|
|
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
|