hermes-agent-features/tests/gateway/test_telegram_voice_ack.py

112 lines
3.3 KiB
Python

from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from gateway.config import Platform
from gateway.platforms.base import MessageEvent, MessageType, SendResult
from gateway.session import SessionSource
def _voice_event(thread_id=None) -> MessageEvent:
return MessageEvent(
text="",
message_type=MessageType.VOICE,
source=SessionSource(
platform=Platform.TELEGRAM,
chat_id="123",
chat_type="dm",
thread_id=thread_id,
message_id="42",
),
message_id="42",
)
@pytest.mark.asyncio
async def test_pre_stt_ack_is_best_effort_and_platform_side():
from gateway.platforms.telegram import TelegramAdapter
adapter = TelegramAdapter.__new__(TelegramAdapter)
adapter.send = AsyncMock(return_value=SendResult(success=True, message_id="99"))
event = _voice_event()
await adapter._send_voice_pre_stt_ack(event)
adapter.send.assert_awaited_once_with(
"123",
"🎧 получил, распознаю",
reply_to="42",
metadata=None,
)
@pytest.mark.asyncio
async def test_pre_stt_ack_failure_does_not_raise():
from gateway.platforms.telegram import TelegramAdapter
adapter = TelegramAdapter.__new__(TelegramAdapter)
adapter.send = AsyncMock(side_effect=RuntimeError("telegram is temporarily unavailable"))
await adapter._send_voice_pre_stt_ack(_voice_event())
adapter.send.assert_awaited_once()
@pytest.mark.asyncio
async def test_voice_handler_sends_ack_before_dispatching_to_gateway():
from gateway.platforms.telegram import TelegramAdapter
adapter = TelegramAdapter.__new__(TelegramAdapter)
adapter.platform = Platform.TELEGRAM
adapter.config = MagicMock()
adapter.config.extra = {}
order = []
adapter._should_process_message = lambda message: True
adapter._apply_telegram_group_observe_attribution = lambda event: event
adapter._send_voice_pre_stt_ack = AsyncMock(side_effect=lambda event: order.append("ack"))
adapter.handle_message = AsyncMock(side_effect=lambda event: order.append("handle"))
file_obj = MagicMock()
file_obj.download_as_bytearray = AsyncMock(return_value=bytearray(b"ogg-data"))
voice = MagicMock()
voice.get_file = AsyncMock(return_value=file_obj)
chat = MagicMock()
chat.id = 123
chat.type = "private"
chat.title = None
chat.full_name = "Тохыч"
user = MagicMock()
user.id = 456
user.full_name = "Тохыч"
msg = MagicMock()
msg.chat = chat
msg.from_user = user
msg.message_id = 42
msg.message_thread_id = None
msg.is_topic_message = False
msg.date = None
msg.caption = None
msg.text = ""
msg.reply_to_message = None
msg.sticker = None
msg.photo = []
msg.video = None
msg.audio = None
msg.voice = voice
msg.document = None
msg.media_group_id = None
update = MagicMock()
update.message = msg
update.update_id = 777
with patch("gateway.platforms.telegram.cache_audio_from_bytes", return_value="/tmp/voice.ogg"):
await adapter._handle_media_message(update, MagicMock())
assert order == ["ack", "handle"]
handled_event = adapter.handle_message.await_args.args[0]
assert handled_event.media_urls == ["/tmp/voice.ogg"]
assert handled_event.media_types == ["audio/ogg"]