"""Unit tests for automation manager job paths.""" from __future__ import annotations from pathlib import Path import pytest from aegis_gitea_mcp.automation import AutomationError, AutomationManager from aegis_gitea_mcp.config import reset_settings from aegis_gitea_mcp.policy import reset_policy_engine class StubAutomationGiteaClient: """Async context manager stub for automation jobs.""" def __init__(self, token: str, issues: list[dict] | None = None) -> None: self.token = token self._issues = issues or [] async def __aenter__(self): return self async def __aexit__(self, *_args): return None async def list_issues(self, owner, repo, *, state, page, limit, labels=None): return self._issues async def create_issue(self, owner, repo, *, title, body, labels=None, assignees=None): return {"number": 77, "title": title, "body": body} @pytest.fixture(autouse=True) def reset_globals() -> None: """Reset singleton state between tests.""" reset_settings() reset_policy_engine() yield reset_settings() reset_policy_engine() @pytest.fixture def automation_env(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> Path: """Set environment for automation manager tests.""" policy_path = tmp_path / "policy.yaml" policy_path.write_text( ( "defaults:\n" " read: allow\n" " write: allow\n" "tools:\n" " allow:\n" " - automation_stale_issue_detection\n" " - automation_auto_issue_creation\n" ), encoding="utf-8", ) monkeypatch.setenv("GITEA_URL", "https://gitea.example.com") monkeypatch.setenv("GITEA_TOKEN", "legacy-token") monkeypatch.setenv("MCP_API_KEYS", "a" * 64) monkeypatch.setenv("ENVIRONMENT", "test") monkeypatch.setenv("AUTOMATION_ENABLED", "true") monkeypatch.setenv("POLICY_FILE_PATH", str(policy_path)) monkeypatch.setenv("WRITE_MODE", "true") monkeypatch.setenv("WRITE_REPOSITORY_WHITELIST", "acme/demo") monkeypatch.setenv("AUTOMATION_STALE_DAYS", "30") return policy_path @pytest.mark.asyncio async def test_stale_issue_detection_job_finds_old_issues( automation_env: Path, monkeypatch: pytest.MonkeyPatch, ) -> None: """Stale issue detection returns issue numbers older than cutoff.""" issues = [ {"number": 1, "updated_at": "2020-01-01T00:00:00Z"}, {"number": 2, "updated_at": "2999-01-01T00:00:00Z"}, ] monkeypatch.setattr( "aegis_gitea_mcp.automation.GiteaClient", lambda token: StubAutomationGiteaClient(token=token, issues=issues), ) manager = AutomationManager() result = await manager.run_job( job_name="stale_issue_detection", owner="acme", repo="demo", user_token="user-token", ) assert result["stale_issue_numbers"] == [1] assert result["stale_count"] == 1 @pytest.mark.asyncio async def test_auto_issue_creation_requires_token( automation_env: Path, ) -> None: """Auto-issue creation is denied when no user token is provided.""" manager = AutomationManager() with pytest.raises(AutomationError, match="missing authenticated user token"): await manager.run_job( job_name="auto_issue_creation", owner="acme", repo="demo", user_token=None, ) @pytest.mark.asyncio async def test_auto_issue_creation_job_success( automation_env: Path, monkeypatch: pytest.MonkeyPatch, ) -> None: """Auto-issue creation succeeds with write mode + scope + token.""" monkeypatch.setattr( "aegis_gitea_mcp.automation.GiteaClient", lambda token: StubAutomationGiteaClient(token=token), ) manager = AutomationManager() result = await manager.run_job( job_name="auto_issue_creation", owner="acme", repo="demo", user_token="user-token", finding_title="Security finding", finding_body="Details", ) assert result["job"] == "auto_issue_creation" assert result["issue_number"] == 77