Files
SnapOtter/packages/ai/python/tests/test_dispatcher_gate.py
T
SnapOtterandGitHub 301e6eb01a test: coverage campaign and mutation testing across five packages (#628)
Coverage 83.6 to 87.36% lines, 81.63 to 84.14% branches. Mutation testing across five packages: image-engine 85, media-engine 92, doc-engine 87, shared+enterprise 86, apps/api security and jobs slice. Runs all five lanes weekly. Fixes the silently-broken mutation CI (babel pin), a redact-pdf envelope-shape test bug, an untested enterprise license valid-signature path, and an audit test that only exercised a hand-copied reproduction. Test and config only, no product code changes beyond the babel pin and one test-only oidc export. Full suite: 16,712 pass, 0 fail.
2026-07-24 17:36:57 +08:00

97 lines
3.7 KiB
Python

"""Contract tests for the dispatcher security gate and installed-bundle reader.
_run_script_main's allowlist + feature gate is the sidecar's PRIMARY security
boundary (there is no process isolation between scripts). These tests exercise
the three reject branches that return BEFORE any script is exec'd, plus the
installed-bundle reader and progress emitter. The "docs" profile is selected so
importing the dispatcher skips all heavy ML imports."""
import json
import os
import sys
import pytest
# Select the lean profile before import so no heavy ML libraries are pulled in.
os.environ["DISPATCHER_PROFILE"] = "docs"
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
import dispatcher # noqa: E402
# --- _run_script_main security gate (returns before exec) -------------------
def test_rejects_invalid_script_name_with_path_separator():
out, code = dispatcher._run_script_main("../evil", ["x"])
assert code == 1
payload = json.loads(out)
assert payload["success"] is False
assert payload["error"] == "invalid_script_name"
@pytest.mark.parametrize("bad", ["Evil", "has space", "dots.py", "semi;colon", ""])
def test_rejects_names_failing_the_strict_regex(bad):
out, code = dispatcher._run_script_main(bad, [])
assert code == 1
assert json.loads(out)["error"] == "invalid_script_name"
def test_rejects_valid_format_name_not_on_allowlist():
# Well-formed but not an allowed script -> script_not_allowed (not exec'd).
out, code = dispatcher._run_script_main("definitely_not_a_real_script", [])
assert code == 1
payload = json.loads(out)
assert payload["error"] == "script_not_allowed"
def test_rejects_allowed_script_whose_bundle_is_not_installed(monkeypatch):
# Allow an AI script that maps to a bundle, but report nothing installed.
monkeypatch.setattr(dispatcher, "ALLOWED_SCRIPTS", {"remove_bg"})
monkeypatch.setattr(dispatcher, "_get_installed_bundles", lambda: set())
out, code = dispatcher._run_script_main("remove_bg", ["in.png"])
assert code == 1
payload = json.loads(out)
assert payload["error"] == "feature_not_installed"
assert payload["feature"] == "background-removal"
# --- _get_installed_bundles -------------------------------------------------
def test_installed_bundles_empty_when_file_missing(monkeypatch, tmp_path):
monkeypatch.setattr(dispatcher, "INSTALLED_PATH", str(tmp_path / "nope.json"))
assert dispatcher._get_installed_bundles() == set()
def test_installed_bundles_reads_bundle_keys(monkeypatch, tmp_path):
p = tmp_path / "installed.json"
p.write_text(json.dumps({"bundles": {"ocr": {}, "transcription": {}}}))
monkeypatch.setattr(dispatcher, "INSTALLED_PATH", str(p))
assert dispatcher._get_installed_bundles() == {"ocr", "transcription"}
def test_installed_bundles_empty_on_malformed_json(monkeypatch, tmp_path):
p = tmp_path / "installed.json"
p.write_text("{ not valid json")
monkeypatch.setattr(dispatcher, "INSTALLED_PATH", str(p))
assert dispatcher._get_installed_bundles() == set()
# --- emit_progress ----------------------------------------------------------
def test_emit_progress_writes_json_to_stderr(capsys):
dispatcher.emit_progress(42, "removing background")
err = capsys.readouterr().err.strip()
payload = json.loads(err)
assert payload == {"progress": 42, "stage": "removing background"}
# --- docs profile swaps the allowlist --------------------------------------
def test_docs_profile_allowlist_is_the_docs_script_set():
# Import-time selected DISPATCHER_PROFILE=docs, so ALLOWED_SCRIPTS is the
# lean document set, not the AI set.
assert "doc_health" in dispatcher.ALLOWED_SCRIPTS
assert "remove_bg" not in dispatcher.ALLOWED_SCRIPTS