diff --git a/tests/tools/test_send_message_tool.py b/tests/tools/test_send_message_tool.py index 7ef9b149d3..2b03847e5c 100644 --- a/tests/tools/test_send_message_tool.py +++ b/tests/tools/test_send_message_tool.py @@ -25,7 +25,7 @@ def _make_config(): def _install_telegram_mock(monkeypatch, bot): - parse_mode = SimpleNamespace(MARKDOWN_V2="MarkdownV2") + parse_mode = SimpleNamespace(MARKDOWN_V2="MarkdownV2", HTML="HTML") constants_mod = SimpleNamespace(ParseMode=parse_mode) telegram_mod = SimpleNamespace(Bot=lambda token: bot, constants=constants_mod) monkeypatch.setitem(sys.modules, "telegram", telegram_mod) @@ -391,3 +391,97 @@ class TestSendToPlatformChunking: assert len(sent_calls) >= 3 assert all(call == [] for call in sent_calls[:-1]) assert sent_calls[-1] == media + + +# --------------------------------------------------------------------------- +# HTML auto-detection in Telegram send +# --------------------------------------------------------------------------- + + +class TestSendTelegramHtmlDetection: + """Verify that messages containing HTML tags are sent with parse_mode=HTML + and that plain / markdown messages use MarkdownV2.""" + + def _make_bot(self): + bot = MagicMock() + bot.send_message = AsyncMock(return_value=SimpleNamespace(message_id=1)) + bot.send_photo = AsyncMock() + bot.send_video = AsyncMock() + bot.send_voice = AsyncMock() + bot.send_audio = AsyncMock() + bot.send_document = AsyncMock() + return bot + + def test_html_message_uses_html_parse_mode(self, monkeypatch): + bot = self._make_bot() + _install_telegram_mock(monkeypatch, bot) + + asyncio.run( + _send_telegram("tok", "123", "Hello world") + ) + + bot.send_message.assert_awaited_once() + kwargs = bot.send_message.await_args.kwargs + assert kwargs["parse_mode"] == "HTML" + assert kwargs["text"] == "Hello world" + + def test_plain_text_uses_markdown_v2(self, monkeypatch): + bot = self._make_bot() + _install_telegram_mock(monkeypatch, bot) + + asyncio.run( + _send_telegram("tok", "123", "Just plain text, no tags") + ) + + bot.send_message.assert_awaited_once() + kwargs = bot.send_message.await_args.kwargs + assert kwargs["parse_mode"] == "MarkdownV2" + + def test_html_with_code_and_pre_tags(self, monkeypatch): + bot = self._make_bot() + _install_telegram_mock(monkeypatch, bot) + + html = "
code blockand
inline"
+ asyncio.run(_send_telegram("tok", "123", html))
+
+ kwargs = bot.send_message.await_args.kwargs
+ assert kwargs["parse_mode"] == "HTML"
+
+ def test_closing_tag_detected(self, monkeypatch):
+ bot = self._make_bot()
+ _install_telegram_mock(monkeypatch, bot)
+
+ asyncio.run(_send_telegram("tok", "123", "text more"))
+
+ kwargs = bot.send_message.await_args.kwargs
+ assert kwargs["parse_mode"] == "HTML"
+
+ def test_angle_brackets_in_math_not_detected(self, monkeypatch):
+ """Expressions like 'x < 5' or '3 > 2' should not trigger HTML mode."""
+ bot = self._make_bot()
+ _install_telegram_mock(monkeypatch, bot)
+
+ asyncio.run(_send_telegram("tok", "123", "if x < 5 then y > 2"))
+
+ kwargs = bot.send_message.await_args.kwargs
+ assert kwargs["parse_mode"] == "MarkdownV2"
+
+ def test_html_parse_failure_falls_back_to_plain(self, monkeypatch):
+ """If Telegram rejects the HTML, fall back to plain text."""
+ bot = self._make_bot()
+ bot.send_message = AsyncMock(
+ side_effect=[
+ Exception("Bad Request: can't parse entities: unsupported html tag"),
+ SimpleNamespace(message_id=2), # plain fallback succeeds
+ ]
+ )
+ _install_telegram_mock(monkeypatch, bot)
+
+ result = asyncio.run(
+ _send_telegram("tok", "123", "