AgentEvalTool/tests/unit/test_webhook.py
sinohqb 5ecb30876e style(tests): ruff 全量清理 — 49 项修复,backend 与 tests 全绿
- ruff --fix 自动修正 44 项:移除未用 import(pytest 等)、import 块排序归一(I001)
- 手工修复剩余 5 项:test_cascade.py 两处未用赋值(F841);test_s2_rules_and_logic.py 中部 import 移至文件顶部(E402 ×3)
- 无行为变更:全量 492 项测试通过
2026-08-03 15:13:24 +08:00

83 lines
3.4 KiB
Python

"""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", {})