mirror of
https://github.com/Alishahryar1/free-claude-code.git
synced 2026-04-28 03:20:01 +00:00
- Add local web_search/web_fetch SSE handling and optional tool schemas - Extend HeuristicToolParser for JSON-style WebFetch/WebSearch text - Consolidate provider defaults, ids, and exception typing; stream contracts - Messaging: typed options, voice config injection, platform contract cleanup - Tests for web server tools, converters, parsers, contracts; ignore debug-*.log
176 lines
6 KiB
Python
176 lines
6 KiB
Python
"""Tests for voice note handling in Telegram and Discord platforms."""
|
|
|
|
import tempfile
|
|
from pathlib import Path
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from messaging.platforms.discord import DISCORD_AVAILABLE, DiscordPlatform
|
|
from messaging.platforms.telegram import TelegramPlatform
|
|
|
|
|
|
@pytest.fixture
|
|
def telegram_platform():
|
|
with patch("messaging.platforms.telegram.TELEGRAM_AVAILABLE", True):
|
|
return TelegramPlatform(bot_token="test_token", allowed_user_id="12345")
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_telegram_voice_disabled_sends_reply():
|
|
"""When voice_note_enabled is False, reply with disabled message."""
|
|
with patch("messaging.platforms.telegram.TELEGRAM_AVAILABLE", True):
|
|
telegram_platform = TelegramPlatform(
|
|
bot_token="test_token",
|
|
allowed_user_id="12345",
|
|
voice_note_enabled=False,
|
|
)
|
|
mock_update = MagicMock()
|
|
mock_update.message.voice = MagicMock(file_id="f1", mime_type="audio/ogg")
|
|
mock_update.effective_user.id = 12345
|
|
mock_update.effective_chat.id = 6789
|
|
mock_update.message.reply_text = AsyncMock()
|
|
|
|
await telegram_platform._on_telegram_voice(mock_update, MagicMock())
|
|
|
|
mock_update.message.reply_text.assert_called_once_with("Voice notes are disabled.")
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_telegram_voice_unauthorized_ignored(telegram_platform):
|
|
"""Voice from unauthorized user is ignored (no reply)."""
|
|
mock_update = MagicMock()
|
|
mock_update.message.voice = MagicMock(file_id="f1", mime_type="audio/ogg")
|
|
mock_update.effective_user.id = 99999 # Not 12345
|
|
mock_update.message.reply_text = AsyncMock()
|
|
|
|
await telegram_platform._on_telegram_voice(mock_update, MagicMock())
|
|
|
|
mock_update.message.reply_text.assert_not_called()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_telegram_voice_success_invokes_handler(telegram_platform):
|
|
"""Successful transcription invokes message handler with transcribed text."""
|
|
handler = AsyncMock()
|
|
telegram_platform.on_message(handler)
|
|
|
|
mock_update = MagicMock()
|
|
mock_voice = MagicMock(file_id="f1", mime_type="audio/ogg")
|
|
mock_update.message.voice = mock_voice
|
|
mock_update.message.message_id = 42
|
|
mock_update.message.reply_to_message = None
|
|
mock_update.effective_user.id = 12345
|
|
mock_update.effective_chat.id = 6789
|
|
mock_update.message.reply_text = AsyncMock()
|
|
|
|
mock_file = AsyncMock()
|
|
mock_context = MagicMock()
|
|
mock_context.bot.get_file = AsyncMock(return_value=mock_file)
|
|
|
|
with tempfile.NamedTemporaryFile(suffix=".ogg", delete=False) as f:
|
|
f.write(b"fake")
|
|
tmp_path = Path(f.name)
|
|
|
|
try:
|
|
|
|
async def fake_download(custom_path=None):
|
|
if custom_path:
|
|
Path(custom_path).write_bytes(b"fake ogg")
|
|
|
|
mock_file.download_to_drive = fake_download
|
|
|
|
mock_queue_send = AsyncMock(return_value="999")
|
|
with (
|
|
patch(
|
|
"messaging.transcription.transcribe_audio",
|
|
return_value="Hello from voice",
|
|
),
|
|
patch.object(
|
|
telegram_platform,
|
|
"queue_send_message",
|
|
mock_queue_send,
|
|
),
|
|
):
|
|
await telegram_platform._on_telegram_voice(mock_update, mock_context)
|
|
|
|
mock_queue_send.assert_called_once()
|
|
call_args, call_kw = mock_queue_send.call_args
|
|
assert "Transcribing voice note" in call_args[1]
|
|
assert call_kw["reply_to"] == "42"
|
|
assert call_kw["fire_and_forget"] is False
|
|
|
|
handler.assert_called_once()
|
|
incoming = handler.call_args[0][0]
|
|
assert incoming.text == "Hello from voice"
|
|
assert incoming.chat_id == "6789"
|
|
assert incoming.user_id == "12345"
|
|
assert incoming.platform == "telegram"
|
|
assert incoming.status_message_id == "999"
|
|
finally:
|
|
tmp_path.unlink(missing_ok=True)
|
|
|
|
|
|
@pytest.mark.skipif(not DISCORD_AVAILABLE, reason="discord.py not installed")
|
|
class TestDiscordGetAudioAttachment:
|
|
"""Tests for _get_audio_attachment helper."""
|
|
|
|
def test_returns_none_when_no_attachments(self):
|
|
platform = DiscordPlatform(bot_token="token")
|
|
msg = MagicMock()
|
|
msg.attachments = []
|
|
assert platform._get_audio_attachment(msg) is None
|
|
|
|
def test_returns_none_when_no_audio_attachments(self):
|
|
platform = DiscordPlatform(bot_token="token")
|
|
msg = MagicMock()
|
|
att = MagicMock()
|
|
att.content_type = "image/png"
|
|
att.filename = "pic.png"
|
|
msg.attachments = [att]
|
|
assert platform._get_audio_attachment(msg) is None
|
|
|
|
def test_returns_attachment_by_content_type(self):
|
|
platform = DiscordPlatform(bot_token="token")
|
|
msg = MagicMock()
|
|
att = MagicMock()
|
|
att.content_type = "audio/ogg"
|
|
att.filename = "voice.ogg"
|
|
msg.attachments = [att]
|
|
assert platform._get_audio_attachment(msg) is att
|
|
|
|
def test_returns_attachment_by_extension(self):
|
|
platform = DiscordPlatform(bot_token="token")
|
|
msg = MagicMock()
|
|
att = MagicMock()
|
|
att.content_type = "application/octet-stream"
|
|
att.filename = "voice.ogg"
|
|
msg.attachments = [att]
|
|
assert platform._get_audio_attachment(msg) is att
|
|
|
|
|
|
@pytest.mark.skipif(not DISCORD_AVAILABLE, reason="discord.py not installed")
|
|
@pytest.mark.asyncio
|
|
async def test_discord_voice_disabled_sends_reply():
|
|
"""When voice_note_enabled is False, reply with disabled message."""
|
|
platform = DiscordPlatform(
|
|
bot_token="token",
|
|
allowed_channel_ids="123",
|
|
voice_note_enabled=False,
|
|
)
|
|
platform._message_handler = None
|
|
|
|
mock_message = MagicMock()
|
|
mock_message.author.bot = False
|
|
mock_message.content = None
|
|
mock_message.channel.id = 123
|
|
mock_message.reply = AsyncMock()
|
|
|
|
mock_att = MagicMock()
|
|
mock_att.content_type = "audio/ogg"
|
|
mock_att.filename = "voice.ogg"
|
|
mock_message.attachments = [mock_att]
|
|
|
|
await platform._on_discord_message(mock_message)
|
|
|
|
mock_message.reply.assert_called_once_with("Voice notes are disabled.")
|