Files
Pavel Eliseev 7780b484f3
CI / ruff · pytest (pull_request) Successful in 2m27s
feat(bot): add MAX notifications adapter and operator handoff
Refs #83
2026-10-04 16:10:30 +03:00

52 lines
1.8 KiB
Python

"""Operator tools do not send messages or expose credentials."""
from unittest.mock import AsyncMock
import pytest
from app.channels import max_setup
from app.channels.max_client import MaxApiError
from app.config import Settings
@pytest.fixture
def client(monkeypatch):
settings = Settings(_env_file=None, max_bot_username="test_bot", max_webhook_url="https://api.example.org/hook")
sender = AsyncMock()
sender.request.return_value = {"is_bot": True, "username": "test_bot"}
monkeypatch.setattr(max_setup, "Settings", lambda **kwargs: settings)
monkeypatch.setattr(max_setup, "MaxClient", lambda cfg: sender)
return sender
async def test_check_only_reads_bot_identity(client):
await max_setup.run("check")
client.request.assert_awaited_once_with("GET", "/me")
client.subscribe.assert_not_called()
client.send.assert_not_called()
client.close.assert_awaited_once()
async def test_subscribe_is_explicit_and_checks_bot_first(client):
await max_setup.run("subscribe")
client.subscribe.assert_awaited_once()
client.send.assert_not_called()
async def test_mismatched_bot_does_not_change_webhooks(client):
client.request.return_value = {"is_bot": True, "username": "another_bot"}
with pytest.raises(MaxApiError, match="bot_username_mismatch"):
await max_setup.run("subscribe")
client.subscribe.assert_not_called()
client.close.assert_awaited_once()
async def test_status_checks_exact_configured_webhook(client):
client.request.side_effect = [
{"is_bot": True, "username": "test_bot"},
{"subscriptions": [{"url": "https://elsewhere.example.org"}]},
]
with pytest.raises(MaxApiError, match="webhook_missing"):
await max_setup.run("status")
client.subscribe.assert_not_called()