"""Tests for the optional reverse-SynthID scorer adapter.""" from __future__ import annotations import json import subprocess import sys from pathlib import Path from types import SimpleNamespace import pytest ROOT = Path(__file__).resolve().parents[1] SCRIPTS = ROOT / "service" / "scripts" sys.path.insert(0, str(SCRIPTS)) import image_meta # noqa: E402 from image_meta import ImageInspectReport, run_synthid_score # noqa: E402 SCORE_SCRIPT = SCRIPTS / "score_synthid.py" def test_score_synthid_cli_unavailable_without_upstream( tmp_path: Path, monkeypatch: pytest.MonkeyPatch ): monkeypatch.delenv("REVERSE_SYNTHID_DIR", raising=False) dummy = tmp_path / "img.png" dummy.write_bytes(b"not really an image") r = subprocess.run( [sys.executable, str(SCORE_SCRIPT), str(dummy)], capture_output=True, text=True, ) assert r.returncode == 3 assert "REVERSE_SYNTHID_DIR" in (r.stderr or "") def test_run_synthid_score_unconfigured_returns_none( monkeypatch: pytest.MonkeyPatch, ): monkeypatch.delenv("REVERSE_SYNTHID_DIR", raising=False) assert run_synthid_score(Path("x.png")) is None def test_run_synthid_score_unavailable_returns_none( monkeypatch: pytest.MonkeyPatch, ): def fake_run(*args, **kwargs): return SimpleNamespace(returncode=3, stdout="", stderr="unavailable") monkeypatch.setattr(image_meta.subprocess, "run", fake_run) assert run_synthid_score(Path("x.png"), upstream_dir="/tmp/upstream") is None def test_run_synthid_score_parses_json( monkeypatch: pytest.MonkeyPatch, ): payload = { "available": True, "is_watermarked": True, "confidence": 0.91, "phase_match": 0.65, } captured: dict = {} def fake_run(cmd, **kwargs): captured["cmd"] = cmd return SimpleNamespace(returncode=0, stdout=json.dumps(payload), stderr="") monkeypatch.setattr(image_meta.subprocess, "run", fake_run) result = run_synthid_score(Path("img.png"), upstream_dir="/tmp/upstream") assert result == payload assert "--json" in captured["cmd"] assert "--upstream-dir" in captured["cmd"] assert "/tmp/upstream" in captured["cmd"] def test_run_synthid_score_runtime_error_is_reported( monkeypatch: pytest.MonkeyPatch, ): def fake_run(*args, **kwargs): return SimpleNamespace(returncode=1, stdout="", stderr="boom") monkeypatch.setattr(image_meta.subprocess, "run", fake_run) result = run_synthid_score(Path("img.png"), upstream_dir="/tmp/upstream") assert result is not None assert result.get("available") is False assert "boom" in result.get("error", "") def test_inspect_image_cli_prints_synthid_score( tmp_path: Path, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str], ): import importlib.util spec = importlib.util.spec_from_file_location( "inspect_image_cli", str(SCRIPTS / "inspect_image.py") ) assert spec and spec.loader cli = importlib.util.module_from_spec(spec) spec.loader.exec_module(cli) report = ImageInspectReport( path="shot.png", format="png", has_c2pa=False, has_ai_metadata=False, synthid={ "available": True, "is_watermarked": True, "confidence": 0.91, }, ) img = tmp_path / "shot.png" img.write_bytes(b"not really an image") monkeypatch.setattr(cli, "inspect_image", lambda path, synthid_dir=None: report) monkeypatch.setattr(sys, "argv", ["inspect_image.py", str(img)]) assert cli.main() == 0 out = capsys.readouterr().out assert "SynthID score: confidence 0.910 (watermarked: yes)" in out def test_inspect_report_to_dict_includes_synthid(): report = ImageInspectReport( path="x.png", format="png", has_c2pa=False, has_ai_metadata=False, synthid={"available": True, "confidence": 0.8}, ) assert report.to_dict()["synthid"]["confidence"] == 0.8 empty = ImageInspectReport( path="x.png", format="png", has_c2pa=False, has_ai_metadata=False, ) assert empty.to_dict()["synthid"] is None