import pytest from unittest.mock import MagicMock, AsyncMock, patch from core.notification_tools import NotificationTools from core.notification_agent import NotificationReaderAgent, NotificationNoToolCalledError pytestmark = pytest.mark.anyio def test_notification_tools() -> None: tools = NotificationTools() assert tools.tool_called is False assert tools.action == "NO_ACTION" res = tools.process_issue("meeks", "repo", 42, "fix bug") assert tools.tool_called is True assert tools.action == "PROCESS_ISSUE" assert tools.arguments == { "owner": "meeks", "repo": "repo", "issue_number": 42, "reason": "fix bug", } assert "marked for processing" in res tools = NotificationTools() res = tools.process_pr("meeks", "repo", 10, "review change") assert tools.tool_called is True assert tools.action == "PROCESS_PR" assert tools.arguments == { "owner": "meeks", "repo": "repo", "pr_number": 10, "reason": "review change", } assert "marked for processing" in res tools = NotificationTools() res = tools.skip_notification("unrelated comments") assert tools.tool_called is True assert tools.action == "SKIP" assert tools.arguments == {"reason": "unrelated comments"} assert "marked to be skipped" in res @patch("core.notification_agent.NotificationReaderAgent.initialize") @patch("core.notification_agent.NotificationReaderAgent.run_with_tools") async def test_notification_reader_agent_success( mock_run_with_tools: MagicMock, mock_initialize: MagicMock ) -> None: mock_initialize.return_value = None agent = NotificationReaderAgent("dummy-model") # Mock tool call inside run_with_tools async def mock_run(mission: str, tools: list) -> str: # Simulate calling a tool for t in tools: if getattr(t, "__name__", "") == "process_issue": t("meeks", "repo", 42, "reason") return "response" mock_run_with_tools.side_effect = mock_run tools = NotificationTools() res = await agent.decide_notification("mission", [], tools) assert res == "response" assert tools.tool_called is True assert tools.action == "PROCESS_ISSUE" @patch("core.notification_agent.NotificationReaderAgent.initialize") @patch("core.notification_agent.NotificationReaderAgent.run_with_tools") async def test_notification_reader_agent_no_tool_error( mock_run_with_tools: MagicMock, mock_initialize: MagicMock ) -> None: mock_initialize.return_value = None agent = NotificationReaderAgent("dummy-model") mock_run_with_tools.return_value = "no tool called" tools = NotificationTools() with pytest.raises(NotificationNoToolCalledError): await agent.decide_notification("mission", [], tools)