agnes-the-ai-analyst/tests/test_telegram_bot.py
ZdenekSrotyr 5a651ca59c test: add Block C services tests (68 tests across 6 files)
Cover ws_gateway JWT auth, telegram storage user linking and verification
codes, telegram bot handlers, scheduler pure functions, corporate memory
collector hash detection and governance, and session file collection.
2026-04-12 11:11:48 +02:00

101 lines
4.3 KiB
Python

"""Tests for Telegram bot message handlers."""
import asyncio
import os
import sys
from unittest.mock import AsyncMock, patch
import pytest
def _make_message(text: str, chat_id: int = 10) -> dict:
return {"chat": {"id": chat_id}, "text": text}
def _run(coro):
"""Run a coroutine synchronously."""
return asyncio.get_event_loop().run_until_complete(coro)
@pytest.fixture(autouse=True, scope="module")
def patch_bot_log(tmp_path_factory):
"""Patch BOT_LOG_FILE before the bot module is imported so the FileHandler succeeds."""
log_dir = tmp_path_factory.mktemp("notify_bot")
log_file = str(log_dir / "bot.log")
import services.telegram_bot.config as cfg
original = cfg.BOT_LOG_FILE
cfg.BOT_LOG_FILE = log_file
# Remove cached bot module so it re-imports with patched config
sys.modules.pop("services.telegram_bot.bot", None)
yield
cfg.BOT_LOG_FILE = original
sys.modules.pop("services.telegram_bot.bot", None)
class TestHandleMessage:
def test_start_unlinked_user_generates_verification_code(self):
"""'/start' for an unlinked user generates and sends a verification code."""
with (
patch("services.telegram_bot.bot.get_username_by_chat_id", return_value=None),
patch("services.telegram_bot.bot.create_verification_code", return_value="123456") as mock_code,
patch("services.telegram_bot.bot.send_message", new_callable=AsyncMock) as mock_send,
):
from services.telegram_bot.bot import handle_message
_run(handle_message(_make_message("/start", chat_id=10)))
mock_code.assert_called_once_with(10)
mock_send.assert_called_once()
sent_text = mock_send.call_args[0][1]
assert "123456" in sent_text
def test_start_already_linked_user_no_code(self):
"""'/start' for an already-linked user does NOT generate a new code."""
with (
patch("services.telegram_bot.bot.get_username_by_chat_id", return_value="alice"),
patch("services.telegram_bot.bot.create_verification_code") as mock_code,
patch("services.telegram_bot.bot.send_message", new_callable=AsyncMock),
):
from services.telegram_bot.bot import handle_message
_run(handle_message(_make_message("/start", chat_id=10)))
mock_code.assert_not_called()
def test_help_returns_help_text(self):
"""'/help' sends a message containing help information."""
with patch("services.telegram_bot.bot.send_message", new_callable=AsyncMock) as mock_send:
from services.telegram_bot.bot import handle_message
_run(handle_message(_make_message("/help", chat_id=20)))
mock_send.assert_called_once()
sent_text = mock_send.call_args[0][1]
assert "/start" in sent_text
assert "/help" in sent_text
def test_unknown_command_sends_unknown_response(self):
"""An unknown command sends an 'Unknown command' reply."""
with patch("services.telegram_bot.bot.send_message", new_callable=AsyncMock) as mock_send:
from services.telegram_bot.bot import handle_message
_run(handle_message(_make_message("/foobar", chat_id=30)))
mock_send.assert_called_once()
sent_text = mock_send.call_args[0][1]
assert "Unknown" in sent_text or "unknown" in sent_text
def test_message_with_no_chat_id_is_ignored(self):
"""A message without a chat id does nothing."""
with patch("services.telegram_bot.bot.send_message", new_callable=AsyncMock) as mock_send:
from services.telegram_bot.bot import handle_message
_run(handle_message({"text": "/help"}))
mock_send.assert_not_called()
def test_whoami_linked_user_sends_username(self):
"""'/whoami' for a linked user sends the username."""
with (
patch("services.telegram_bot.bot.get_username_by_chat_id", return_value="dave"),
patch("services.telegram_bot.bot.send_message", new_callable=AsyncMock) as mock_send,
):
from services.telegram_bot.bot import handle_message
_run(handle_message(_make_message("/whoami", chat_id=40)))
mock_send.assert_called_once()
sent_text = mock_send.call_args[0][1]
assert "dave" in sent_text