Merge remote-tracking branch 'origin/dev-3.x' into dev-3.x

# Conflicts:
#	README.md
#	README.rst
#	aiogram/__init__.py
#	aiogram/bot/bot.py
#	aiogram/contrib/fsm_storage/redis.py
#	aiogram/contrib/middlewares/logging.py
#	aiogram/dispatcher/dispatcher.py
#	aiogram/dispatcher/filters/__init__.py
#	aiogram/dispatcher/filters/builtin.py
#	aiogram/dispatcher/filters/filters.py
#	aiogram/dispatcher/filters/state.py
#	aiogram/dispatcher/handler.py
#	aiogram/dispatcher/webhook.py
#	aiogram/types/base.py
#	aiogram/types/chat.py
#	aiogram/types/chat_member.py
#	aiogram/types/input_media.py
#	aiogram/types/message.py
#	aiogram/utils/callback_data.py
#	aiogram/utils/deprecated.py
#	aiogram/utils/exceptions.py
#	aiogram/utils/executor.py
#	aiogram/utils/helper.py
#	aiogram/utils/json.py
#	aiogram/utils/mixins.py
#	aiogram/utils/payload.py
#	dev_requirements.txt
#	docs/source/index.rst
#	examples/callback_data_factory.py
#	examples/check_user_language.py
#	examples/echo_bot.py
#	examples/finite_state_machine_example.py
#	examples/i18n_example.py
#	examples/inline_bot.py
#	examples/media_group.py
#	examples/middleware_and_antiflood.py
#	examples/payments.py
#	examples/proxy_and_emojize.py
#	examples/regexp_commands_filter_example.py
#	examples/throtling_example.py
#	examples/webhook_example.py
#	examples/webhook_example_2.py
#	setup.py
#	tests/test_bot.py
#	tests/test_token.py
#	tests/types/dataset.py
This commit is contained in:
Alex Root Junior 2019-11-03 22:19:44 +02:00
commit 87393f2475
98 changed files with 5048 additions and 4854 deletions

View file

@ -3,7 +3,7 @@ import pytest
from aiogram import Bot, types
TOKEN = "123456789:AABBCCDDEEFFaabbccddeeff-1234567890"
TOKEN = '123456789:AABBCCDDEEFFaabbccddeeff-1234567890'
class FakeTelegram(aresponses.ResponsesMockServer):
@ -13,25 +13,23 @@ class FakeTelegram(aresponses.ResponsesMockServer):
async def __aenter__(self):
await super().__aenter__()
_response = self.Response(text=self._body, headers=self._headers, status=200, reason="OK")
_response = self.Response(text=self._body, headers=self._headers, status=200, reason='OK')
self.add(self.ANY, response=_response)
@staticmethod
def parse_data(message_dict):
import json
_body = '{"ok":true,"result":' + json.dumps(message_dict) + "}"
_headers = {
"Server": "nginx/1.12.2",
"Date": "Tue, 03 Apr 2018 16:59:54 GMT",
"Content-Type": "application/json",
"Content-Length": str(len(_body)),
"Connection": "keep-alive",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Expose-Headers": "Content-Length,Content-Type,Date,Server,Connection",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains",
}
_body = '{"ok":true,"result":' + json.dumps(message_dict) + '}'
_headers = {'Server': 'nginx/1.12.2',
'Date': 'Tue, 03 Apr 2018 16:59:54 GMT',
'Content-Type': 'application/json',
'Content-Length': str(len(_body)),
'Connection': 'keep-alive',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Expose-Headers': 'Content-Length,Content-Type,Date,Server,Connection',
'Strict-Transport-Security': 'max-age=31536000; includeSubdomains'}
return _body, _headers
@ -48,7 +46,6 @@ async def bot(event_loop):
async def test_get_me(bot: Bot, event_loop):
""" getMe method test """
from .types.dataset import USER
user = types.User(**USER)
async with FakeTelegram(message_dict=USER, loop=event_loop):
@ -60,7 +57,6 @@ async def test_get_me(bot: Bot, event_loop):
async def test_send_message(bot: Bot, event_loop):
""" sendMessage method test """
from .types.dataset import MESSAGE
msg = types.Message(**MESSAGE)
async with FakeTelegram(message_dict=MESSAGE, loop=event_loop):
@ -72,15 +68,11 @@ async def test_send_message(bot: Bot, event_loop):
async def test_forward_message(bot: Bot, event_loop):
""" forwardMessage method test """
from .types.dataset import FORWARDED_MESSAGE
msg = types.Message(**FORWARDED_MESSAGE)
async with FakeTelegram(message_dict=FORWARDED_MESSAGE, loop=event_loop):
result = await bot.forward_message(
chat_id=msg.chat.id,
from_chat_id=msg.forward_from_chat.id,
message_id=msg.forward_from_message_id,
)
result = await bot.forward_message(chat_id=msg.chat.id, from_chat_id=msg.forward_from_chat.id,
message_id=msg.forward_from_message_id)
assert result == msg
@ -88,18 +80,12 @@ async def test_forward_message(bot: Bot, event_loop):
async def test_send_photo(bot: Bot, event_loop):
""" sendPhoto method test with file_id """
from .types.dataset import MESSAGE_WITH_PHOTO, PHOTO
msg = types.Message(**MESSAGE_WITH_PHOTO)
photo = types.PhotoSize(**PHOTO)
async with FakeTelegram(message_dict=MESSAGE_WITH_PHOTO, loop=event_loop):
result = await bot.send_photo(
msg.chat.id,
photo=photo.file_id,
caption=msg.caption,
parse_mode=types.ParseMode.HTML,
disable_notification=False,
)
result = await bot.send_photo(msg.chat.id, photo=photo.file_id, caption=msg.caption,
parse_mode=types.ParseMode.HTML, disable_notification=False)
assert result == msg
@ -107,20 +93,12 @@ async def test_send_photo(bot: Bot, event_loop):
async def test_send_audio(bot: Bot, event_loop):
""" sendAudio method test with file_id """
from .types.dataset import MESSAGE_WITH_AUDIO
msg = types.Message(**MESSAGE_WITH_AUDIO)
async with FakeTelegram(message_dict=MESSAGE_WITH_AUDIO, loop=event_loop):
result = await bot.send_audio(
chat_id=msg.chat.id,
audio=msg.audio.file_id,
caption=msg.caption,
parse_mode=types.ParseMode.HTML,
duration=msg.audio.duration,
performer=msg.audio.performer,
title=msg.audio.title,
disable_notification=False,
)
result = await bot.send_audio(chat_id=msg.chat.id, audio=msg.audio.file_id, caption=msg.caption,
parse_mode=types.ParseMode.HTML, duration=msg.audio.duration,
performer=msg.audio.performer, title=msg.audio.title, disable_notification=False)
assert result == msg
@ -128,17 +106,11 @@ async def test_send_audio(bot: Bot, event_loop):
async def test_send_document(bot: Bot, event_loop):
""" sendDocument method test with file_id """
from .types.dataset import MESSAGE_WITH_DOCUMENT
msg = types.Message(**MESSAGE_WITH_DOCUMENT)
async with FakeTelegram(message_dict=MESSAGE_WITH_DOCUMENT, loop=event_loop):
result = await bot.send_document(
chat_id=msg.chat.id,
document=msg.document.file_id,
caption=msg.caption,
parse_mode=types.ParseMode.HTML,
disable_notification=False,
)
result = await bot.send_document(chat_id=msg.chat.id, document=msg.document.file_id, caption=msg.caption,
parse_mode=types.ParseMode.HTML, disable_notification=False)
assert result == msg
@ -146,22 +118,14 @@ async def test_send_document(bot: Bot, event_loop):
async def test_send_video(bot: Bot, event_loop):
""" sendVideo method test with file_id """
from .types.dataset import MESSAGE_WITH_VIDEO, VIDEO
msg = types.Message(**MESSAGE_WITH_VIDEO)
video = types.Video(**VIDEO)
async with FakeTelegram(message_dict=MESSAGE_WITH_VIDEO, loop=event_loop):
result = await bot.send_video(
chat_id=msg.chat.id,
video=video.file_id,
duration=video.duration,
width=video.width,
height=video.height,
caption=msg.caption,
parse_mode=types.ParseMode.HTML,
supports_streaming=True,
disable_notification=False,
)
result = await bot.send_video(chat_id=msg.chat.id, video=video.file_id, duration=video.duration,
width=video.width, height=video.height, caption=msg.caption,
parse_mode=types.ParseMode.HTML, supports_streaming=True,
disable_notification=False)
assert result == msg
@ -169,19 +133,13 @@ async def test_send_video(bot: Bot, event_loop):
async def test_send_voice(bot: Bot, event_loop):
""" sendVoice method test with file_id """
from .types.dataset import MESSAGE_WITH_VOICE, VOICE
msg = types.Message(**MESSAGE_WITH_VOICE)
voice = types.Voice(**VOICE)
async with FakeTelegram(message_dict=MESSAGE_WITH_VOICE, loop=event_loop):
result = await bot.send_voice(
chat_id=msg.chat.id,
voice=voice.file_id,
caption=msg.caption,
parse_mode=types.ParseMode.HTML,
duration=voice.duration,
disable_notification=False,
)
result = await bot.send_voice(chat_id=msg.chat.id, voice=voice.file_id, caption=msg.caption,
parse_mode=types.ParseMode.HTML, duration=voice.duration,
disable_notification=False)
assert result == msg
@ -189,18 +147,13 @@ async def test_send_voice(bot: Bot, event_loop):
async def test_send_video_note(bot: Bot, event_loop):
""" sendVideoNote method test with file_id """
from .types.dataset import MESSAGE_WITH_VIDEO_NOTE, VIDEO_NOTE
msg = types.Message(**MESSAGE_WITH_VIDEO_NOTE)
video_note = types.VideoNote(**VIDEO_NOTE)
async with FakeTelegram(message_dict=MESSAGE_WITH_VIDEO_NOTE, loop=event_loop):
result = await bot.send_video_note(
chat_id=msg.chat.id,
video_note=video_note.file_id,
duration=video_note.duration,
length=video_note.length,
disable_notification=False,
)
result = await bot.send_video_note(chat_id=msg.chat.id, video_note=video_note.file_id,
duration=video_note.duration, length=video_note.length,
disable_notification=False)
assert result == msg
@ -208,17 +161,11 @@ async def test_send_video_note(bot: Bot, event_loop):
async def test_send_media_group(bot: Bot, event_loop):
""" sendMediaGroup method test with file_id """
from .types.dataset import MESSAGE_WITH_MEDIA_GROUP, PHOTO
msg = types.Message(**MESSAGE_WITH_MEDIA_GROUP)
photo = types.PhotoSize(**PHOTO)
media = [
types.InputMediaPhoto(media=photo.file_id),
types.InputMediaPhoto(media=photo.file_id),
]
media = [types.InputMediaPhoto(media=photo.file_id), types.InputMediaPhoto(media=photo.file_id)]
async with FakeTelegram(
message_dict=[MESSAGE_WITH_MEDIA_GROUP, MESSAGE_WITH_MEDIA_GROUP], loop=event_loop
):
async with FakeTelegram(message_dict=[MESSAGE_WITH_MEDIA_GROUP, MESSAGE_WITH_MEDIA_GROUP], loop=event_loop):
result = await bot.send_media_group(msg.chat.id, media=media, disable_notification=False)
assert len(result) == len(media)
assert result.pop().media_group_id
@ -228,18 +175,12 @@ async def test_send_media_group(bot: Bot, event_loop):
async def test_send_location(bot: Bot, event_loop):
""" sendLocation method test """
from .types.dataset import MESSAGE_WITH_LOCATION, LOCATION
msg = types.Message(**MESSAGE_WITH_LOCATION)
location = types.Location(**LOCATION)
async with FakeTelegram(message_dict=MESSAGE_WITH_LOCATION, loop=event_loop):
result = await bot.send_location(
msg.chat.id,
latitude=location.latitude,
longitude=location.longitude,
live_period=10,
disable_notification=False,
)
result = await bot.send_location(msg.chat.id, latitude=location.latitude, longitude=location.longitude,
live_period=10, disable_notification=False)
assert result == msg
@ -247,18 +188,13 @@ async def test_send_location(bot: Bot, event_loop):
async def test_edit_message_live_location_by_bot(bot: Bot, event_loop):
""" editMessageLiveLocation method test """
from .types.dataset import MESSAGE_WITH_LOCATION, LOCATION
msg = types.Message(**MESSAGE_WITH_LOCATION)
location = types.Location(**LOCATION)
# editing bot message
async with FakeTelegram(message_dict=MESSAGE_WITH_LOCATION, loop=event_loop):
result = await bot.edit_message_live_location(
chat_id=msg.chat.id,
message_id=msg.message_id,
latitude=location.latitude,
longitude=location.longitude,
)
result = await bot.edit_message_live_location(chat_id=msg.chat.id, message_id=msg.message_id,
latitude=location.latitude, longitude=location.longitude)
assert result == msg
@ -266,18 +202,13 @@ async def test_edit_message_live_location_by_bot(bot: Bot, event_loop):
async def test_edit_message_live_location_by_user(bot: Bot, event_loop):
""" editMessageLiveLocation method test """
from .types.dataset import MESSAGE_WITH_LOCATION, LOCATION
msg = types.Message(**MESSAGE_WITH_LOCATION)
location = types.Location(**LOCATION)
# editing user's message
async with FakeTelegram(message_dict=True, loop=event_loop):
result = await bot.edit_message_live_location(
chat_id=msg.chat.id,
message_id=msg.message_id,
latitude=location.latitude,
longitude=location.longitude,
)
result = await bot.edit_message_live_location(chat_id=msg.chat.id, message_id=msg.message_id,
latitude=location.latitude, longitude=location.longitude)
assert isinstance(result, bool) and result is True
@ -285,14 +216,11 @@ async def test_edit_message_live_location_by_user(bot: Bot, event_loop):
async def test_stop_message_live_location_by_bot(bot: Bot, event_loop):
""" stopMessageLiveLocation method test """
from .types.dataset import MESSAGE_WITH_LOCATION
msg = types.Message(**MESSAGE_WITH_LOCATION)
# stopping bot message
async with FakeTelegram(message_dict=MESSAGE_WITH_LOCATION, loop=event_loop):
result = await bot.stop_message_live_location(
chat_id=msg.chat.id, message_id=msg.message_id
)
result = await bot.stop_message_live_location(chat_id=msg.chat.id, message_id=msg.message_id)
assert result == msg
@ -300,14 +228,11 @@ async def test_stop_message_live_location_by_bot(bot: Bot, event_loop):
async def test_stop_message_live_location_by_user(bot: Bot, event_loop):
""" stopMessageLiveLocation method test """
from .types.dataset import MESSAGE_WITH_LOCATION
msg = types.Message(**MESSAGE_WITH_LOCATION)
# stopping user's message
async with FakeTelegram(message_dict=True, loop=event_loop):
result = await bot.stop_message_live_location(
chat_id=msg.chat.id, message_id=msg.message_id
)
result = await bot.stop_message_live_location(chat_id=msg.chat.id, message_id=msg.message_id)
assert isinstance(result, bool)
assert result is True
@ -316,21 +241,14 @@ async def test_stop_message_live_location_by_user(bot: Bot, event_loop):
async def test_send_venue(bot: Bot, event_loop):
""" sendVenue method test """
from .types.dataset import MESSAGE_WITH_VENUE, VENUE, LOCATION
msg = types.Message(**MESSAGE_WITH_VENUE)
location = types.Location(**LOCATION)
venue = types.Venue(**VENUE)
async with FakeTelegram(message_dict=MESSAGE_WITH_VENUE, loop=event_loop):
result = await bot.send_venue(
msg.chat.id,
latitude=location.latitude,
longitude=location.longitude,
title=venue.title,
address=venue.address,
foursquare_id=venue.foursquare_id,
disable_notification=False,
)
result = await bot.send_venue(msg.chat.id, latitude=location.latitude, longitude=location.longitude,
title=venue.title, address=venue.address, foursquare_id=venue.foursquare_id,
disable_notification=False)
assert result == msg
@ -338,18 +256,12 @@ async def test_send_venue(bot: Bot, event_loop):
async def test_send_contact(bot: Bot, event_loop):
""" sendContact method test """
from .types.dataset import MESSAGE_WITH_CONTACT, CONTACT
msg = types.Message(**MESSAGE_WITH_CONTACT)
contact = types.Contact(**CONTACT)
async with FakeTelegram(message_dict=MESSAGE_WITH_CONTACT, loop=event_loop):
result = await bot.send_contact(
msg.chat.id,
phone_number=contact.phone_number,
first_name=contact.first_name,
last_name=contact.last_name,
disable_notification=False,
)
result = await bot.send_contact(msg.chat.id, phone_number=contact.phone_number, first_name=contact.first_name,
last_name=contact.last_name, disable_notification=False)
assert result == msg
@ -357,7 +269,6 @@ async def test_send_contact(bot: Bot, event_loop):
async def test_send_chat_action(bot: Bot, event_loop):
""" sendChatAction method test """
from .types.dataset import CHAT
chat = types.Chat(**CHAT)
async with FakeTelegram(message_dict=True, loop=event_loop):
@ -370,7 +281,6 @@ async def test_send_chat_action(bot: Bot, event_loop):
async def test_get_user_profile_photo(bot: Bot, event_loop):
""" getUserProfilePhotos method test """
from .types.dataset import USER_PROFILE_PHOTOS, USER
user = types.User(**USER)
async with FakeTelegram(message_dict=USER_PROFILE_PHOTOS, loop=event_loop):
@ -382,7 +292,6 @@ async def test_get_user_profile_photo(bot: Bot, event_loop):
async def test_get_file(bot: Bot, event_loop):
""" getFile method test """
from .types.dataset import FILE
file = types.File(**FILE)
async with FakeTelegram(message_dict=FILE, loop=event_loop):
@ -394,7 +303,6 @@ async def test_get_file(bot: Bot, event_loop):
async def test_kick_chat_member(bot: Bot, event_loop):
""" kickChatMember method test """
from .types.dataset import USER, CHAT
user = types.User(**USER)
chat = types.Chat(**CHAT)
@ -408,7 +316,6 @@ async def test_kick_chat_member(bot: Bot, event_loop):
async def test_unban_chat_member(bot: Bot, event_loop):
""" unbanChatMember method test """
from .types.dataset import USER, CHAT
user = types.User(**USER)
chat = types.Chat(**CHAT)
@ -422,7 +329,6 @@ async def test_unban_chat_member(bot: Bot, event_loop):
async def test_restrict_chat_member(bot: Bot, event_loop):
""" restrictChatMember method test """
from .types.dataset import USER, CHAT
user = types.User(**USER)
chat = types.Chat(**CHAT)
@ -430,12 +336,12 @@ async def test_restrict_chat_member(bot: Bot, event_loop):
result = await bot.restrict_chat_member(
chat_id=chat.id,
user_id=user.id,
can_add_web_page_previews=False,
can_send_media_messages=False,
can_send_messages=False,
can_send_other_messages=False,
until_date=123,
)
permissions=types.ChatPermissions(
can_add_web_page_previews=False,
can_send_media_messages=False,
can_send_messages=False,
can_send_other_messages=False
), until_date=123)
assert isinstance(result, bool)
assert result is True
@ -444,23 +350,14 @@ async def test_restrict_chat_member(bot: Bot, event_loop):
async def test_promote_chat_member(bot: Bot, event_loop):
""" promoteChatMember method test """
from .types.dataset import USER, CHAT
user = types.User(**USER)
chat = types.Chat(**CHAT)
async with FakeTelegram(message_dict=True, loop=event_loop):
result = await bot.promote_chat_member(
chat_id=chat.id,
user_id=user.id,
can_change_info=True,
can_delete_messages=True,
can_edit_messages=True,
can_invite_users=True,
can_pin_messages=True,
can_post_messages=True,
can_promote_members=True,
can_restrict_members=True,
)
result = await bot.promote_chat_member(chat_id=chat.id, user_id=user.id, can_change_info=True,
can_delete_messages=True, can_edit_messages=True,
can_invite_users=True, can_pin_messages=True, can_post_messages=True,
can_promote_members=True, can_restrict_members=True)
assert isinstance(result, bool)
assert result is True
@ -469,7 +366,6 @@ async def test_promote_chat_member(bot: Bot, event_loop):
async def test_export_chat_invite_link(bot: Bot, event_loop):
""" exportChatInviteLink method test """
from .types.dataset import CHAT, INVITE_LINK
chat = types.Chat(**CHAT)
async with FakeTelegram(message_dict=INVITE_LINK, loop=event_loop):
@ -481,7 +377,6 @@ async def test_export_chat_invite_link(bot: Bot, event_loop):
async def test_delete_chat_photo(bot: Bot, event_loop):
""" deleteChatPhoto method test """
from .types.dataset import CHAT
chat = types.Chat(**CHAT)
async with FakeTelegram(message_dict=True, loop=event_loop):
@ -494,11 +389,10 @@ async def test_delete_chat_photo(bot: Bot, event_loop):
async def test_set_chat_title(bot: Bot, event_loop):
""" setChatTitle method test """
from .types.dataset import CHAT
chat = types.Chat(**CHAT)
async with FakeTelegram(message_dict=True, loop=event_loop):
result = await bot.set_chat_title(chat_id=chat.id, title="Test title")
result = await bot.set_chat_title(chat_id=chat.id, title='Test title')
assert isinstance(result, bool)
assert result is True
@ -507,11 +401,10 @@ async def test_set_chat_title(bot: Bot, event_loop):
async def test_set_chat_description(bot: Bot, event_loop):
""" setChatDescription method test """
from .types.dataset import CHAT
chat = types.Chat(**CHAT)
async with FakeTelegram(message_dict=True, loop=event_loop):
result = await bot.set_chat_description(chat_id=chat.id, description="Test description")
result = await bot.set_chat_description(chat_id=chat.id, description='Test description')
assert isinstance(result, bool)
assert result is True
@ -520,13 +413,11 @@ async def test_set_chat_description(bot: Bot, event_loop):
async def test_pin_chat_message(bot: Bot, event_loop):
""" pinChatMessage method test """
from .types.dataset import MESSAGE
message = types.Message(**MESSAGE)
async with FakeTelegram(message_dict=True, loop=event_loop):
result = await bot.pin_chat_message(
chat_id=message.chat.id, message_id=message.message_id, disable_notification=False
)
result = await bot.pin_chat_message(chat_id=message.chat.id, message_id=message.message_id,
disable_notification=False)
assert isinstance(result, bool)
assert result is True
@ -535,7 +426,6 @@ async def test_pin_chat_message(bot: Bot, event_loop):
async def test_unpin_chat_message(bot: Bot, event_loop):
""" unpinChatMessage method test """
from .types.dataset import CHAT
chat = types.Chat(**CHAT)
async with FakeTelegram(message_dict=True, loop=event_loop):
@ -548,7 +438,6 @@ async def test_unpin_chat_message(bot: Bot, event_loop):
async def test_leave_chat(bot: Bot, event_loop):
""" leaveChat method test """
from .types.dataset import CHAT
chat = types.Chat(**CHAT)
async with FakeTelegram(message_dict=True, loop=event_loop):
@ -561,7 +450,6 @@ async def test_leave_chat(bot: Bot, event_loop):
async def test_get_chat(bot: Bot, event_loop):
""" getChat method test """
from .types.dataset import CHAT
chat = types.Chat(**CHAT)
async with FakeTelegram(message_dict=CHAT, loop=event_loop):
@ -573,7 +461,6 @@ async def test_get_chat(bot: Bot, event_loop):
async def test_get_chat_administrators(bot: Bot, event_loop):
""" getChatAdministrators method test """
from .types.dataset import CHAT, CHAT_MEMBER
chat = types.Chat(**CHAT)
member = types.ChatMember(**CHAT_MEMBER)
@ -587,7 +474,6 @@ async def test_get_chat_administrators(bot: Bot, event_loop):
async def test_get_chat_members_count(bot: Bot, event_loop):
""" getChatMembersCount method test """
from .types.dataset import CHAT
chat = types.Chat(**CHAT)
count = 5
@ -600,7 +486,6 @@ async def test_get_chat_members_count(bot: Bot, event_loop):
async def test_get_chat_member(bot: Bot, event_loop):
""" getChatMember method test """
from .types.dataset import CHAT, CHAT_MEMBER
chat = types.Chat(**CHAT)
member = types.ChatMember(**CHAT_MEMBER)
@ -614,13 +499,10 @@ async def test_get_chat_member(bot: Bot, event_loop):
async def test_set_chat_sticker_set(bot: Bot, event_loop):
""" setChatStickerSet method test """
from .types.dataset import CHAT
chat = types.Chat(**CHAT)
async with FakeTelegram(message_dict=True, loop=event_loop):
result = await bot.set_chat_sticker_set(
chat_id=chat.id, sticker_set_name="aiogram_stickers"
)
result = await bot.set_chat_sticker_set(chat_id=chat.id, sticker_set_name='aiogram_stickers')
assert isinstance(result, bool)
assert result is True
@ -629,7 +511,6 @@ async def test_set_chat_sticker_set(bot: Bot, event_loop):
async def test_delete_chat_sticker_set(bot: Bot, event_loop):
""" setChatStickerSet method test """
from .types.dataset import CHAT
chat = types.Chat(**CHAT)
async with FakeTelegram(message_dict=True, loop=event_loop):
@ -643,7 +524,7 @@ async def test_answer_callback_query(bot: Bot, event_loop):
""" answerCallbackQuery method test """
async with FakeTelegram(message_dict=True, loop=event_loop):
result = await bot.answer_callback_query(callback_query_id="QuERyId", text="Test Answer")
result = await bot.answer_callback_query(callback_query_id='QuERyId', text='Test Answer')
assert isinstance(result, bool)
assert result is True
@ -652,14 +533,11 @@ async def test_answer_callback_query(bot: Bot, event_loop):
async def test_edit_message_text_by_bot(bot: Bot, event_loop):
""" editMessageText method test """
from .types.dataset import EDITED_MESSAGE
msg = types.Message(**EDITED_MESSAGE)
# message by bot
async with FakeTelegram(message_dict=EDITED_MESSAGE, loop=event_loop):
result = await bot.edit_message_text(
text=msg.text, chat_id=msg.chat.id, message_id=msg.message_id
)
result = await bot.edit_message_text(text=msg.text, chat_id=msg.chat.id, message_id=msg.message_id)
assert result == msg
@ -667,13 +545,10 @@ async def test_edit_message_text_by_bot(bot: Bot, event_loop):
async def test_edit_message_text_by_user(bot: Bot, event_loop):
""" editMessageText method test """
from .types.dataset import EDITED_MESSAGE
msg = types.Message(**EDITED_MESSAGE)
# message by user
async with FakeTelegram(message_dict=True, loop=event_loop):
result = await bot.edit_message_text(
text=msg.text, chat_id=msg.chat.id, message_id=msg.message_id
)
result = await bot.edit_message_text(text=msg.text, chat_id=msg.chat.id, message_id=msg.message_id)
assert isinstance(result, bool)
assert result is True

View file

@ -0,0 +1,18 @@
import pytest
from aiogram.bot.api import check_token
from aiogram.utils.exceptions import ValidationError
VALID_TOKEN = '123456789:AABBCCDDEEFFaabbccddeeff-1234567890'
INVALID_TOKEN = '123456789:AABBCCDDEEFFaabbccddeeff 123456789' # Space in token and wrong length
class Test_check_token:
def test_valid(self):
assert check_token(VALID_TOKEN) is True
def test_invalid_token(self):
with pytest.raises(ValidationError):
check_token(INVALID_TOKEN)

View file

@ -0,0 +1,18 @@
import pytest
from aiogram.dispatcher.filters.builtin import Text
class TestText:
@pytest.mark.parametrize('param, key', [
('text', 'equals'),
('text_contains', 'contains'),
('text_startswith', 'startswith'),
('text_endswith', 'endswith'),
])
def test_validate(self, param, key):
value = 'spam and eggs'
config = {param: value}
res = Text.validate(config)
assert res == {key: value}

View file

@ -0,0 +1,18 @@
from aiogram.dispatcher.filters.state import StatesGroup
class TestStatesGroup:
def test_all_childs(self):
class InnerState1(StatesGroup):
pass
class InnerState2(InnerState1):
pass
class Form(StatesGroup):
inner1 = InnerState1
inner2 = InnerState2
form_childs = Form.all_childs
assert form_childs == (InnerState1, InnerState2)

263
tests/test_filters.py Normal file
View file

@ -0,0 +1,263 @@
import pytest
from aiogram.dispatcher.filters import Text
from aiogram.types import Message, CallbackQuery, InlineQuery, Poll
def data_sample_1():
return [
('', ''),
('', 'exAmple_string'),
('example_string', 'example_string'),
('example_string', 'exAmple_string'),
('exAmple_string', 'example_string'),
('example_string', 'example_string_dsf'),
('example_string', 'example_striNG_dsf'),
('example_striNG', 'example_string_dsf'),
('example_string', 'not_example_string'),
('example_string', 'not_eXample_string'),
('EXample_string', 'not_example_string'),
]
class TestTextFilter:
async def _run_check(self, check, test_text):
assert await check(Message(text=test_text))
assert await check(CallbackQuery(data=test_text))
assert await check(InlineQuery(query=test_text))
assert await check(Poll(question=test_text))
@pytest.mark.asyncio
@pytest.mark.parametrize('ignore_case', (True, False))
@pytest.mark.parametrize("test_prefix, test_text", data_sample_1())
async def test_startswith(self, test_prefix, test_text, ignore_case):
test_filter = Text(startswith=test_prefix, ignore_case=ignore_case)
async def check(obj):
result = await test_filter.check(obj)
if ignore_case:
_test_prefix = test_prefix.lower()
_test_text = test_text.lower()
else:
_test_prefix = test_prefix
_test_text = test_text
return result is _test_text.startswith(_test_prefix)
await self._run_check(check, test_text)
@pytest.mark.asyncio
@pytest.mark.parametrize('ignore_case', (True, False))
@pytest.mark.parametrize("test_prefix_list, test_text", [
(['not_example', ''], ''),
(['', 'not_example'], 'exAmple_string'),
(['not_example', 'example_string'], 'example_string'),
(['example_string', 'not_example'], 'exAmple_string'),
(['not_example', 'exAmple_string'], 'example_string'),
(['not_example', 'example_string'], 'example_string_dsf'),
(['example_string', 'not_example'], 'example_striNG_dsf'),
(['not_example', 'example_striNG'], 'example_string_dsf'),
(['not_example', 'example_string'], 'not_example_string'),
(['example_string', 'not_example'], 'not_eXample_string'),
(['not_example', 'EXample_string'], 'not_example_string'),
])
async def test_startswith_list(self, test_prefix_list, test_text, ignore_case):
test_filter = Text(startswith=test_prefix_list, ignore_case=ignore_case)
async def check(obj):
result = await test_filter.check(obj)
if ignore_case:
_test_prefix_list = map(str.lower, test_prefix_list)
_test_text = test_text.lower()
else:
_test_prefix_list = test_prefix_list
_test_text = test_text
return result is any(map(_test_text.startswith, _test_prefix_list))
await self._run_check(check, test_text)
@pytest.mark.asyncio
@pytest.mark.parametrize('ignore_case', (True, False))
@pytest.mark.parametrize("test_postfix, test_text", data_sample_1())
async def test_endswith(self, test_postfix, test_text, ignore_case):
test_filter = Text(endswith=test_postfix, ignore_case=ignore_case)
async def check(obj):
result = await test_filter.check(obj)
if ignore_case:
_test_postfix = test_postfix.lower()
_test_text = test_text.lower()
else:
_test_postfix = test_postfix
_test_text = test_text
return result is _test_text.endswith(_test_postfix)
await self._run_check(check, test_text)
@pytest.mark.asyncio
@pytest.mark.parametrize('ignore_case', (True, False))
@pytest.mark.parametrize("test_postfix_list, test_text", [
(['', 'not_example'], ''),
(['not_example', ''], 'exAmple_string'),
(['example_string', 'not_example'], 'example_string'),
(['not_example', 'example_string'], 'exAmple_string'),
(['exAmple_string', 'not_example'], 'example_string'),
(['not_example', 'example_string'], 'example_string_dsf'),
(['example_string', 'not_example'], 'example_striNG_dsf'),
(['not_example', 'example_striNG'], 'example_string_dsf'),
(['not_example', 'example_string'], 'not_example_string'),
(['example_string', 'not_example'], 'not_eXample_string'),
(['not_example', 'EXample_string'], 'not_example_string'),
])
async def test_endswith_list(self, test_postfix_list, test_text, ignore_case):
test_filter = Text(endswith=test_postfix_list, ignore_case=ignore_case)
async def check(obj):
result = await test_filter.check(obj)
if ignore_case:
_test_postfix_list = map(str.lower, test_postfix_list)
_test_text = test_text.lower()
else:
_test_postfix_list = test_postfix_list
_test_text = test_text
return result is any(map(_test_text.endswith, _test_postfix_list))
await self._run_check(check, test_text)
@pytest.mark.asyncio
@pytest.mark.parametrize('ignore_case', (True, False))
@pytest.mark.parametrize("test_string, test_text", [
('', ''),
('', 'exAmple_string'),
('example_string', 'example_string'),
('example_string', 'exAmple_string'),
('exAmple_string', 'example_string'),
('example_string', 'example_string_dsf'),
('example_string', 'example_striNG_dsf'),
('example_striNG', 'example_string_dsf'),
('example_string', 'not_example_strin'),
('example_string', 'not_eXample_strin'),
('EXample_string', 'not_example_strin'),
])
async def test_contains(self, test_string, test_text, ignore_case):
test_filter = Text(contains=test_string, ignore_case=ignore_case)
async def check(obj):
result = await test_filter.check(obj)
if ignore_case:
_test_string = test_string.lower()
_test_text = test_text.lower()
else:
_test_string = test_string
_test_text = test_text
return result is (_test_string in _test_text)
await self._run_check(check, test_text)
@pytest.mark.asyncio
@pytest.mark.parametrize('ignore_case', (True, False))
@pytest.mark.parametrize("test_filter_list, test_text", [
(['a', 'ab', 'abc'], 'A'),
(['a', 'ab', 'abc'], 'ab'),
(['a', 'ab', 'abc'], 'aBc'),
(['a', 'ab', 'abc'], 'd'),
])
async def test_contains_list(self, test_filter_list, test_text, ignore_case):
test_filter = Text(contains=test_filter_list, ignore_case=ignore_case)
async def check(obj):
result = await test_filter.check(obj)
if ignore_case:
_test_filter_list = list(map(str.lower, test_filter_list))
_test_text = test_text.lower()
else:
_test_filter_list = test_filter_list
_test_text = test_text
return result is all(map(_test_text.__contains__, _test_filter_list))
await self._run_check(check, test_text)
@pytest.mark.asyncio
@pytest.mark.parametrize('ignore_case', (True, False))
@pytest.mark.parametrize("test_filter_text, test_text", [
('', ''),
('', 'exAmple_string'),
('example_string', 'example_string'),
('example_string', 'exAmple_string'),
('exAmple_string', 'example_string'),
('example_string', 'not_example_string'),
('example_string', 'not_eXample_string'),
('EXample_string', 'not_example_string'),
])
async def test_equals_string(self, test_filter_text, test_text, ignore_case):
test_filter = Text(equals=test_filter_text, ignore_case=ignore_case)
async def check(obj):
result = await test_filter.check(obj)
if ignore_case:
_test_filter_text = test_filter_text.lower()
_test_text = test_text.lower()
else:
_test_filter_text = test_filter_text
_test_text = test_text
return result is (_test_text == _test_filter_text)
await self._run_check(check, test_text)
@pytest.mark.asyncio
@pytest.mark.parametrize('ignore_case', (True, False))
@pytest.mark.parametrize("test_filter_list, test_text", [
(['new_string', ''], ''),
(['', 'new_string'], 'exAmple_string'),
(['example_string'], 'example_string'),
(['example_string'], 'exAmple_string'),
(['exAmple_string'], 'example_string'),
(['example_string'], 'not_example_string'),
(['example_string'], 'not_eXample_string'),
(['EXample_string'], 'not_example_string'),
(['example_string', 'new_string'], 'example_string'),
(['new_string', 'example_string'], 'exAmple_string'),
(['exAmple_string', 'new_string'], 'example_string'),
(['example_string', 'new_string'], 'not_example_string'),
(['new_string', 'example_string'], 'not_eXample_string'),
(['EXample_string', 'new_string'], 'not_example_string'),
])
async def test_equals_list(self, test_filter_list, test_text, ignore_case):
test_filter = Text(equals=test_filter_list, ignore_case=ignore_case)
async def check(obj):
result = await test_filter.check(obj)
if ignore_case:
_test_filter_list = list(map(str.lower, test_filter_list))
_test_text = test_text.lower()
else:
_test_filter_list = test_filter_list
_test_text = test_text
assert result is (_test_text in _test_filter_list)
await check(Message(text=test_text))
await check(CallbackQuery(data=test_text))
await check(InlineQuery(query=test_text))
await check(Poll(question=test_text))

View file

@ -1,41 +0,0 @@
import pytest
from aiogram.bot import api
from aiogram.utils import auth_widget, exceptions
VALID_TOKEN = "123456789:AABBCCDDEEFFaabbccddeeff-1234567890"
INVALID_TOKEN = "123456789:AABBCCDDEEFFaabbccddeeff 123456789" # Space in token and wrong length
VALID_DATA = {
"date": 1525385236,
"first_name": "Test",
"last_name": "User",
"id": 123456789,
"username": "username",
"hash": "69a9871558fbbe4cd0dbaba52fa1cc4f38315d3245b7504381a64139fb024b5b",
}
INVALID_DATA = {
"date": 1525385237,
"first_name": "Test",
"last_name": "User",
"id": 123456789,
"username": "username",
"hash": "69a9871558fbbe4cd0dbaba52fa1cc4f38315d3245b7504381a64139fb024b5b",
}
def test_valid_token():
assert api.check_token(VALID_TOKEN)
def test_invalid_token():
with pytest.raises(exceptions.ValidationError):
api.check_token(INVALID_TOKEN)
def test_widget():
assert auth_widget.check_token(VALID_DATA, VALID_TOKEN)
def test_invalid_widget_data():
assert not auth_widget.check_token(INVALID_DATA, VALID_TOKEN)

View file

@ -0,0 +1,46 @@
import pytest
from aiogram.utils.auth_widget import check_integrity, \
generate_hash, check_token
TOKEN = '123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11'
@pytest.fixture
def data():
return {
'id': '42',
'first_name': 'John',
'last_name': 'Smith',
'username': 'username',
'photo_url': 'https://t.me/i/userpic/320/picname.jpg',
'auth_date': '1565810688',
'hash': 'c303db2b5a06fe41d23a9b14f7c545cfc11dcc7473c07c9c5034ae60062461ce',
}
def test_generate_hash(data):
res = generate_hash(data, TOKEN)
assert res == data['hash']
class Test_check_token:
"""
This case gonna be deleted
"""
def test_ok(self, data):
assert check_token(data, TOKEN) is True
def test_fail(self, data):
data.pop('username')
assert check_token(data, TOKEN) is False
class Test_check_integrity:
def test_ok(self, data):
assert check_integrity(TOKEN, data) is True
def test_fail(self, data):
data.pop('username')
assert check_integrity(TOKEN, data) is False

View file

@ -0,0 +1,22 @@
from aiogram.utils.helper import OrderedHelper, Item, ListItem
class TestOrderedHelper:
def test_items_are_ordered(self):
class Helper(OrderedHelper):
A = Item()
D = Item()
C = Item()
B = Item()
assert Helper.all() == ['A', 'D', 'C', 'B']
def test_list_items_are_ordered(self):
class Helper(OrderedHelper):
A = ListItem()
D = ListItem()
C = ListItem()
B = ListItem()
assert Helper.all() == ['A', 'D', 'C', 'B']

View file

@ -47,7 +47,11 @@ CHAT_MEMBER = {
"can_promote_members": False,
}
CONTACT = {"phone_number": "88005553535", "first_name": "John", "last_name": "Smith"}
CONTACT = {
"phone_number": "88005553535",
"first_name": "John",
"last_name": "Smith",
}
DOCUMENT = {
"file_name": "test.docx",
@ -64,17 +68,42 @@ ANIMATION = {
"file_size": 65837,
}
ENTITY_BOLD = {"offset": 5, "length": 2, "type": "bold"}
ENTITY_BOLD = {
"offset": 5,
"length": 2,
"type": "bold",
}
ENTITY_ITALIC = {"offset": 8, "length": 1, "type": "italic"}
ENTITY_ITALIC = {
"offset": 8,
"length": 1,
"type": "italic",
}
ENTITY_LINK = {"offset": 10, "length": 6, "type": "text_link", "url": "http://google.com/"}
ENTITY_LINK = {
"offset": 10,
"length": 6,
"type": "text_link",
"url": "http://google.com/",
}
ENTITY_CODE = {"offset": 17, "length": 7, "type": "code"}
ENTITY_CODE = {
"offset": 17,
"length": 7,
"type": "code",
}
ENTITY_PRE = {"offset": 30, "length": 4, "type": "pre"}
ENTITY_PRE = {
"offset": 30,
"length": 4,
"type": "pre",
}
ENTITY_MENTION = {"offset": 47, "length": 9, "type": "mention"}
ENTITY_MENTION = {
"offset": 47,
"length": 9,
"type": "mention",
}
GAME = {
"title": "Karate Kido",
@ -86,15 +115,18 @@ GAME = {
INVOICE = {
"title": "Working Time Machine",
"description": "Want to visit your great-great-great-grandparents? "
"Make a fortune at the races? "
"Shake hands with Hammurabi and take a stroll in the Hanging Gardens? "
"Order our Working Time Machine today!",
"Make a fortune at the races? "
"Shake hands with Hammurabi and take a stroll in the Hanging Gardens? "
"Order our Working Time Machine today!",
"start_parameter": "time-machine-example",
"currency": "USD",
"total_amount": 6250,
}
LOCATION = {"latitude": 50.693416, "longitude": 30.624605}
LOCATION = {
"latitude": 50.693416,
"longitude": 30.624605,
}
VENUE = {
"location": LOCATION,
@ -121,7 +153,7 @@ STICKER = {
"file_id": "AAbbCCddEEffGGhh1234567890",
"file_size": 1234,
"width": 128,
"height": 128,
"height": 128
},
"file_id": "AAbbCCddEEffGGhh1234567890",
"file_size": 12345,
@ -186,15 +218,8 @@ FORWARDED_MESSAGE = {
"forward_from_message_id": 123,
"forward_date": 1522749037,
"text": "Forwarded text with entities from public channel ",
"entities": [
ENTITY_BOLD,
ENTITY_CODE,
ENTITY_ITALIC,
ENTITY_LINK,
ENTITY_LINK,
ENTITY_MENTION,
ENTITY_PRE,
],
"entities": [ENTITY_BOLD, ENTITY_CODE, ENTITY_ITALIC, ENTITY_LINK,
ENTITY_LINK, ENTITY_MENTION, ENTITY_PRE],
}
INLINE_QUERY = {}
@ -391,12 +416,27 @@ SHIPPING_QUERY = {
"shipping_address": SHIPPING_ADDRESS,
}
USER_PROFILE_PHOTOS = {"total_count": 1, "photos": [[PHOTO, PHOTO, PHOTO]]}
USER_PROFILE_PHOTOS = {
"total_count": 1, "photos": [
[PHOTO, PHOTO, PHOTO],
],
}
FILE = {"file_id": "XXXYYYZZZ", "file_size": 5254, "file_path": "voice/file_8"}
FILE = {
"file_id": "XXXYYYZZZ",
"file_size": 5254,
"file_path": "voice/file_8",
}
INVITE_LINK = "https://t.me/joinchat/AbCdEfjKILDADwdd123"
INVITE_LINK = 'https://t.me/joinchat/AbCdEfjKILDADwdd123'
UPDATE = {"update_id": 123456789, "message": MESSAGE}
UPDATE = {
"update_id": 123456789,
"message": MESSAGE,
}
WEBHOOK_INFO = {"url": "", "has_custom_certificate": False, "pending_update_count": 0}
WEBHOOK_INFO = {
"url": "",
"has_custom_certificate": False,
"pending_update_count": 0,
}

View file

@ -0,0 +1,77 @@
from aiogram import types
from .dataset import CHAT_MEMBER
chat_member = types.ChatMember(**CHAT_MEMBER)
def test_export():
exported = chat_member.to_python()
assert isinstance(exported, dict)
assert exported == CHAT_MEMBER
def test_user():
assert isinstance(chat_member.user, types.User)
def test_status():
assert isinstance(chat_member.status, str)
assert chat_member.status == CHAT_MEMBER['status']
def test_privileges():
assert isinstance(chat_member.can_be_edited, bool)
assert chat_member.can_be_edited == CHAT_MEMBER['can_be_edited']
assert isinstance(chat_member.can_change_info, bool)
assert chat_member.can_change_info == CHAT_MEMBER['can_change_info']
assert isinstance(chat_member.can_delete_messages, bool)
assert chat_member.can_delete_messages == CHAT_MEMBER['can_delete_messages']
assert isinstance(chat_member.can_invite_users, bool)
assert chat_member.can_invite_users == CHAT_MEMBER['can_invite_users']
assert isinstance(chat_member.can_restrict_members, bool)
assert chat_member.can_restrict_members == CHAT_MEMBER['can_restrict_members']
assert isinstance(chat_member.can_pin_messages, bool)
assert chat_member.can_pin_messages == CHAT_MEMBER['can_pin_messages']
assert isinstance(chat_member.can_promote_members, bool)
assert chat_member.can_promote_members == CHAT_MEMBER['can_promote_members']
def test_int():
assert int(chat_member) == chat_member.user.id
assert isinstance(int(chat_member), int)
def test_chat_member_status():
assert types.ChatMemberStatus.CREATOR == 'creator'
assert types.ChatMemberStatus.ADMINISTRATOR == 'administrator'
assert types.ChatMemberStatus.MEMBER == 'member'
assert types.ChatMemberStatus.RESTRICTED == 'restricted'
assert types.ChatMemberStatus.LEFT == 'left'
assert types.ChatMemberStatus.KICKED == 'kicked'
def test_chat_member_status_filters():
assert types.ChatMemberStatus.is_chat_admin(chat_member.status)
assert types.ChatMemberStatus.is_chat_member(chat_member.status)
assert types.ChatMemberStatus.is_chat_admin(types.ChatMemberStatus.CREATOR)
assert types.ChatMemberStatus.is_chat_admin(types.ChatMemberStatus.ADMINISTRATOR)
assert types.ChatMemberStatus.is_chat_member(types.ChatMemberStatus.CREATOR)
assert types.ChatMemberStatus.is_chat_member(types.ChatMemberStatus.ADMINISTRATOR)
assert types.ChatMemberStatus.is_chat_member(types.ChatMemberStatus.MEMBER)
assert types.ChatMemberStatus.is_chat_member(types.ChatMemberStatus.RESTRICTED)
assert not types.ChatMemberStatus.is_chat_member(types.ChatMemberStatus.LEFT)
assert not types.ChatMemberStatus.is_chat_member(types.ChatMemberStatus.KICKED)
def test_chat_member_filters():
assert chat_member.is_chat_admin()
assert chat_member.is_chat_member()