coulomb-social/tests/test_owner_communication_gate.py
tegwick cb9301537e
Some checks failed
Use-case regression gate / usecase-regressions (push) Failing after 6m57s
Exercise actual communication owner sources through isolated browser flows
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a18e2d-f513-7742-b8e7-12af0b744ff3
2026-10-30 21:51:36 +01:00

79 lines
3.7 KiB
Python

"""The explicit owner-browser runner must isolate configuration and refuse weak reports."""
import importlib.util
import json
import sys
from pathlib import Path
from types import SimpleNamespace
import pytest
ROOT = Path(__file__).resolve().parents[1]
def runner():
spec = importlib.util.spec_from_file_location("owner_browser_gate", ROOT / "scripts"
/ "check-owner-communication.py")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
@pytest.mark.parametrize("report_kind", ["passed", "skipped", "wrong_node"])
def test_snapshot_strips_credentials_runtime_data_and_requires_exact_unskipped_node(
tmp_path, monkeypatch, report_kind):
module = runner()
owners = []
for package in ("user_engine", "email_connect"):
owner = tmp_path / package
source = owner / "src" / package
source.mkdir(parents=True)
(source / "__init__.py").write_text("# synthetic owner source\n")
(owner / ".env").write_text("SMTP_PASSWORD=synthetic-not-to-inherit")
(source / "runtime.db").write_bytes(b"synthetic-private-database")
owners.append(owner)
output = tmp_path / "receipt.json"
monkeypatch.setattr(sys, "argv", ["gate", "--user-engine", str(owners[0]),
"--email-connect", str(owners[1]),
"--receipt", str(output)])
monkeypatch.setenv("SMTP_PASSWORD", "synthetic-not-to-inherit")
monkeypatch.setenv("USER_ENGINE_FLEX_AUTH_TOKEN_FILE", "/synthetic/production-config")
def execute(argv, *, cwd, env, **kwargs):
assert "SMTP_PASSWORD" not in env and "USER_ENGINE_FLEX_AUTH_TOKEN_FILE" not in env
assert not list(cwd.rglob(".env")) and not list(cwd.rglob("*.db"))
assert argv[argv.index("-c") + 1] == str(cwd / "pytest.ini")
assert module.NODE in argv
node = module.NODE.split("::")[-1] if report_kind != "wrong_node" else "another_test"
skipped = "<skipped/>" if report_kind == "skipped" else ""
(cwd / "result.xml").write_text(
f'<testsuites><testsuite><testcase name="{node}">{skipped}</testcase>'
'</testsuite></testsuites>')
Path(env["OWNER_CHECKS_RESULT"]).write_text(json.dumps({"passed": True}))
return SimpleNamespace(returncode=0, stdout=b"", stderr=b"")
monkeypatch.setattr(module.subprocess, "run", execute)
assert module.main() == (0 if report_kind == "passed" else 1)
proof = json.loads(output.read_bytes())
assert proof["passed"] == (report_kind == "passed")
assert not proof["production_access"] and not proof["productive_acceptance"]
assert output.stat().st_mode & 0o777 == 0o600
manifest = output.with_name(proof["source_manifest"]).read_text()
assert ".env:" not in manifest and ".db:" not in manifest
with pytest.raises(ValueError, match="Fresh receipt"):
module.main()
def test_symlinked_owner_source_is_refused_before_any_execution(tmp_path, monkeypatch):
module = runner()
source = tmp_path / "owner/src/user_engine"
source.mkdir(parents=True)
(source / "__init__.py").write_text("# synthetic package")
(tmp_path / "private.py").write_text("# not owner source")
(source / "linked.py").symlink_to(tmp_path / "private.py")
monkeypatch.setattr(sys, "argv", ["gate", "--user-engine", str(tmp_path / "owner"),
"--email-connect", str(tmp_path / "missing"),
"--receipt", str(tmp_path / "receipt.json")])
monkeypatch.setattr(module.subprocess, "run", lambda *a, **kw: pytest.fail("must not execute"))
with pytest.raises(ValueError, match="symlink refused"):
module.main()