95 lines
3.3 KiB
Python
95 lines
3.3 KiB
Python
from __future__ import annotations
|
|
|
|
import unittest
|
|
from types import SimpleNamespace
|
|
from unittest.mock import AsyncMock, patch
|
|
|
|
from pyrogram.enums import MessageEntityType
|
|
|
|
from app.commands.builtins import command_registry, txt
|
|
from app.transcription import TranscriptionError
|
|
|
|
|
|
class TxtCommandTests(unittest.IsolatedAsyncioTestCase):
|
|
def test_txt_is_registered_as_shared(self) -> None:
|
|
definition = command_registry.resolve("txt")
|
|
|
|
self.assertIsNotNone(definition)
|
|
self.assertTrue(definition.is_shared)
|
|
self.assertEqual(definition.guest_prefix, "..")
|
|
|
|
def _ctx(self, *, reply=None, args: str = ""):
|
|
message = SimpleNamespace(
|
|
id=123,
|
|
reply_to_message=reply,
|
|
react=AsyncMock(),
|
|
reply_text=AsyncMock(),
|
|
)
|
|
return SimpleNamespace(
|
|
args=args,
|
|
message=message,
|
|
replied_message=reply,
|
|
client=SimpleNamespace(download_media=AsyncMock(return_value="downloaded.ogg")),
|
|
manager=SimpleNamespace(
|
|
config=SimpleNamespace(elevenlabs=SimpleNamespace())
|
|
),
|
|
reply=message.reply_text,
|
|
)
|
|
|
|
async def test_invalid_usage_only_reacts_with_dislike(self) -> None:
|
|
ctx = self._ctx()
|
|
|
|
await txt(ctx)
|
|
|
|
ctx.message.react.assert_awaited_once_with("👎")
|
|
ctx.reply.assert_not_awaited()
|
|
ctx.client.download_media.assert_not_awaited()
|
|
|
|
async def test_api_error_only_reacts_with_dislike(self) -> None:
|
|
media = SimpleNamespace(mime_type="audio/ogg")
|
|
reply = SimpleNamespace(voice=media, video_note=None, video=None)
|
|
ctx = self._ctx(reply=reply)
|
|
|
|
with patch(
|
|
"app.commands.builtins.transcribe_file",
|
|
AsyncMock(side_effect=TranscriptionError("API failed")),
|
|
):
|
|
with self.assertLogs("app.commands.builtins", level="ERROR"):
|
|
await txt(ctx)
|
|
|
|
ctx.message.react.assert_awaited_once_with("👎")
|
|
ctx.reply.assert_not_awaited()
|
|
|
|
async def test_success_replies_with_expandable_blockquote(self) -> None:
|
|
media = SimpleNamespace(mime_type="video/mp4")
|
|
reply = SimpleNamespace(voice=None, video_note=media, video=None)
|
|
ctx = self._ctx(reply=reply)
|
|
|
|
with patch(
|
|
"app.commands.builtins.transcribe_file",
|
|
AsyncMock(return_value="Расшифрованный текст"),
|
|
) as transcribe:
|
|
await txt(ctx)
|
|
|
|
ctx.message.react.assert_not_awaited()
|
|
ctx.reply.assert_awaited_once()
|
|
self.assertEqual(ctx.reply.await_args.args[0], "Расшифрованный текст")
|
|
entity = ctx.reply.await_args.kwargs["entities"][0]
|
|
self.assertEqual(entity.type, MessageEntityType.BLOCKQUOTE)
|
|
self.assertTrue(entity.expandable)
|
|
transcribe.assert_awaited_once()
|
|
|
|
async def test_arguments_make_otherwise_valid_command_invalid(self) -> None:
|
|
media = SimpleNamespace(mime_type="video/mp4")
|
|
reply = SimpleNamespace(voice=None, video_note=None, video=media)
|
|
ctx = self._ctx(reply=reply, args="unexpected")
|
|
|
|
await txt(ctx)
|
|
|
|
ctx.message.react.assert_awaited_once_with("👎")
|
|
ctx.reply.assert_not_awaited()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|