Files
hermes-agent/tests/gateway/test_telegram_voice_caption_markdown.py
T
kshitijk4poor c1693d7dcc refactor: remove 27 duplicate _ensure_telegram_mock() copies from gateway tests
tests/gateway/conftest.py already installs a comprehensive telegram mock
at collection time (line 330), before any test module's imports run.
The per-file copies were fully redundant — each was a simpler subset
(plain strings, setdefault, fewer error classes) of the conftest version
(which uses _fake_str_enum for PTB-faithful StrEnum semantics, sys.modules
overwrite to win over partial/broken imports, and a full error hierarchy
including BadRequest, Forbidden, RetryAfter, Conflict, InvalidToken).

Removed: function def + module-level call + now-unused imports (sys,
MagicMock where no longer referenced) + dangling comment blocks that
referenced the deleted mock, in 27 test files.
Left untouched: tests/gateway/conftest.py (canonical source) and
tests/e2e/conftest.py (separate conftest tree that may run in isolation).

Found by /simplify-code review of PR #90560.
2026-08-21 16:25:24 +05:30

60 lines
2.0 KiB
Python

"""Telegram voice-message captions must render markdown (#32029).
``TelegramAdapter.send_voice`` used to pass captions raw with no
``parse_mode``, so auto-TTS captions carrying the agent's markdown reply
showed literal *asterisks*, backticks and [links](...). It now formats the
caption to MarkdownV2 (when the formatted text fits the 1024-char caption
cap) and falls back to the plain truncated caption when the Bot API rejects
the entities or formatting overflows.
"""
from unittest.mock import AsyncMock, MagicMock
import pytest
from gateway.config import PlatformConfig
from plugins.platforms.telegram import adapter as telegram_mod # noqa: E402
from plugins.platforms.telegram.adapter import TelegramAdapter # noqa: E402
def _make_adapter() -> TelegramAdapter:
adapter = TelegramAdapter(PlatformConfig(enabled=True, token="***"))
adapter._bot = MagicMock()
adapter._bot.send_voice = AsyncMock(return_value=MagicMock(message_id=1))
adapter._bot.send_audio = AsyncMock(return_value=MagicMock(message_id=2))
return adapter
def _write_ogg(tmp_path):
audio = tmp_path / "reply.ogg"
audio.write_bytes(b"\x00" * 16)
return audio
@pytest.mark.asyncio
async def test_voice_caption_falls_back_to_plain_on_entity_rejection(
monkeypatch, tmp_path
):
"""A Bot API entity-parse rejection retries with the plain caption."""
monkeypatch.setattr(
telegram_mod, "_probe_voice_duration_seconds", lambda _p: 3
)
adapter = _make_adapter()
adapter._bot.send_voice = AsyncMock(
side_effect=[
Exception("Bad Request: can't parse entities"),
MagicMock(message_id=7),
]
)
result = await adapter.send_voice(
"123", str(_write_ogg(tmp_path)), caption="*bold* reply"
)
assert result.success is True
assert adapter._bot.send_voice.await_count == 2
retry_kwargs = adapter._bot.send_voice.await_args_list[1].kwargs
assert retry_kwargs["parse_mode"] is None
assert retry_kwargs["caption"] == "*bold* reply"