import asyncio
import json
from pathlib import Path
import pytest
from domin8.tools.request_change import handle_request_change
from domin8.git_ops import create_diff
from domin8.storage import get_agent_data_root
VALID_LONG_SUMMARY = (
"This is a sufficiently long justification intended to satisfy the strict word-count rules. "
"It explains why the change is necessary because it removes an ambiguous API and clarifies the public surface, "
"therefore reducing future maintenance burden and preventing accidental misuse. "
"The change is limited in scope and targets a single file to keep blast radius minimal, and thus is safe to review."
)
@pytest.mark.asyncio
async def test_summary_too_short(tmp_path):
# Build a small valid diff for an existing file
repo_root = Path('.').resolve()
target = Path('docs/refactor_plan.md')
assert target.exists()
original = target.read_text()
new = original.replace('Phase 1 – Single Tool Contract', 'Phase 1 — Single Tool Contract')
diff = create_diff(original, new, str(target))
res = await handle_request_change({
'summary': 'Too short.',
'diff': diff,
'actor_id': 'agent.test'
})
assert 'Summary word count must be between 40 and 250 words' in res
@pytest.mark.asyncio
async def test_invalid_diff_detected():
res = await handle_request_change({
'summary': VALID_LONG_SUMMARY,
'diff': 'this is not a diff',
'actor_id': 'agent.test'
})
assert "Diff does not appear to be a unified diff" in res
@pytest.mark.asyncio
async def test_success_creates_artifact_and_writes_files(tmp_path):
# Create a small single-file diff modifying docs/refactor_plan.md
target = Path('docs/refactor_plan.md')
assert target.exists()
original = target.read_text()
new = original.replace('This roadmap takes you from an ad hoc, agent-driven modification flow', 'This roadmap begins the transition from ad hoc agent-driven modifications')
diff = create_diff(original, new, str(target))
res = await handle_request_change({
'summary': VALID_LONG_SUMMARY,
'diff': diff,
'actor_id': 'agent.test',
'tags': ['refactor', 'pipeline'],
})
# Non-interactive CLI/test mode returns a specific confirmation message with artifact UUID and path
assert 'Change request created and pending approval' in res or 'Artifact UUID' in res
# Attempt to extract the UUID and check artifact directory was created on disk
# The response includes the artifact path: ~/.domin8/agent_data/<repo_relative>/artifacts/<uuid>/
import re
m = re.search(r'~/.domin8/agent_data/(.+?)/artifacts/([0-9a-fA-F-]+)', res)
assert m is not None
repo_rel = m.group(1)
uuid = m.group(2)
artifact_dir = get_agent_data_root() / repo_rel / 'artifacts' / uuid
# artifact files should exist
assert (artifact_dir / 'meta.json').exists()
assert (artifact_dir / 'intent.json').exists()
assert (artifact_dir / 'diff.patch').exists()