import json
import os
import re
from pathlib import Path
import pytest
from domin8.storage import get_agent_data_root, write_json_atomic
from domin8.crypto import create_signing_key, sign_approval
from domin8.tools.approval_pipeline import approve_artifact
def make_artifact(tmp_path, repo_rel='src/domin8/config.py'):
root = get_agent_data_root()
artifact_uuid = 'test-uuid-1234'
artifact_dir = root / repo_rel / 'artifacts' / artifact_uuid
artifact_dir.mkdir(parents=True, exist_ok=True)
meta = {
'uuid': artifact_uuid,
'repo_relative_path': repo_rel,
'action': 'edit',
'actor': {'id': 'agent.test', 'type': 'agent'},
'created_at': '2026-01-01T00:00:00+00:00',
'pre_state_sha': None,
'post_state_sha': None,
'deterministic_flags': {'schema_version': 1},
'status': 'pending'
}
intent = {'summary': 'This is a long summary because it fixes things in order to reduce risk and thus is safe.', 'diff': '--- a/src/domin8/config.py\n+++ b/src/domin8/config.py\n@@ -1,1 +1,2 @@\n original\n+new\n'}
write_json_atomic(artifact_dir / 'meta.json', meta)
write_json_atomic(artifact_dir / 'intent.json', intent)
(artifact_dir / 'diff.patch').write_text(intent['diff'])
return artifact_dir, artifact_uuid, repo_rel
@pytest.mark.asyncio
async def test_approve_artifact_success(monkeypatch, tmp_path):
artifact_dir, uuid, repo_rel = make_artifact(tmp_path)
# Create a signing key for approver
approver = 'alice'
try:
create_signing_key(approver)
except Exception:
# key may already exist in CI
pass
approval = {'approver_id': approver, 'approved_at': '2026-01-01T12:00:00+00:00', 'decision': 'approved'}
signed = sign_approval(dict(approval), approver)
# Monkeypatch stage_and_commit and pytest invocation to avoid actual git operations
monkeypatch.setattr('domin8.tools.approval_pipeline.stage_and_commit', lambda paths, msg: None)
monkeypatch.setattr('subprocess.run', lambda *args, **kwargs: type('r', (), {'returncode': 0, 'stdout': 'ok', 'stderr': ''})())
res = approve_artifact(repo_rel, uuid, signed)
assert res['status'] == 'approved'
assert (artifact_dir / 'verification.sha256').exists()
def test_approve_artifact_checks_fail(monkeypatch, tmp_path):
artifact_dir, uuid, repo_rel = make_artifact(tmp_path)
approver = 'bob'
try:
create_signing_key(approver)
except Exception:
pass
approval = {'approver_id': approver, 'approved_at': '2026-01-01T12:00:00+00:00', 'decision': 'approved'}
signed = sign_approval(dict(approval), approver)
# Simulate checks failing early by monkeypatching run_checks_for_changes
monkeypatch.setattr('domin8.tools.approval_pipeline.run_checks_for_changes', lambda normalized, root: {'per_type': {}, 'policy': {'findings': [{'path': 'x', 'hits': ['secrets']}]} })
res = approve_artifact(repo_rel, uuid, signed)
assert res['status'] == 'failed_checks'