"""Unit tests for webhook notification utility."""

from unittest.mock import AsyncMock, MagicMock, patch


async def test_webhook_not_called_when_url_not_configured():
    with patch("agenteval.utils.webhook.get_settings") as mock_settings:
        mock_settings.return_value.webhook_url = None
        mock_settings.return_value.webhook_secret = None

        with patch("agenteval.utils.webhook.httpx.AsyncClient") as MockClient:
            from agenteval.utils.webhook import send_run_webhook
            await send_run_webhook("run-1", "completed", {"pass_rate": 1.0})
            MockClient.assert_not_called()


async def test_webhook_posts_correct_payload():
    captured = {}

    async def fake_post(url, *, json=None, headers=None, **kwargs):
        captured["url"] = url
        captured["json"] = json
        captured["headers"] = headers
        resp = MagicMock()
        resp.status_code = 200
        return resp

    with patch("agenteval.utils.webhook.get_settings") as mock_settings:
        mock_settings.return_value.webhook_url = "http://hook.example.com/notify"
        mock_settings.return_value.webhook_secret = "secret123"

        with patch("agenteval.utils.webhook.httpx.AsyncClient") as MockClient:
            instance = MockClient.return_value.__aenter__.return_value
            instance.post = AsyncMock(side_effect=fake_post)

            from agenteval.utils.webhook import send_run_webhook
            await send_run_webhook("run-42", "completed", {"pass_rate": 0.9})

    assert captured["url"] == "http://hook.example.com/notify"
    assert captured["json"]["run_id"] == "run-42"
    assert captured["json"]["status"] == "completed"
    assert captured["json"]["event"] == "run_completed"
    assert captured["json"]["summary"]["pass_rate"] == 0.9
    assert captured["headers"]["X-Webhook-Secret"] == "secret123"
    assert "/api/reports/run-42" in captured["json"]["report_url"]


async def test_webhook_no_secret_header():
    captured_headers = {}

    async def fake_post(url, *, json=None, headers=None, **kwargs):
        captured_headers.update(headers or {})
        resp = MagicMock()
        resp.status_code = 200
        return resp

    with patch("agenteval.utils.webhook.get_settings") as mock_settings:
        mock_settings.return_value.webhook_url = "http://hook.example.com/notify"
        mock_settings.return_value.webhook_secret = None

        with patch("agenteval.utils.webhook.httpx.AsyncClient") as MockClient:
            instance = MockClient.return_value.__aenter__.return_value
            instance.post = AsyncMock(side_effect=fake_post)

            from agenteval.utils.webhook import send_run_webhook
            await send_run_webhook("run-1", "completed", {})

    assert "X-Webhook-Secret" not in captured_headers


async def test_webhook_silently_ignores_errors():
    with patch("agenteval.utils.webhook.get_settings") as mock_settings:
        mock_settings.return_value.webhook_url = "http://unreachable.example.com"
        mock_settings.return_value.webhook_secret = None

        with patch("agenteval.utils.webhook.httpx.AsyncClient") as MockClient:
            instance = MockClient.return_value.__aenter__.return_value
            instance.post = AsyncMock(side_effect=Exception("connection refused"))

            from agenteval.utils.webhook import send_run_webhook
            # Must not raise — errors are silently logged
            await send_run_webhook("run-1", "failed", {})
