refactor(telegram): msgspec schemas and parsing (#156)
This commit is contained in:
@@ -141,7 +141,7 @@ class FakeBot(BotClient):
|
||||
"replace_message_id": replace_message_id,
|
||||
}
|
||||
)
|
||||
return Message(message_id=1)
|
||||
return Message(message_id=1, chat=Chat(id=chat_id, type="private"))
|
||||
|
||||
async def send_document(
|
||||
self,
|
||||
@@ -164,7 +164,7 @@ class FakeBot(BotClient):
|
||||
"caption": caption,
|
||||
}
|
||||
)
|
||||
return Message(message_id=2)
|
||||
return Message(message_id=2, chat=Chat(id=chat_id, type="private"))
|
||||
|
||||
async def edit_message_text(
|
||||
self,
|
||||
@@ -188,7 +188,7 @@ class FakeBot(BotClient):
|
||||
"wait": wait,
|
||||
}
|
||||
)
|
||||
return Message(message_id=message_id)
|
||||
return Message(message_id=message_id, chat=Chat(id=chat_id, type="private"))
|
||||
|
||||
async def delete_message(self, chat_id: int, message_id: int) -> bool:
|
||||
self.delete_calls.append({"chat_id": chat_id, "message_id": message_id})
|
||||
|
||||
@@ -9,7 +9,7 @@ from rich.text import Text
|
||||
|
||||
from takopi.config import ConfigError
|
||||
from takopi.telegram import onboarding
|
||||
from takopi.telegram.api_models import Update, User
|
||||
from takopi.telegram.api_models import Chat, Message, Update, User
|
||||
from takopi.telegram.client import TelegramRetryAfter
|
||||
|
||||
|
||||
@@ -311,35 +311,57 @@ async def test_get_bot_info_gives_up(monkeypatch) -> None:
|
||||
@pytest.mark.anyio
|
||||
async def test_wait_for_chat_filters_updates(monkeypatch) -> None:
|
||||
updates = [
|
||||
[Update(update_id=1, message={"from": {"is_bot": True}, "chat": {"id": 1}})],
|
||||
[
|
||||
Update(
|
||||
update_id=1,
|
||||
message=Message(
|
||||
message_id=1,
|
||||
from_=User(id=1, is_bot=True),
|
||||
chat=Chat(id=1, type="private"),
|
||||
),
|
||||
)
|
||||
],
|
||||
None,
|
||||
[],
|
||||
[Update(update_id=2, message=None)],
|
||||
[
|
||||
Update(
|
||||
update_id=3,
|
||||
message={"from": {"is_bot": True}, "chat": {"id": 2}},
|
||||
message=Message(
|
||||
message_id=3,
|
||||
from_=User(id=2, is_bot=True),
|
||||
chat=Chat(id=2, type="private"),
|
||||
),
|
||||
)
|
||||
],
|
||||
[
|
||||
Update(
|
||||
update_id=4,
|
||||
message={"from": {"is_bot": False}, "chat": "nope"},
|
||||
message=Message(
|
||||
message_id=4,
|
||||
from_=User(id=3, is_bot=True),
|
||||
chat=Chat(id=3, type="private"),
|
||||
),
|
||||
)
|
||||
],
|
||||
[
|
||||
Update(
|
||||
update_id=5,
|
||||
message={"from": {"is_bot": False}, "chat": {"id": "bad"}},
|
||||
message=Message(
|
||||
message_id=5,
|
||||
from_=User(id=4, is_bot=True),
|
||||
chat=Chat(id=4, type="private"),
|
||||
),
|
||||
)
|
||||
],
|
||||
[
|
||||
Update(
|
||||
update_id=6,
|
||||
message={
|
||||
"from": {"is_bot": False},
|
||||
"chat": {"id": 7, "username": "bob", "type": "private"},
|
||||
},
|
||||
message=Message(
|
||||
message_id=6,
|
||||
from_=User(id=5, is_bot=False),
|
||||
chat=Chat(id=7, username="bob", type="private"),
|
||||
),
|
||||
)
|
||||
],
|
||||
]
|
||||
|
||||
@@ -14,7 +14,7 @@ from takopi.telegram.commands.topics import _handle_topic_command
|
||||
import takopi.telegram.loop as telegram_loop
|
||||
import takopi.telegram.topics as telegram_topics
|
||||
from takopi.directives import parse_directives
|
||||
from takopi.telegram.api_models import File, ForumTopic, Message, Update, User
|
||||
from takopi.telegram.api_models import Chat, File, ForumTopic, Message, Update, User
|
||||
from takopi.settings import TelegramFilesSettings, TelegramTopicsSettings
|
||||
from takopi.telegram.bridge import (
|
||||
TelegramBridgeConfig,
|
||||
@@ -462,7 +462,7 @@ async def test_telegram_transport_edit_wait_false_returns_ref() -> None:
|
||||
)
|
||||
if not wait:
|
||||
return None
|
||||
return Message(message_id=message_id)
|
||||
return Message(message_id=message_id, chat=Chat(id=chat_id, type="private"))
|
||||
|
||||
async def delete_message(
|
||||
self,
|
||||
|
||||
@@ -71,9 +71,9 @@ async def test_client_methods_build_params_and_decode() -> None:
|
||||
payloads = {
|
||||
"getUpdates": [{"update_id": 1}],
|
||||
"getFile": {"file_path": "path"},
|
||||
"sendMessage": {"message_id": 1},
|
||||
"sendDocument": {"message_id": 2},
|
||||
"editMessageText": {"message_id": 3},
|
||||
"sendMessage": {"message_id": 1, "chat": {"id": 1, "type": "private"}},
|
||||
"sendDocument": {"message_id": 2, "chat": {"id": 1, "type": "private"}},
|
||||
"editMessageText": {"message_id": 3, "chat": {"id": 1, "type": "private"}},
|
||||
"deleteMessage": True,
|
||||
"setMyCommands": True,
|
||||
"getMe": {"id": 7},
|
||||
|
||||
+156
-149
@@ -3,23 +3,37 @@ from takopi.telegram import (
|
||||
TelegramIncomingMessage,
|
||||
parse_incoming_update,
|
||||
)
|
||||
from takopi.telegram.api_models import (
|
||||
CallbackQuery,
|
||||
CallbackQueryMessage,
|
||||
Chat,
|
||||
Document,
|
||||
Message,
|
||||
MessageReply,
|
||||
PhotoSize,
|
||||
Sticker,
|
||||
Update,
|
||||
User,
|
||||
Video,
|
||||
Voice,
|
||||
)
|
||||
|
||||
|
||||
def test_parse_incoming_update_maps_fields() -> None:
|
||||
update = {
|
||||
"update_id": 1,
|
||||
"message": {
|
||||
"message_id": 10,
|
||||
"text": "hello",
|
||||
"chat": {"id": 123, "type": "supergroup", "is_forum": True},
|
||||
"from": {"id": 99},
|
||||
"reply_to_message": {
|
||||
"message_id": 5,
|
||||
"text": "prev",
|
||||
"from": {"id": 77, "is_bot": True, "username": "ReplyBot"},
|
||||
},
|
||||
},
|
||||
}
|
||||
update = Update(
|
||||
update_id=1,
|
||||
message=Message(
|
||||
message_id=10,
|
||||
text="hello",
|
||||
chat=Chat(id=123, type="supergroup", is_forum=True),
|
||||
from_=User(id=99),
|
||||
reply_to_message=MessageReply(
|
||||
message_id=5,
|
||||
text="prev",
|
||||
from_=User(id=77, is_bot=True, username="ReplyBot"),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
msg = parse_incoming_update(update, chat_id=123)
|
||||
assert msg is not None
|
||||
@@ -39,50 +53,49 @@ def test_parse_incoming_update_maps_fields() -> None:
|
||||
assert msg.is_forum is True
|
||||
assert msg.voice is None
|
||||
assert msg.document is None
|
||||
assert msg.raw == update["message"]
|
||||
assert msg.raw
|
||||
assert msg.raw["message_id"] == 10
|
||||
|
||||
|
||||
def test_parse_incoming_update_filters_non_matching_chat() -> None:
|
||||
update = {
|
||||
"update_id": 1,
|
||||
"message": {
|
||||
"message_id": 10,
|
||||
"text": "hello",
|
||||
"chat": {"id": 123},
|
||||
},
|
||||
}
|
||||
update = Update(
|
||||
update_id=1,
|
||||
message=Message(
|
||||
message_id=10,
|
||||
text="hello",
|
||||
chat=Chat(id=123, type="private"),
|
||||
),
|
||||
)
|
||||
|
||||
assert parse_incoming_update(update, chat_id=999) is None
|
||||
|
||||
|
||||
def test_parse_incoming_update_filters_non_text_and_non_voice() -> None:
|
||||
update = {
|
||||
"update_id": 1,
|
||||
"message": {
|
||||
"message_id": 10,
|
||||
"chat": {"id": 123},
|
||||
"location": {"latitude": 1.0, "longitude": 2.0},
|
||||
},
|
||||
}
|
||||
update = Update(
|
||||
update_id=1,
|
||||
message=Message(
|
||||
message_id=10,
|
||||
chat=Chat(id=123, type="private"),
|
||||
),
|
||||
)
|
||||
|
||||
assert parse_incoming_update(update, chat_id=123) is None
|
||||
|
||||
|
||||
def test_parse_incoming_update_voice_message() -> None:
|
||||
update = {
|
||||
"update_id": 1,
|
||||
"message": {
|
||||
"message_id": 10,
|
||||
"chat": {"id": 123},
|
||||
"voice": {
|
||||
"file_id": "voice-id",
|
||||
"file_unique_id": "uniq",
|
||||
"duration": 3,
|
||||
"mime_type": "audio/ogg",
|
||||
"file_size": 1234,
|
||||
},
|
||||
},
|
||||
}
|
||||
update = Update(
|
||||
update_id=1,
|
||||
message=Message(
|
||||
message_id=10,
|
||||
chat=Chat(id=123, type="private"),
|
||||
voice=Voice(
|
||||
file_id="voice-id",
|
||||
duration=3,
|
||||
mime_type="audio/ogg",
|
||||
file_size=1234,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
msg = parse_incoming_update(update, chat_id=123)
|
||||
assert msg is not None
|
||||
@@ -96,21 +109,20 @@ def test_parse_incoming_update_voice_message() -> None:
|
||||
|
||||
|
||||
def test_parse_incoming_update_document_message() -> None:
|
||||
update = {
|
||||
"update_id": 1,
|
||||
"message": {
|
||||
"message_id": 10,
|
||||
"caption": "/file put incoming/doc.txt",
|
||||
"chat": {"id": 123},
|
||||
"document": {
|
||||
"file_id": "doc-id",
|
||||
"file_unique_id": "uniq",
|
||||
"file_name": "doc.txt",
|
||||
"mime_type": "text/plain",
|
||||
"file_size": 4321,
|
||||
},
|
||||
},
|
||||
}
|
||||
update = Update(
|
||||
update_id=1,
|
||||
message=Message(
|
||||
message_id=10,
|
||||
caption="/file put incoming/doc.txt",
|
||||
chat=Chat(id=123, type="private"),
|
||||
document=Document(
|
||||
file_id="doc-id",
|
||||
file_name="doc.txt",
|
||||
mime_type="text/plain",
|
||||
file_size=4321,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
msg = parse_incoming_update(update, chat_id=123)
|
||||
assert msg is not None
|
||||
@@ -124,30 +136,28 @@ def test_parse_incoming_update_document_message() -> None:
|
||||
|
||||
|
||||
def test_parse_incoming_update_photo_message() -> None:
|
||||
update = {
|
||||
"update_id": 1,
|
||||
"message": {
|
||||
"message_id": 10,
|
||||
"caption": "/file put incoming/photo.jpg",
|
||||
"chat": {"id": 123},
|
||||
"photo": [
|
||||
{
|
||||
"file_id": "small",
|
||||
"file_unique_id": "uniq-small",
|
||||
"file_size": 100,
|
||||
"width": 90,
|
||||
"height": 90,
|
||||
},
|
||||
{
|
||||
"file_id": "large",
|
||||
"file_unique_id": "uniq-large",
|
||||
"file_size": 1000,
|
||||
"width": 800,
|
||||
"height": 600,
|
||||
},
|
||||
update = Update(
|
||||
update_id=1,
|
||||
message=Message(
|
||||
message_id=10,
|
||||
caption="/file put incoming/photo.jpg",
|
||||
chat=Chat(id=123, type="private"),
|
||||
photo=[
|
||||
PhotoSize(
|
||||
file_id="small",
|
||||
file_size=100,
|
||||
width=90,
|
||||
height=90,
|
||||
),
|
||||
PhotoSize(
|
||||
file_id="large",
|
||||
file_size=1000,
|
||||
width=800,
|
||||
height=600,
|
||||
),
|
||||
],
|
||||
},
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
msg = parse_incoming_update(update, chat_id=123)
|
||||
assert msg is not None
|
||||
@@ -160,23 +170,22 @@ def test_parse_incoming_update_photo_message() -> None:
|
||||
|
||||
|
||||
def test_parse_incoming_update_media_group_id() -> None:
|
||||
update = {
|
||||
"update_id": 1,
|
||||
"message": {
|
||||
"message_id": 10,
|
||||
"chat": {"id": 123},
|
||||
"media_group_id": "group-1",
|
||||
"photo": [
|
||||
{
|
||||
"file_id": "large",
|
||||
"file_unique_id": "uniq-large",
|
||||
"file_size": 1000,
|
||||
"width": 800,
|
||||
"height": 600,
|
||||
}
|
||||
update = Update(
|
||||
update_id=1,
|
||||
message=Message(
|
||||
message_id=10,
|
||||
chat=Chat(id=123, type="private"),
|
||||
media_group_id="group-1",
|
||||
photo=[
|
||||
PhotoSize(
|
||||
file_id="large",
|
||||
file_size=1000,
|
||||
width=800,
|
||||
height=600,
|
||||
)
|
||||
],
|
||||
},
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
msg = parse_incoming_update(update, chat_id=123)
|
||||
assert msg is not None
|
||||
@@ -185,21 +194,20 @@ def test_parse_incoming_update_media_group_id() -> None:
|
||||
|
||||
|
||||
def test_parse_incoming_update_video_message() -> None:
|
||||
update = {
|
||||
"update_id": 1,
|
||||
"message": {
|
||||
"message_id": 10,
|
||||
"caption": "/file put incoming/video.mp4",
|
||||
"chat": {"id": 123},
|
||||
"video": {
|
||||
"file_id": "video-id",
|
||||
"file_unique_id": "uniq",
|
||||
"file_name": "video.mp4",
|
||||
"mime_type": "video/mp4",
|
||||
"file_size": 4242,
|
||||
},
|
||||
},
|
||||
}
|
||||
update = Update(
|
||||
update_id=1,
|
||||
message=Message(
|
||||
message_id=10,
|
||||
caption="/file put incoming/video.mp4",
|
||||
chat=Chat(id=123, type="private"),
|
||||
video=Video(
|
||||
file_id="video-id",
|
||||
file_name="video.mp4",
|
||||
mime_type="video/mp4",
|
||||
file_size=4242,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
msg = parse_incoming_update(update, chat_id=123)
|
||||
assert msg is not None
|
||||
@@ -213,19 +221,18 @@ def test_parse_incoming_update_video_message() -> None:
|
||||
|
||||
|
||||
def test_parse_incoming_update_sticker_message() -> None:
|
||||
update = {
|
||||
"update_id": 1,
|
||||
"message": {
|
||||
"message_id": 10,
|
||||
"caption": "/file put incoming/sticker.webp",
|
||||
"chat": {"id": 123},
|
||||
"sticker": {
|
||||
"file_id": "sticker-id",
|
||||
"file_unique_id": "uniq",
|
||||
"file_size": 2468,
|
||||
},
|
||||
},
|
||||
}
|
||||
update = Update(
|
||||
update_id=1,
|
||||
message=Message(
|
||||
message_id=10,
|
||||
caption="/file put incoming/sticker.webp",
|
||||
chat=Chat(id=123, type="private"),
|
||||
sticker=Sticker(
|
||||
file_id="sticker-id",
|
||||
file_size=2468,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
msg = parse_incoming_update(update, chat_id=123)
|
||||
assert msg is not None
|
||||
@@ -239,18 +246,18 @@ def test_parse_incoming_update_sticker_message() -> None:
|
||||
|
||||
|
||||
def test_parse_incoming_update_callback_query() -> None:
|
||||
update = {
|
||||
"update_id": 1,
|
||||
"callback_query": {
|
||||
"id": "cbq-1",
|
||||
"data": "takopi:cancel",
|
||||
"from": {"id": 321},
|
||||
"message": {
|
||||
"message_id": 55,
|
||||
"chat": {"id": 123},
|
||||
},
|
||||
},
|
||||
}
|
||||
update = Update(
|
||||
update_id=1,
|
||||
callback_query=CallbackQuery(
|
||||
id="cbq-1",
|
||||
data="takopi:cancel",
|
||||
from_=User(id=321),
|
||||
message=CallbackQueryMessage(
|
||||
message_id=55,
|
||||
chat=Chat(id=123, type="private"),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
msg = parse_incoming_update(update, chat_id=123)
|
||||
assert isinstance(msg, TelegramCallbackQuery)
|
||||
@@ -263,16 +270,16 @@ def test_parse_incoming_update_callback_query() -> None:
|
||||
|
||||
|
||||
def test_parse_incoming_update_topic_fields() -> None:
|
||||
update = {
|
||||
"update_id": 1,
|
||||
"message": {
|
||||
"message_id": 10,
|
||||
"text": "hello",
|
||||
"message_thread_id": 77,
|
||||
"is_topic_message": True,
|
||||
"chat": {"id": -100, "type": "supergroup", "is_forum": True},
|
||||
},
|
||||
}
|
||||
update = Update(
|
||||
update_id=1,
|
||||
message=Message(
|
||||
message_id=10,
|
||||
text="hello",
|
||||
message_thread_id=77,
|
||||
is_topic_message=True,
|
||||
chat=Chat(id=-100, type="supergroup", is_forum=True),
|
||||
),
|
||||
)
|
||||
|
||||
msg = parse_incoming_update(update, chat_id=-100)
|
||||
assert isinstance(msg, TelegramIncomingMessage)
|
||||
|
||||
@@ -3,7 +3,7 @@ from typing import Any
|
||||
import anyio
|
||||
import pytest
|
||||
|
||||
from takopi.telegram.api_models import File, Message, Update, User
|
||||
from takopi.telegram.api_models import Chat, File, Message, Update, User
|
||||
from takopi.telegram.client import BotClient, TelegramClient, TelegramRetryAfter
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ class FakeBot(BotClient):
|
||||
_ = reply_markup
|
||||
_ = replace_message_id
|
||||
self.calls.append("send_message")
|
||||
return Message(message_id=1)
|
||||
return Message(message_id=1, chat=Chat(id=chat_id, type="private"))
|
||||
|
||||
async def send_document(
|
||||
self,
|
||||
@@ -61,7 +61,7 @@ class FakeBot(BotClient):
|
||||
caption,
|
||||
)
|
||||
self.calls.append("send_document")
|
||||
return Message(message_id=1)
|
||||
return Message(message_id=1, chat=Chat(id=chat_id, type="private"))
|
||||
|
||||
async def edit_message_text(
|
||||
self,
|
||||
@@ -86,7 +86,7 @@ class FakeBot(BotClient):
|
||||
self._edit_attempts += 1
|
||||
raise TelegramRetryAfter(self.retry_after)
|
||||
self._edit_attempts += 1
|
||||
return Message(message_id=message_id)
|
||||
return Message(message_id=message_id, chat=Chat(id=chat_id, type="private"))
|
||||
|
||||
async def delete_message(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user