Merge branch 'dev-3.x' into feature/iter_states

This commit is contained in:
Andrey Tikhonov 2021-08-17 23:43:56 +03:00
commit 6588b569aa
239 changed files with 5162 additions and 1667 deletions

View file

@ -1,13 +1,74 @@
import pytest
from _pytest.config import UsageError
from aioredis.connection import parse_url as parse_redis_url
from aiogram import Bot
from aiogram.dispatcher.fsm.storage.memory import MemoryStorage
from aiogram.dispatcher.fsm.storage.redis import RedisStorage
from tests.mocked_bot import MockedBot
def pytest_addoption(parser):
parser.addoption("--redis", default=None, help="run tests which require redis connection")
def pytest_configure(config):
config.addinivalue_line("markers", "redis: marked tests require redis connection to run")
def pytest_collection_modifyitems(config, items):
redis_uri = config.getoption("--redis")
if redis_uri is None:
skip_redis = pytest.mark.skip(reason="need --redis option with redis URI to run")
for item in items:
if "redis" in item.keywords:
item.add_marker(skip_redis)
return
try:
parse_redis_url(redis_uri)
except ValueError as e:
raise UsageError(f"Invalid redis URI {redis_uri!r}: {e}")
@pytest.fixture(scope="session")
def redis_server(request):
redis_uri = request.config.getoption("--redis")
return redis_uri
@pytest.fixture()
@pytest.mark.redis
async def redis_storage(redis_server):
if not redis_server:
pytest.skip("Redis is not available here")
storage = RedisStorage.from_url(redis_server)
try:
await storage.redis.info()
except ConnectionError as e:
pytest.skip(str(e))
try:
yield storage
finally:
conn = await storage.redis
await conn.flushdb()
await storage.close()
@pytest.fixture()
async def memory_storage():
storage = MemoryStorage()
try:
yield storage
finally:
await storage.close()
@pytest.fixture()
def bot():
bot = MockedBot()
token = Bot.set_current(bot)
yield bot
Bot.reset_current(token)
bot.me.invalidate(bot)
try:
yield bot
finally:
Bot.reset_current(token)
bot.me.invalidate(bot)

7
tests/docker-compose.yml Normal file
View file

@ -0,0 +1,7 @@
version: "3.9"
services:
redis:
image: redis:6-alpine
ports:
- "${REDIS_PORT-6379}:6379"

View file

@ -4,17 +4,17 @@ from typing import TYPE_CHECKING, AsyncGenerator, Deque, Optional, Type
from aiogram import Bot
from aiogram.client.session.base import BaseSession
from aiogram.methods import TelegramMethod
from aiogram.methods.base import Request, Response, T
from aiogram.types import UNSET
from aiogram.methods.base import Request, Response, TelegramType
from aiogram.types import UNSET, ResponseParameters
class MockedSession(BaseSession):
def __init__(self):
super(MockedSession, self).__init__()
self.responses: Deque[Response[T]] = deque()
self.responses: Deque[Response[TelegramType]] = deque()
self.requests: Deque[Request] = deque()
def add_result(self, response: Response[T]) -> Response[T]:
def add_result(self, response: Response[TelegramType]) -> Response[TelegramType]:
self.responses.append(response)
return response
@ -25,11 +25,13 @@ class MockedSession(BaseSession):
pass
async def make_request(
self, bot: Bot, method: TelegramMethod[T], timeout: Optional[int] = UNSET
) -> T:
self, bot: Bot, method: TelegramMethod[TelegramType], timeout: Optional[int] = UNSET
) -> TelegramType:
self.requests.append(method.build_request(bot))
response: Response[T] = self.responses.pop()
self.raise_for_status(response)
response: Response[TelegramType] = self.responses.pop()
self.check_response(
method=method, status_code=response.error_code, content=response.json()
)
return response.result # type: ignore
async def stream_content(
@ -47,21 +49,23 @@ class MockedBot(Bot):
def add_result_for(
self,
method: Type[TelegramMethod[T]],
method: Type[TelegramMethod[TelegramType]],
ok: bool,
result: T = None,
result: TelegramType = None,
description: Optional[str] = None,
error_code: Optional[int] = None,
error_code: int = 200,
migrate_to_chat_id: Optional[int] = None,
retry_after: Optional[int] = None,
) -> Response[T]:
) -> Response[TelegramType]:
response = Response[method.__returning__]( # type: ignore
ok=ok,
result=result,
description=description,
error_code=error_code,
migrate_to_chat_id=migrate_to_chat_id,
retry_after=retry_after,
parameters=ResponseParameters(
migrate_to_chat_id=migrate_to_chat_id,
retry_after=retry_after,
),
)
self.session.add_result(response)
return response

View file

@ -16,6 +16,8 @@ except ImportError:
from unittest.mock import AsyncMock as CoroutineMock # type: ignore
from unittest.mock import patch
pytestmark = pytest.mark.asyncio
class TestBot:
def test_init(self):
@ -32,7 +34,6 @@ class TestBot:
assert bot == Bot("42:TEST")
assert bot != "42:TEST"
@pytest.mark.asyncio
async def test_emit(self):
bot = Bot("42:TEST")
@ -45,7 +46,6 @@ class TestBot:
await bot(method)
mocked_make_request.assert_awaited_with(bot, method, timeout=None)
@pytest.mark.asyncio
async def test_close(self):
session = AiohttpSession()
bot = Bot("42:TEST", session=session)
@ -57,7 +57,6 @@ class TestBot:
await bot.session.close()
mocked_close.assert_awaited()
@pytest.mark.asyncio
@pytest.mark.parametrize("close", [True, False])
async def test_context_manager(self, close: bool):
with patch(
@ -70,7 +69,6 @@ class TestBot:
else:
mocked_close.assert_not_awaited()
@pytest.mark.asyncio
async def test_download_file(self, aresponses: ResponsesMockServer):
aresponses.add(
aresponses.ANY, aresponses.ANY, "get", aresponses.Response(status=200, body=b"\f" * 10)
@ -88,7 +86,6 @@ class TestBot:
await bot.download_file("TEST", "file.png")
mock_file.write.assert_called_once_with(b"\f" * 10)
@pytest.mark.asyncio
async def test_download_file_default_destination(self, aresponses: ResponsesMockServer):
bot = Bot("42:TEST")
@ -101,7 +98,6 @@ class TestBot:
assert isinstance(result, io.BytesIO)
assert result.read() == b"\f" * 10
@pytest.mark.asyncio
async def test_download_file_custom_destination(self, aresponses: ResponsesMockServer):
bot = Bot("42:TEST")
@ -117,7 +113,6 @@ class TestBot:
assert result is custom
assert result.read() == b"\f" * 10
@pytest.mark.asyncio
async def test_download(self, bot: MockedBot, aresponses: ResponsesMockServer):
bot.add_result_for(
GetFile, ok=True, result=File(file_id="file id", file_unique_id="file id")

View file

@ -1,7 +1,9 @@
import asyncio
from typing import AsyncContextManager, AsyncGenerator
import aiohttp_socks
import pytest
from aiohttp import ClientError
from aresponses import ResponsesMockServer
from aiogram import Bot
@ -9,6 +11,7 @@ from aiogram.client.session import aiohttp
from aiogram.client.session.aiohttp import AiohttpSession
from aiogram.methods import Request, TelegramMethod
from aiogram.types import UNSET, InputFile
from aiogram.utils.exceptions.network import NetworkError
from tests.mocked_bot import MockedBot
try:
@ -17,6 +20,8 @@ except ImportError:
from unittest.mock import AsyncMock as CoroutineMock # type: ignore
from unittest.mock import patch
pytestmark = pytest.mark.asyncio
class BareInputFile(InputFile):
async def read(self, chunk_size: int):
@ -24,7 +29,6 @@ class BareInputFile(InputFile):
class TestAiohttpSession:
@pytest.mark.asyncio
async def test_create_session(self):
session = AiohttpSession()
@ -33,7 +37,6 @@ class TestAiohttpSession:
assert session._session is not None
assert isinstance(aiohttp_session, aiohttp.ClientSession)
@pytest.mark.asyncio
async def test_create_proxy_session(self):
session = AiohttpSession(
proxy=("socks5://proxy.url/", aiohttp.BasicAuth("login", "password", "encoding"))
@ -47,7 +50,6 @@ class TestAiohttpSession:
aiohttp_session = await session.create_session()
assert isinstance(aiohttp_session.connector, aiohttp_socks.ProxyConnector)
@pytest.mark.asyncio
async def test_create_proxy_session_proxy_url(self):
session = AiohttpSession(proxy="socks4://proxy.url/")
@ -59,7 +61,6 @@ class TestAiohttpSession:
aiohttp_session = await session.create_session()
assert isinstance(aiohttp_session.connector, aiohttp_socks.ProxyConnector)
@pytest.mark.asyncio
async def test_create_proxy_session_chained_proxies(self):
session = AiohttpSession(
proxy=[
@ -86,7 +87,6 @@ class TestAiohttpSession:
aiohttp_session = await session.create_session()
assert isinstance(aiohttp_session.connector, aiohttp_socks.ChainProxyConnector)
@pytest.mark.asyncio
async def test_reset_connector(self):
session = AiohttpSession()
assert session._should_reset_connector
@ -102,7 +102,6 @@ class TestAiohttpSession:
assert session._should_reset_connector is False
await session.close()
@pytest.mark.asyncio
async def test_close_session(self):
session = AiohttpSession()
await session.create_session()
@ -150,7 +149,6 @@ class TestAiohttpSession:
assert fields[1][0]["filename"] == "file.txt"
assert isinstance(fields[1][2], BareInputFile)
@pytest.mark.asyncio
async def test_make_request(self, bot: MockedBot, aresponses: ResponsesMockServer):
aresponses.add(
aresponses.ANY,
@ -172,16 +170,26 @@ class TestAiohttpSession:
return Request(method="method", data={})
call = TestMethod()
result = await session.make_request(bot, call)
assert isinstance(result, int)
assert result == 42
@pytest.mark.parametrize("error", [ClientError("mocked"), asyncio.TimeoutError()])
async def test_make_request_network_error(self, error):
bot = Bot("42:TEST")
async def side_effect(*args, **kwargs):
raise error
with patch(
"aiogram.client.session.base.BaseSession.raise_for_status"
) as patched_raise_for_status:
result = await session.make_request(bot, call)
assert isinstance(result, int)
assert result == 42
"aiohttp.client.ClientSession._request",
new_callable=CoroutineMock,
side_effect=side_effect,
):
with pytest.raises(NetworkError):
await bot.get_me()
assert patched_raise_for_status.called_once()
@pytest.mark.asyncio
async def test_stream_content(self, aresponses: ResponsesMockServer):
aresponses.add(
aresponses.ANY, aresponses.ANY, "get", aresponses.Response(status=200, body=b"\f" * 10)
@ -201,7 +209,6 @@ class TestAiohttpSession:
size += chunk_size
assert size == 10
@pytest.mark.asyncio
async def test_context_manager(self):
session = AiohttpSession()
assert isinstance(session, AsyncContextManager)

View file

@ -4,10 +4,20 @@ from typing import AsyncContextManager, AsyncGenerator, Optional
import pytest
from aiogram.client.session.base import BaseSession, T
from aiogram import Bot
from aiogram.client.session.base import BaseSession, TelegramType
from aiogram.client.telegram import PRODUCTION, TelegramAPIServer
from aiogram.methods import GetMe, Response, TelegramMethod
from aiogram.types import UNSET
from aiogram.methods import DeleteMessage, GetMe, TelegramMethod
from aiogram.types import UNSET, User
from aiogram.utils.exceptions.bad_request import BadRequest
from aiogram.utils.exceptions.base import TelegramAPIError
from aiogram.utils.exceptions.conflict import ConflictError
from aiogram.utils.exceptions.network import EntityTooLarge
from aiogram.utils.exceptions.not_found import NotFound
from aiogram.utils.exceptions.server import RestartingTelegram, ServerError
from aiogram.utils.exceptions.special import MigrateToChat, RetryAfter
from aiogram.utils.exceptions.unauthorized import UnauthorizedError
from tests.mocked_bot import MockedBot
try:
from asynctest import CoroutineMock, patch
@ -15,12 +25,16 @@ except ImportError:
from unittest.mock import AsyncMock as CoroutineMock # type: ignore
from unittest.mock import patch
pytestmark = pytest.mark.asyncio
class CustomSession(BaseSession):
async def close(self):
pass
async def make_request(self, token: str, method: TelegramMethod[T], timeout: Optional[int] = UNSET) -> None: # type: ignore
async def make_request(
self, token: str, method: TelegramMethod[TelegramType], timeout: Optional[int] = UNSET
) -> None: # type: ignore
assert isinstance(token, str)
assert isinstance(method, TelegramMethod)
@ -135,20 +149,59 @@ class TestBaseSession:
assert session.clean_json(42) == 42
def test_raise_for_status(self):
@pytest.mark.parametrize(
"status_code,content,error",
[
[200, '{"ok":true,"result":true}', None],
[400, '{"ok":false,"description":"test"}', BadRequest],
[
400,
'{"ok":false,"description":"test", "parameters": {"retry_after": 1}}',
RetryAfter,
],
[
400,
'{"ok":false,"description":"test", "parameters": {"migrate_to_chat_id": -42}}',
MigrateToChat,
],
[404, '{"ok":false,"description":"test"}', NotFound],
[401, '{"ok":false,"description":"test"}', UnauthorizedError],
[403, '{"ok":false,"description":"test"}', UnauthorizedError],
[409, '{"ok":false,"description":"test"}', ConflictError],
[413, '{"ok":false,"description":"test"}', EntityTooLarge],
[500, '{"ok":false,"description":"restarting"}', RestartingTelegram],
[500, '{"ok":false,"description":"test"}', ServerError],
[502, '{"ok":false,"description":"test"}', ServerError],
[499, '{"ok":false,"description":"test"}', TelegramAPIError],
[499, '{"ok":false,"description":"test"}', TelegramAPIError],
],
)
def test_check_response(self, status_code, content, error):
session = CustomSession()
method = DeleteMessage(chat_id=42, message_id=42)
if error is None:
session.check_response(
method=method,
status_code=status_code,
content=content,
)
else:
with pytest.raises(error) as exc_info:
session.check_response(
method=method,
status_code=status_code,
content=content,
)
error: TelegramAPIError = exc_info.value
string = str(error)
if error.url:
assert error.url in string
session.raise_for_status(Response[bool](ok=True, result=True))
with pytest.raises(Exception):
session.raise_for_status(Response[bool](ok=False, description="Error", error_code=400))
@pytest.mark.asyncio
async def test_make_request(self):
session = CustomSession()
assert await session.make_request("42:TEST", GetMe()) is None
@pytest.mark.asyncio
async def test_stream_content(self):
session = CustomSession()
stream = session.stream_content(
@ -159,7 +212,6 @@ class TestBaseSession:
async for chunk in stream:
assert isinstance(chunk, bytes)
@pytest.mark.asyncio
async def test_context_manager(self):
session = CustomSession()
assert isinstance(session, AsyncContextManager)
@ -171,3 +223,35 @@ class TestBaseSession:
async with session as ctx:
assert session == ctx
mocked_close.assert_awaited_once()
def test_add_middleware(self):
async def my_middleware(bot, method, make_request):
return await make_request(bot, method)
session = CustomSession()
assert not session.middlewares
session.middleware(my_middleware)
assert my_middleware in session.middlewares
assert len(session.middlewares) == 1
async def test_use_middleware(self, bot: MockedBot):
flag_before = False
flag_after = False
@bot.session.middleware
async def my_middleware(b, method, make_request):
nonlocal flag_before, flag_after
flag_before = True
try:
assert isinstance(b, Bot)
assert isinstance(method, TelegramMethod)
return await make_request(bot, method)
finally:
flag_after = True
bot.add_result_for(GetMe, ok=True, result=User(id=42, is_bot=True, first_name="Test"))
assert await bot.get_me()
assert flag_before
assert flag_after

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import AddStickerToSet, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestAddStickerToSet:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(AddStickerToSet, ok=True, result=True)
@ -16,7 +17,6 @@ class TestAddStickerToSet:
assert request.method == "addStickerToSet"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(AddStickerToSet, ok=True, result=True)

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import AnswerCallbackQuery, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestAnswerCallbackQuery:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(AnswerCallbackQuery, ok=True, result=True)
@ -14,7 +15,6 @@ class TestAnswerCallbackQuery:
assert request.method == "answerCallbackQuery"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(AnswerCallbackQuery, ok=True, result=True)

View file

@ -2,12 +2,13 @@ import pytest
from aiogram import Bot
from aiogram.methods import AnswerInlineQuery, Request
from aiogram.types import InlineQueryResult, InlineQueryResultPhoto
from aiogram.types import InlineQueryResult, InlineQueryResultPhoto, InputTextMessageContent
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestAnswerInlineQuery:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(AnswerInlineQuery, ok=True, result=True)
@ -18,7 +19,6 @@ class TestAnswerInlineQuery:
assert request.method == "answerInlineQuery"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(AnswerInlineQuery, ok=True, result=True)
@ -40,3 +40,22 @@ class TestAnswerInlineQuery:
new_bot = Bot(token="42:TEST", parse_mode="HTML")
request = query.build_request(new_bot)
assert request.data["results"][0]["parse_mode"] == "HTML"
def test_parse_mode_input_message_content(self, bot: MockedBot):
query = AnswerInlineQuery(
inline_query_id="query id",
results=[
InlineQueryResultPhoto(
id="result id",
photo_url="photo",
thumb_url="thumb",
input_message_content=InputTextMessageContent(message_text="test"),
)
],
)
request = query.build_request(bot)
assert request.data["results"][0]["input_message_content"]["parse_mode"] is None
new_bot = Bot(token="42:TEST", parse_mode="HTML")
request = query.build_request(new_bot)
assert request.data["results"][0]["input_message_content"]["parse_mode"] == "HTML"

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import AnswerPreCheckoutQuery, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestAnswerPreCheckoutQuery:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(AnswerPreCheckoutQuery, ok=True, result=True)
@ -14,7 +15,6 @@ class TestAnswerPreCheckoutQuery:
assert request.method == "answerPreCheckoutQuery"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(AnswerPreCheckoutQuery, ok=True, result=True)

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import AnswerShippingQuery, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestAnswerShippingQuery:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(AnswerShippingQuery, ok=True, result=True)
@ -14,7 +15,6 @@ class TestAnswerShippingQuery:
assert request.method == "answerShippingQuery"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(AnswerShippingQuery, ok=True, result=True)

View file

@ -0,0 +1,24 @@
import pytest
from aiogram.methods import BanChatMember, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestKickChatMember:
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(BanChatMember, ok=True, result=True)
response: bool = await BanChatMember(chat_id=-42, user_id=42)
request: Request = bot.get_request()
assert request.method == "banChatMember"
assert response == prepare_result.result
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(BanChatMember, ok=True, result=True)
response: bool = await bot.ban_chat_member(chat_id=-42, user_id=42)
request: Request = bot.get_request()
assert request.method == "banChatMember"
assert response == prepare_result.result

View file

@ -6,6 +6,8 @@ from aiogram import Bot
from aiogram.methods.base import prepare_parse_mode
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestPrepareFile:
# TODO: Add tests
@ -34,7 +36,6 @@ class TestPrepareParseMode:
["Markdown", {"parse_mode": "HTML"}, "HTML"],
],
)
@pytest.mark.asyncio
async def test_default_parse_mode(
self, bot: MockedBot, parse_mode: str, data: Dict[str, str], result: Optional[str]
):
@ -43,7 +44,6 @@ class TestPrepareParseMode:
prepare_parse_mode(bot, data)
assert data.get("parse_mode") == result
@pytest.mark.asyncio
async def test_list(self):
data = [{}] * 2
data.append({"parse_mode": "HTML"})

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import Close, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestClose:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(Close, ok=True, result=True)
@ -15,7 +16,6 @@ class TestClose:
# assert request.data == {}
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(Close, ok=True, result=True)

View file

@ -4,9 +4,10 @@ from aiogram.methods import CopyMessage, Request
from aiogram.types import MessageId
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestCopyMessage:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(CopyMessage, ok=True, result=MessageId(message_id=42))
@ -20,7 +21,6 @@ class TestCopyMessage:
# assert request.data == {}
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(CopyMessage, ok=True, result=MessageId(message_id=42))

View file

@ -4,9 +4,10 @@ from aiogram.methods import CreateChatInviteLink, Request
from aiogram.types import ChatInviteLink, User
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestCreateChatInviteLink:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
CreateChatInviteLink,
@ -27,7 +28,6 @@ class TestCreateChatInviteLink:
# assert request.data == {"chat_id": -42}
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
CreateChatInviteLink,

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import CreateNewStickerSet, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestCreateNewStickerSet:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(CreateNewStickerSet, ok=True, result=True)
@ -16,7 +17,6 @@ class TestCreateNewStickerSet:
assert request.method == "createNewStickerSet"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(CreateNewStickerSet, ok=True, result=True)

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import DeleteChatPhoto, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestDeleteChatPhoto:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(DeleteChatPhoto, ok=True, result=True)
@ -14,7 +15,6 @@ class TestDeleteChatPhoto:
assert request.method == "deleteChatPhoto"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(DeleteChatPhoto, ok=True, result=True)

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import DeleteChatStickerSet, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestDeleteChatStickerSet:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(DeleteChatStickerSet, ok=True, result=True)
@ -14,7 +15,6 @@ class TestDeleteChatStickerSet:
assert request.method == "deleteChatStickerSet"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(DeleteChatStickerSet, ok=True, result=True)

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import DeleteMessage, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestDeleteMessage:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(DeleteMessage, ok=True, result=True)
@ -14,7 +15,6 @@ class TestDeleteMessage:
assert request.method == "deleteMessage"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(DeleteMessage, ok=True, result=True)

View file

@ -0,0 +1,24 @@
import pytest
from aiogram.methods import DeleteMyCommands, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestKickChatMember:
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(DeleteMyCommands, ok=True, result=True)
response: bool = await DeleteMyCommands()
request: Request = bot.get_request()
assert request.method == "deleteMyCommands"
assert response == prepare_result.result
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(DeleteMyCommands, ok=True, result=True)
response: bool = await bot.delete_my_commands()
request: Request = bot.get_request()
assert request.method == "deleteMyCommands"
assert response == prepare_result.result

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import DeleteStickerFromSet, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestDeleteStickerFromSet:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(DeleteStickerFromSet, ok=True, result=True)
@ -14,7 +15,6 @@ class TestDeleteStickerFromSet:
assert request.method == "deleteStickerFromSet"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(DeleteStickerFromSet, ok=True, result=True)

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import DeleteWebhook, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestDeleteWebhook:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(DeleteWebhook, ok=True, result=True)
@ -14,7 +15,6 @@ class TestDeleteWebhook:
assert request.method == "deleteWebhook"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(DeleteWebhook, ok=True, result=True)

View file

@ -4,9 +4,10 @@ from aiogram.methods import EditChatInviteLink, Request
from aiogram.types import ChatInviteLink, User
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestEditChatInviteLink:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
EditChatInviteLink,
@ -27,7 +28,6 @@ class TestEditChatInviteLink:
# assert request.data == {}
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
EditChatInviteLink,

View file

@ -7,9 +7,10 @@ from aiogram.methods import EditMessageCaption, Request
from aiogram.types import Chat, Message
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestEditMessageCaption:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
EditMessageCaption,
@ -27,7 +28,6 @@ class TestEditMessageCaption:
assert request.method == "editMessageCaption"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
EditMessageCaption,

View file

@ -6,9 +6,10 @@ from aiogram.methods import EditMessageLiveLocation, Request
from aiogram.types import Message
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestEditMessageLiveLocation:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(EditMessageLiveLocation, ok=True, result=True)
@ -19,7 +20,6 @@ class TestEditMessageLiveLocation:
assert request.method == "editMessageLiveLocation"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(EditMessageLiveLocation, ok=True, result=True)

View file

@ -3,12 +3,13 @@ from typing import Union
import pytest
from aiogram.methods import EditMessageMedia, Request
from aiogram.types import BufferedInputFile, InputMedia, InputMediaPhoto, Message
from aiogram.types import BufferedInputFile, InputMediaPhoto, Message
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestEditMessageMedia:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(EditMessageMedia, ok=True, result=True)
@ -19,7 +20,6 @@ class TestEditMessageMedia:
assert request.method == "editMessageMedia"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(EditMessageMedia, ok=True, result=True)

View file

@ -6,9 +6,10 @@ from aiogram.methods import EditMessageReplyMarkup, Request
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestEditMessageReplyMarkup:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(EditMessageReplyMarkup, ok=True, result=True)
@ -25,7 +26,6 @@ class TestEditMessageReplyMarkup:
assert request.method == "editMessageReplyMarkup"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(EditMessageReplyMarkup, ok=True, result=True)

View file

@ -6,9 +6,10 @@ from aiogram.methods import EditMessageText, Request
from aiogram.types import Message
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestEditMessageText:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(EditMessageText, ok=True, result=True)
@ -19,7 +20,6 @@ class TestEditMessageText:
assert request.method == "editMessageText"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(EditMessageText, ok=True, result=True)

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import ExportChatInviteLink, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestExportChatInviteLink:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
ExportChatInviteLink, ok=True, result="http://example.com"
@ -16,7 +17,6 @@ class TestExportChatInviteLink:
assert request.method == "exportChatInviteLink"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
ExportChatInviteLink, ok=True, result="http://example.com"

View file

@ -6,9 +6,10 @@ from aiogram.methods import ForwardMessage, Request
from aiogram.types import Chat, Message
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestForwardMessage:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
ForwardMessage,
@ -27,7 +28,6 @@ class TestForwardMessage:
# assert request.data == {}
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
ForwardMessage,

View file

@ -4,9 +4,10 @@ from aiogram.methods import GetChat, Request
from aiogram.types import Chat
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestGetChat:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
GetChat, ok=True, result=Chat(id=-42, type="channel", title="chat")
@ -17,7 +18,6 @@ class TestGetChat:
assert request.method == "getChat"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
GetChat, ok=True, result=Chat(id=-42, type="channel", title="chat")

View file

@ -3,18 +3,21 @@ from typing import List
import pytest
from aiogram.methods import GetChatAdministrators, Request
from aiogram.types import ChatMember, User
from aiogram.types import ChatMember, ChatMemberOwner, User
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestGetChatAdministrators:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
GetChatAdministrators,
ok=True,
result=[
ChatMember(user=User(id=42, is_bot=False, first_name="User"), status="creator")
ChatMemberOwner(
user=User(id=42, is_bot=False, first_name="User"), is_anonymous=False
)
],
)
@ -23,13 +26,14 @@ class TestGetChatAdministrators:
assert request.method == "getChatAdministrators"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
GetChatAdministrators,
ok=True,
result=[
ChatMember(user=User(id=42, is_bot=False, first_name="User"), status="creator")
ChatMemberOwner(
user=User(id=42, is_bot=False, first_name="User"), is_anonymous=False
)
],
)
response: List[ChatMember] = await bot.get_chat_administrators(chat_id=-42)

View file

@ -1,17 +1,20 @@
import pytest
from aiogram.methods import GetChatMember, Request
from aiogram.types import ChatMember, User
from aiogram.types import ChatMember, ChatMemberOwner, User
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestGetChatMember:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
GetChatMember,
ok=True,
result=ChatMember(user=User(id=42, is_bot=False, first_name="User"), status="creator"),
result=ChatMemberOwner(
user=User(id=42, is_bot=False, first_name="User"), is_anonymous=False
),
)
response: ChatMember = await GetChatMember(chat_id=-42, user_id=42)
@ -19,12 +22,13 @@ class TestGetChatMember:
assert request.method == "getChatMember"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
GetChatMember,
ok=True,
result=ChatMember(user=User(id=42, is_bot=False, first_name="User"), status="creator"),
result=ChatMemberOwner(
user=User(id=42, is_bot=False, first_name="User"), is_anonymous=False
),
)
response: ChatMember = await bot.get_chat_member(chat_id=-42, user_id=42)

View file

@ -0,0 +1,24 @@
import pytest
from aiogram.methods import GetChatMemberCount, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestGetChatMembersCount:
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(GetChatMemberCount, ok=True, result=42)
response: int = await GetChatMemberCount(chat_id=-42)
request: Request = bot.get_request()
assert request.method == "getChatMemberCount"
assert response == prepare_result.result
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(GetChatMemberCount, ok=True, result=42)
response: int = await bot.get_chat_member_count(chat_id=-42)
request: Request = bot.get_request()
assert request.method == "getChatMemberCount"
assert response == prepare_result.result

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import GetChatMembersCount, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestGetChatMembersCount:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(GetChatMembersCount, ok=True, result=42)
@ -14,7 +15,6 @@ class TestGetChatMembersCount:
assert request.method == "getChatMembersCount"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(GetChatMembersCount, ok=True, result=42)

View file

@ -4,9 +4,10 @@ from aiogram.methods import GetFile, Request
from aiogram.types import File
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestGetFile:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
GetFile, ok=True, result=File(file_id="file id", file_unique_id="file id")
@ -17,7 +18,6 @@ class TestGetFile:
assert request.method == "getFile"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
GetFile, ok=True, result=File(file_id="file id", file_unique_id="file id")

View file

@ -6,9 +6,10 @@ from aiogram.methods import GetGameHighScores, Request
from aiogram.types import GameHighScore, User
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestGetGameHighScores:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
GetGameHighScores,
@ -25,7 +26,6 @@ class TestGetGameHighScores:
assert request.method == "getGameHighScores"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
GetGameHighScores,

View file

@ -4,9 +4,10 @@ from aiogram.methods import GetMe, Request
from aiogram.types import User
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestGetMe:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
GetMe, ok=True, result=User(id=42, is_bot=False, first_name="User")
@ -18,7 +19,6 @@ class TestGetMe:
assert request.data == {}
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
GetMe, ok=True, result=User(id=42, is_bot=False, first_name="User")
@ -29,7 +29,6 @@ class TestGetMe:
assert request.data == {}
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_me_property(self, bot: MockedBot):
prepare_result = bot.add_result_for(
GetMe, ok=True, result=User(id=42, is_bot=False, first_name="User")

View file

@ -6,9 +6,10 @@ from aiogram.methods import GetMyCommands, Request
from aiogram.types import BotCommand
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestGetMyCommands:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(GetMyCommands, ok=True, result=None)
@ -17,7 +18,6 @@ class TestGetMyCommands:
assert request.method == "getMyCommands"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(GetMyCommands, ok=True, result=None)

View file

@ -4,9 +4,10 @@ from aiogram.methods import GetStickerSet, Request
from aiogram.types import Sticker, StickerSet
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestGetStickerSet:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
GetStickerSet,
@ -33,7 +34,6 @@ class TestGetStickerSet:
assert request.method == "getStickerSet"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
GetStickerSet,

View file

@ -6,9 +6,10 @@ from aiogram.methods import GetUpdates, Request
from aiogram.types import Update
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestGetUpdates:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(GetUpdates, ok=True, result=[Update(update_id=42)])
@ -17,7 +18,6 @@ class TestGetUpdates:
assert request.method == "getUpdates"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(GetUpdates, ok=True, result=[Update(update_id=42)])

View file

@ -0,0 +1,51 @@
import datetime
from typing import Optional
import pytest
from aiogram.types import Chat, Message
from tests.mocked_bot import MockedBot
class TestGetMessageUrl:
@pytest.mark.parametrize(
"chat_type,chat_id,chat_username,force_private,expected_result",
[
["private", 123456, "username", False, None],
["group", -123456, "username", False, None],
["supergroup", -1001234567890, None, False, "https://t.me/c/1234567890/10"],
["supergroup", -1001234567890, None, True, "https://t.me/c/1234567890/10"],
["supergroup", -1001234567890, "username", False, "https://t.me/username/10"],
["supergroup", -1001234567890, "username", True, "https://t.me/c/1234567890/10"],
["channel", -1001234567890, None, False, "https://t.me/c/1234567890/10"],
["channel", -1001234567890, None, True, "https://t.me/c/1234567890/10"],
["channel", -1001234567890, "username", False, "https://t.me/username/10"],
["channel", -1001234567890, "username", True, "https://t.me/c/1234567890/10"],
# 2 extra cases: 9-digit ID and 11-digit ID (without "-100")
["supergroup", -100123456789, None, True, "https://t.me/c/123456789/10"],
["supergroup", -10012345678901, None, True, "https://t.me/c/12345678901/10"],
],
)
def test_method(
self,
bot: MockedBot,
chat_type: str,
chat_id: int,
chat_username: Optional[str],
force_private: bool,
expected_result: Optional[str],
):
fake_chat = Chat(id=chat_id, username=chat_username, type=chat_type)
fake_message_id = 10
fake_message = Message(
message_id=fake_message_id,
date=datetime.datetime.now(),
text="test",
chat=fake_chat,
)
if expected_result is None:
assert fake_message.get_url(force_private=force_private) is None
else:
assert fake_message.get_url(force_private=force_private) == expected_result

View file

@ -4,9 +4,10 @@ from aiogram.methods import GetUserProfilePhotos, Request
from aiogram.types import PhotoSize, UserProfilePhotos
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestGetUserProfilePhotos:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
GetUserProfilePhotos,
@ -24,7 +25,6 @@ class TestGetUserProfilePhotos:
assert request.method == "getUserProfilePhotos"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
GetUserProfilePhotos,

View file

@ -4,9 +4,10 @@ from aiogram.methods import GetWebhookInfo, Request
from aiogram.types import WebhookInfo
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestGetWebhookInfo:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
GetWebhookInfo,
@ -21,7 +22,6 @@ class TestGetWebhookInfo:
assert request.method == "getWebhookInfo"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
GetWebhookInfo,

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import KickChatMember, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestKickChatMember:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(KickChatMember, ok=True, result=True)
@ -14,7 +15,6 @@ class TestKickChatMember:
assert request.method == "kickChatMember"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(KickChatMember, ok=True, result=True)

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import LeaveChat, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestLeaveChat:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(LeaveChat, ok=True, result=True)
@ -14,7 +15,6 @@ class TestLeaveChat:
assert request.method == "leaveChat"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(LeaveChat, ok=True, result=True)

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import LogOut, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestLogOut:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(LogOut, ok=True, result=True)
@ -15,7 +16,6 @@ class TestLogOut:
# assert request.data == {}
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(LogOut, ok=True, result=True)

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import PinChatMessage, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestPinChatMessage:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(PinChatMessage, ok=True, result=True)
@ -14,7 +15,6 @@ class TestPinChatMessage:
assert request.method == "pinChatMessage"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(PinChatMessage, ok=True, result=True)

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import PromoteChatMember, Request
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestPromoteChatMember:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(PromoteChatMember, ok=True, result=True)
@ -14,7 +15,6 @@ class TestPromoteChatMember:
assert request.method == "promoteChatMember"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(PromoteChatMember, ok=True, result=True)

View file

@ -4,9 +4,10 @@ from aiogram.methods import Request, RestrictChatMember
from aiogram.types import ChatPermissions
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestRestrictChatMember:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(RestrictChatMember, ok=True, result=True)
@ -17,7 +18,6 @@ class TestRestrictChatMember:
assert request.method == "restrictChatMember"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(RestrictChatMember, ok=True, result=True)

View file

@ -4,9 +4,10 @@ from aiogram.methods import Request, RevokeChatInviteLink
from aiogram.types import ChatInviteLink, User
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestRevokeChatInviteLink:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
RevokeChatInviteLink,
@ -28,7 +29,6 @@ class TestRevokeChatInviteLink:
# assert request.data == {}
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
RevokeChatInviteLink,

View file

@ -6,9 +6,10 @@ from aiogram.methods import Request, SendAnimation
from aiogram.types import Animation, Chat, Message
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSendAnimation:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendAnimation,
@ -28,7 +29,6 @@ class TestSendAnimation:
assert request.method == "sendAnimation"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendAnimation,

View file

@ -3,12 +3,13 @@ import datetime
import pytest
from aiogram.methods import Request, SendAudio
from aiogram.types import Audio, Chat, File, Message
from aiogram.types import Audio, Chat, Message
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSendAudio:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendAudio,
@ -26,7 +27,6 @@ class TestSendAudio:
assert request.method == "sendAudio"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendAudio,

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import Request, SendChatAction
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSendChatAction:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SendChatAction, ok=True, result=True)
@ -14,7 +15,6 @@ class TestSendChatAction:
assert request.method == "sendChatAction"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SendChatAction, ok=True, result=True)

View file

@ -6,9 +6,10 @@ from aiogram.methods import Request, SendContact
from aiogram.types import Chat, Contact, Message
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSendContact:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendContact,
@ -26,7 +27,6 @@ class TestSendContact:
assert request.method == "sendContact"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendContact,

View file

@ -4,9 +4,10 @@ from aiogram.methods import Request, SendDice
from aiogram.types import Message
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSendDice:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SendDice, ok=True, result=None)
@ -15,7 +16,6 @@ class TestSendDice:
assert request.method == "sendDice"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SendDice, ok=True, result=None)

View file

@ -6,9 +6,10 @@ from aiogram.methods import Request, SendDocument
from aiogram.types import Chat, Document, Message
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSendDocument:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendDocument,
@ -26,7 +27,6 @@ class TestSendDocument:
assert request.method == "sendDocument"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendDocument,

View file

@ -6,9 +6,10 @@ from aiogram.methods import Request, SendGame
from aiogram.types import Chat, Game, Message, PhotoSize
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSendGame:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendGame,
@ -32,7 +33,6 @@ class TestSendGame:
assert request.method == "sendGame"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendGame,

View file

@ -6,9 +6,10 @@ from aiogram.methods import Request, SendInvoice
from aiogram.types import Chat, Invoice, LabeledPrice, Message
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSendInvoice:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendInvoice,
@ -41,7 +42,6 @@ class TestSendInvoice:
assert request.method == "sendInvoice"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendInvoice,

View file

@ -6,9 +6,10 @@ from aiogram.methods import Request, SendLocation
from aiogram.types import Chat, Location, Message
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSendLocation:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendLocation,
@ -26,7 +27,6 @@ class TestSendLocation:
assert request.method == "sendLocation"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendLocation,

View file

@ -15,9 +15,10 @@ from aiogram.types import (
)
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSendMediaGroup:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendMediaGroup,
@ -59,7 +60,6 @@ class TestSendMediaGroup:
assert request.method == "sendMediaGroup"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendMediaGroup,

View file

@ -6,9 +6,10 @@ from aiogram.methods import Request, SendMessage
from aiogram.types import Chat, Message
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSendMessage:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendMessage,
@ -26,7 +27,6 @@ class TestSendMessage:
assert request.method == "sendMessage"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendMessage,

View file

@ -6,9 +6,10 @@ from aiogram.methods import Request, SendPhoto
from aiogram.types import Chat, Message, PhotoSize
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSendPhoto:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendPhoto,
@ -28,7 +29,6 @@ class TestSendPhoto:
assert request.method == "sendPhoto"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendPhoto,

View file

@ -6,9 +6,10 @@ from aiogram.methods import Request, SendPoll
from aiogram.types import Chat, Message, Poll, PollOption
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSendPoll:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendPoll,
@ -41,7 +42,6 @@ class TestSendPoll:
assert request.method == "sendPoll"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendPoll,

View file

@ -6,9 +6,10 @@ from aiogram.methods import Request, SendSticker
from aiogram.types import Chat, Message, Sticker
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSendSticker:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendSticker,
@ -32,7 +33,6 @@ class TestSendSticker:
assert request.method == "sendSticker"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendSticker,

View file

@ -6,9 +6,10 @@ from aiogram.methods import Request, SendVenue
from aiogram.types import Chat, Location, Message, Venue
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSendVenue:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendVenue,
@ -38,7 +39,6 @@ class TestSendVenue:
assert request.method == "sendVenue"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendVenue,

View file

@ -6,9 +6,10 @@ from aiogram.methods import Request, SendVideo
from aiogram.types import Chat, Message, Video
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSendVideo:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendVideo,
@ -28,7 +29,6 @@ class TestSendVideo:
assert request.method == "sendVideo"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendVideo,

View file

@ -6,9 +6,10 @@ from aiogram.methods import Request, SendVideoNote
from aiogram.types import BufferedInputFile, Chat, Message, VideoNote
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSendVideoNote:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendVideoNote,
@ -30,7 +31,6 @@ class TestSendVideoNote:
assert request.method == "sendVideoNote"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendVideoNote,

View file

@ -6,9 +6,10 @@ from aiogram.methods import Request, SendVoice
from aiogram.types import Chat, Message, Voice
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSendVoice:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendVoice,
@ -26,7 +27,6 @@ class TestSendVoice:
assert request.method == "sendVoice"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
SendVoice,

View file

@ -1,11 +1,12 @@
import pytest
from aiogram.methods import Request, SetChatAdministratorCustomTitle, SetChatTitle
from aiogram.methods import Request, SetChatAdministratorCustomTitle
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSetChatTitle:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetChatAdministratorCustomTitle, ok=True, result=True)
@ -16,7 +17,6 @@ class TestSetChatTitle:
assert request.method == "setChatAdministratorCustomTitle"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetChatAdministratorCustomTitle, ok=True, result=True)

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import Request, SetChatDescription
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSetChatDescription:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetChatDescription, ok=True, result=True)
@ -14,7 +15,6 @@ class TestSetChatDescription:
assert request.method == "setChatDescription"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetChatDescription, ok=True, result=True)

View file

@ -4,9 +4,10 @@ from aiogram.methods import Request, SetChatPermissions
from aiogram.types import ChatPermissions
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSetChatPermissions:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetChatPermissions, ok=True, result=True)
@ -17,7 +18,6 @@ class TestSetChatPermissions:
assert request.method == "setChatPermissions"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetChatPermissions, ok=True, result=True)

View file

@ -1,12 +1,13 @@
import pytest
from aiogram.methods import Request, SetChatPhoto
from aiogram.types import BufferedInputFile, InputFile
from aiogram.types import BufferedInputFile
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSetChatPhoto:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetChatPhoto, ok=True, result=True)
@ -17,7 +18,6 @@ class TestSetChatPhoto:
assert request.method == "setChatPhoto"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetChatPhoto, ok=True, result=True)

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import Request, SetChatStickerSet
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSetChatStickerSet:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetChatStickerSet, ok=True, result=True)
@ -14,7 +15,6 @@ class TestSetChatStickerSet:
assert request.method == "setChatStickerSet"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetChatStickerSet, ok=True, result=True)

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import Request, SetChatTitle
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSetChatTitle:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetChatTitle, ok=True, result=True)
@ -14,7 +15,6 @@ class TestSetChatTitle:
assert request.method == "setChatTitle"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetChatTitle, ok=True, result=True)

View file

@ -6,9 +6,10 @@ from aiogram.methods import Request, SetGameScore
from aiogram.types import Message
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSetGameScore:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetGameScore, ok=True, result=True)
@ -19,7 +20,6 @@ class TestSetGameScore:
assert request.method == "setGameScore"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetGameScore, ok=True, result=True)

View file

@ -4,9 +4,10 @@ from aiogram.methods import Request, SetMyCommands
from aiogram.types import BotCommand
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSetMyCommands:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetMyCommands, ok=True, result=None)
@ -17,7 +18,6 @@ class TestSetMyCommands:
assert request.method == "setMyCommands"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetMyCommands, ok=True, result=None)

View file

@ -4,9 +4,10 @@ from aiogram.methods import Request, SetPassportDataErrors
from aiogram.types import PassportElementError
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSetPassportDataErrors:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetPassportDataErrors, ok=True, result=True)
@ -15,7 +16,6 @@ class TestSetPassportDataErrors:
assert request.method == "setPassportDataErrors"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetPassportDataErrors, ok=True, result=True)

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import Request, SetStickerPositionInSet
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSetStickerPositionInSet:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetStickerPositionInSet, ok=True, result=True)
@ -14,7 +15,6 @@ class TestSetStickerPositionInSet:
assert request.method == "setStickerPositionInSet"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetStickerPositionInSet, ok=True, result=True)

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import Request, SetStickerSetThumb
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSetStickerSetThumb:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetStickerSetThumb, ok=True, result=None)
@ -15,7 +16,6 @@ class TestSetStickerSetThumb:
# assert request.data == {}
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetStickerSetThumb, ok=True, result=None)

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import Request, SetWebhook
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestSetWebhook:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetWebhook, ok=True, result=True)
@ -14,7 +15,6 @@ class TestSetWebhook:
assert request.method == "setWebhook"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(SetWebhook, ok=True, result=True)

View file

@ -6,9 +6,10 @@ from aiogram.methods import Request, StopMessageLiveLocation
from aiogram.types import Message
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestStopMessageLiveLocation:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(StopMessageLiveLocation, ok=True, result=True)
@ -19,7 +20,6 @@ class TestStopMessageLiveLocation:
assert request.method == "stopMessageLiveLocation"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(StopMessageLiveLocation, ok=True, result=True)

View file

@ -4,9 +4,10 @@ from aiogram.methods import Request, StopPoll
from aiogram.types import Poll, PollOption
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestStopPoll:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
StopPoll,
@ -29,7 +30,6 @@ class TestStopPoll:
assert request.method == "stopPoll"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
StopPoll,

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import Request, UnbanChatMember
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestUnbanChatMember:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(UnbanChatMember, ok=True, result=True)
@ -14,7 +15,6 @@ class TestUnbanChatMember:
assert request.method == "unbanChatMember"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(UnbanChatMember, ok=True, result=True)

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import Request, UnpinAllChatMessages
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestUnpinAllChatMessages:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(UnpinAllChatMessages, ok=True, result=True)
@ -17,7 +18,6 @@ class TestUnpinAllChatMessages:
# assert request.data == {}
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(UnpinAllChatMessages, ok=True, result=True)

View file

@ -3,9 +3,10 @@ import pytest
from aiogram.methods import Request, UnpinChatMessage
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestUnpinChatMessage:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(UnpinChatMessage, ok=True, result=True)
@ -14,7 +15,6 @@ class TestUnpinChatMessage:
assert request.method == "unpinChatMessage"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(UnpinChatMessage, ok=True, result=True)

View file

@ -4,9 +4,10 @@ from aiogram.methods import Request, UploadStickerFile
from aiogram.types import BufferedInputFile, File
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestUploadStickerFile:
@pytest.mark.asyncio
async def test_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
UploadStickerFile, ok=True, result=File(file_id="file id", file_unique_id="file id")
@ -19,7 +20,6 @@ class TestUploadStickerFile:
assert request.method == "uploadStickerFile"
assert response == prepare_result.result
@pytest.mark.asyncio
async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(
UploadStickerFile, ok=True, result=File(file_id="file id", file_unique_id="file id")

View file

@ -1,29 +0,0 @@
import pytest
from aiogram.types import ChatMember, User
user = User(id=42, is_bot=False, first_name="User", last_name=None)
class TestChatMember:
@pytest.mark.parametrize(
"status,result", [["administrator", True], ["creator", True], ["member", False]]
)
def test_is_chat_admin(self, status: str, result: bool):
chat_member = ChatMember(user=user, status=status)
assert chat_member.is_chat_admin == result
@pytest.mark.parametrize(
"status,result",
[
["administrator", True],
["creator", True],
["member", True],
["restricted", True],
["kicked", False],
["left", False],
],
)
def test_is_chat_member(self, status: str, result: bool):
chat_member = ChatMember(user=user, status=status)
assert chat_member.is_chat_member == result

View file

@ -6,6 +6,8 @@ from aresponses import ResponsesMockServer
from aiogram import Bot
from aiogram.types import BufferedInputFile, FSInputFile, InputFile, URLInputFile
pytestmark = pytest.mark.asyncio
class TestInputFile:
def test_fs_input_file(self):
@ -18,7 +20,6 @@ class TestInputFile:
assert file.filename.endswith(".py")
assert file.chunk_size > 0
@pytest.mark.asyncio
async def test_fs_input_file_readable(self):
file = FSInputFile(__file__, chunk_size=1)
@ -39,7 +40,6 @@ class TestInputFile:
assert file.filename == "file.bin"
assert isinstance(file.data, bytes)
@pytest.mark.asyncio
async def test_buffered_input_file_readable(self):
file = BufferedInputFile(b"\f" * 10, filename="file.bin", chunk_size=1)
@ -50,7 +50,6 @@ class TestInputFile:
size += chunk_size
assert size == 10
@pytest.mark.asyncio
async def test_buffered_input_file_from_file(self):
file = BufferedInputFile.from_file(__file__, chunk_size=10)
@ -62,7 +61,6 @@ class TestInputFile:
assert isinstance(file.data, bytes)
assert file.chunk_size == 10
@pytest.mark.asyncio
async def test_buffered_input_file_from_file_readable(self):
file = BufferedInputFile.from_file(__file__, chunk_size=1)
@ -73,7 +71,6 @@ class TestInputFile:
size += chunk_size
assert size > 0
@pytest.mark.asyncio
async def test_uri_input_file(self, aresponses: ResponsesMockServer):
aresponses.add(
aresponses.ANY, aresponses.ANY, "get", aresponses.Response(status=200, body=b"\f" * 10)

View file

@ -5,6 +5,10 @@ import pytest
from aiogram.methods import (
CopyMessage,
DeleteMessage,
EditMessageCaption,
EditMessageReplyMarkup,
EditMessageText,
SendAnimation,
SendAudio,
SendContact,
@ -33,6 +37,8 @@ from aiogram.types import (
Document,
EncryptedCredentials,
Game,
InlineKeyboardButton,
InlineKeyboardMarkup,
Invoice,
Location,
MessageAutoDeleteTimerChanged,
@ -549,3 +555,86 @@ class TestMessage:
if method:
assert isinstance(method, expected_method)
# TODO: Check additional fields
def test_edit_text(self):
message = Message(
message_id=42, chat=Chat(id=42, type="private"), date=datetime.datetime.now()
)
method = message.edit_text(text="test")
assert isinstance(method, EditMessageText)
assert method.chat_id == message.chat.id
def test_edit_reply_markup(self):
reply_markup = InlineKeyboardMarkup(
inline_keyboard=[
[
InlineKeyboardButton(
text="test",
callback_data="test",
),
],
]
)
reply_markup_new = InlineKeyboardMarkup(
inline_keyboard=[
[
InlineKeyboardButton(
text="test2",
callback_data="test2",
),
],
]
)
message = Message(
message_id=42,
chat=Chat(id=42, type="private"),
date=datetime.datetime.now(),
reply_markup=reply_markup,
)
method = message.edit_reply_markup(
reply_markup=reply_markup_new,
)
assert isinstance(method, EditMessageReplyMarkup)
assert method.reply_markup == reply_markup_new
assert method.chat_id == message.chat.id
def test_delete_reply_markup(self):
reply_markup = InlineKeyboardMarkup(
inline_keyboard=[
[
InlineKeyboardButton(
text="test",
callback_data="test",
),
],
]
)
message = Message(
message_id=42,
chat=Chat(id=42, type="private"),
date=datetime.datetime.now(),
reply_markup=reply_markup,
)
method = message.delete_reply_markup()
assert isinstance(method, EditMessageReplyMarkup)
assert method.reply_markup is None
assert method.chat_id == message.chat.id
def test_edit_caption(self):
message = Message(
message_id=42, chat=Chat(id=42, type="private"), date=datetime.datetime.now()
)
method = message.edit_caption(caption="test")
assert isinstance(method, EditMessageCaption)
assert method.chat_id == message.chat.id
def test_delete(self):
message = Message(
message_id=42, chat=Chat(id=42, type="private"), date=datetime.datetime.now()
)
method = message.delete()
assert isinstance(method, DeleteMessage)
assert method.chat_id == message.chat.id
assert method.message_id == message.message_id

View file

@ -2,6 +2,7 @@ import asyncio
import datetime
import time
import warnings
from collections import Counter
from typing import Any
import pytest
@ -9,14 +10,12 @@ import pytest
from aiogram import Bot
from aiogram.dispatcher.dispatcher import Dispatcher
from aiogram.dispatcher.event.bases import UNHANDLED, SkipHandler
from aiogram.dispatcher.fsm.strategy import FSMStrategy
from aiogram.dispatcher.middlewares.user_context import UserContextMiddleware
from aiogram.dispatcher.router import Router
from aiogram.methods import GetMe, GetUpdates, SendMessage
from aiogram.types import (
CallbackQuery,
Chat,
ChatMember,
ChatMemberMember,
ChatMemberUpdated,
ChosenInlineResult,
InlineQuery,
@ -30,6 +29,7 @@ from aiogram.types import (
Update,
User,
)
from aiogram.utils.handlers_in_use import get_handlers_in_use
from tests.mocked_bot import MockedBot
try:
@ -38,6 +38,8 @@ except ImportError:
from unittest.mock import AsyncMock as CoroutineMock # type: ignore
from unittest.mock import patch
pytestmark = pytest.mark.asyncio
async def simple_message_handler(message: Message):
await asyncio.sleep(0.2)
@ -49,6 +51,10 @@ async def invalid_message_handler(message: Message):
raise Exception(42)
async def anext(ait):
return await ait.__anext__()
RAW_UPDATE = {
"update_id": 42,
"message": {
@ -78,7 +84,6 @@ class TestDispatcher:
dp._parent_router = Router()
assert dp.parent_router is None
@pytest.mark.asyncio
@pytest.mark.parametrize("isolate_events", (True, False))
async def test_feed_update(self, isolate_events):
dp = Dispatcher(isolate_events=isolate_events)
@ -108,7 +113,6 @@ class TestDispatcher:
results_count += 1
assert result == "test"
@pytest.mark.asyncio
async def test_feed_raw_update(self):
dp = Dispatcher()
bot = Bot("42:TEST")
@ -133,7 +137,6 @@ class TestDispatcher:
)
assert result == "test"
@pytest.mark.asyncio
async def test_listen_updates(self, bot: MockedBot):
dispatcher = Dispatcher()
bot.add_result_for(
@ -147,7 +150,20 @@ class TestDispatcher:
break
assert index == 42
@pytest.mark.asyncio
async def test_listen_update_with_error(self, bot: MockedBot):
dispatcher = Dispatcher()
listen = dispatcher._listen_updates(bot=bot)
bot.add_result_for(
GetUpdates, ok=True, result=[Update(update_id=update_id) for update_id in range(42)]
)
bot.add_result_for(GetUpdates, ok=False, error_code=500, description="restarting")
with patch(
"aiogram.utils.backoff.Backoff.asleep",
new_callable=CoroutineMock,
) as mocked_asleep:
assert isinstance(await anext(listen), Update)
assert mocked_asleep.awaited
async def test_silent_call_request(self, bot: MockedBot, caplog):
dispatcher = Dispatcher()
bot.add_result_for(SendMessage, ok=False, error_code=400, description="Kaboom")
@ -156,14 +172,12 @@ class TestDispatcher:
assert len(log_records) == 1
assert "Failed to make answer" in log_records[0]
@pytest.mark.asyncio
async def test_process_update_empty(self, bot: MockedBot):
dispatcher = Dispatcher()
result = await dispatcher._process_update(bot=bot, update=Update(update_id=42))
assert not result
@pytest.mark.asyncio
async def test_process_update_handled(self, bot: MockedBot):
dispatcher = Dispatcher()
@ -173,7 +187,6 @@ class TestDispatcher:
assert await dispatcher._process_update(bot=bot, update=Update(update_id=42))
@pytest.mark.asyncio
@pytest.mark.parametrize(
"event_type,update,has_chat,has_user",
[
@ -376,11 +389,11 @@ class TestDispatcher:
chat=Chat(id=42, type="private"),
from_user=User(id=42, is_bot=False, first_name="Test"),
date=datetime.datetime.now(),
old_chat_member=ChatMember(
user=User(id=42, is_bot=False, first_name="Test"), status="restricted"
old_chat_member=ChatMemberMember(
user=User(id=42, is_bot=False, first_name="Test")
),
new_chat_member=ChatMember(
user=User(id=42, is_bot=False, first_name="Test"), status="restricted"
new_chat_member=ChatMemberMember(
user=User(id=42, is_bot=False, first_name="Test")
),
),
),
@ -395,11 +408,11 @@ class TestDispatcher:
chat=Chat(id=42, type="private"),
from_user=User(id=42, is_bot=False, first_name="Test"),
date=datetime.datetime.now(),
old_chat_member=ChatMember(
user=User(id=42, is_bot=False, first_name="Test"), status="restricted"
old_chat_member=ChatMemberMember(
user=User(id=42, is_bot=False, first_name="Test")
),
new_chat_member=ChatMember(
user=User(id=42, is_bot=False, first_name="Test"), status="restricted"
new_chat_member=ChatMemberMember(
user=User(id=42, is_bot=False, first_name="Test")
),
),
),
@ -409,7 +422,12 @@ class TestDispatcher:
],
)
async def test_listen_update(
self, event_type: str, update: Update, has_chat: bool, has_user: bool
self,
event_type: str,
update: Update,
has_chat: bool,
has_user: bool,
bot: MockedBot,
):
router = Dispatcher()
observer = router.observers[event_type]
@ -423,20 +441,18 @@ class TestDispatcher:
assert User.get_current(False)
return kwargs
result = await router.update.trigger(update, test="PASS")
result = await router.feed_update(bot, update, test="PASS")
assert isinstance(result, dict)
assert result["event_update"] == update
assert result["event_router"] == router
assert result["test"] == "PASS"
@pytest.mark.asyncio
async def test_listen_unknown_update(self):
dp = Dispatcher()
with pytest.raises(SkipHandler):
await dp._listen_update(Update(update_id=42))
@pytest.mark.asyncio
async def test_listen_unhandled_update(self):
dp = Dispatcher()
observer = dp.observers["message"]
@ -466,8 +482,7 @@ class TestDispatcher:
)
assert response is UNHANDLED
@pytest.mark.asyncio
async def test_nested_router_listen_update(self):
async def test_nested_router_listen_update(self, bot: MockedBot):
dp = Dispatcher()
router0 = Router()
router1 = Router()
@ -489,13 +504,55 @@ class TestDispatcher:
from_user=User(id=42, is_bot=False, first_name="Test"),
),
)
result = await dp._listen_update(update, test="PASS")
result = await dp.feed_update(bot, update, test="PASS")
assert isinstance(result, dict)
assert result["event_update"] == update
assert result["event_router"] == router1
assert result["test"] == "PASS"
@pytest.mark.asyncio
async def test_nested_router_middleware_resolution(self, bot: MockedBot):
counter = Counter()
def mw(type_: str, inject_data: dict):
async def middleware(h, event, data):
counter[type_] += 1
data.update(inject_data)
return await h(event, data)
return middleware
async def handler(event, foo, bar, baz, fizz, buzz):
counter["child.handler"] += 1
root = Dispatcher()
child = Router()
root.message.outer_middleware(mw("root.outer_middleware", {"foo": True}))
root.message.middleware(mw("root.middleware", {"bar": None}))
child.message.outer_middleware(mw("child.outer_middleware", {"fizz": 42}))
child.message.middleware(mw("child.middleware", {"buzz": -42}))
child.message.register(handler)
root.include_router(child)
await root.feed_update(
bot=bot,
update=Update(
update_id=42,
message=Message(
message_id=42,
date=datetime.datetime.fromtimestamp(0),
chat=Chat(id=-42, type="group"),
),
),
baz=...,
)
assert counter["root.outer_middleware"] == 1
assert counter["root.middleware"] == 1
assert counter["child.outer_middleware"] == 1
assert counter["child.middleware"] == 1
assert counter["child.handler"] == 1
async def test_process_update_call_request(self, bot: MockedBot):
dispatcher = Dispatcher()
@ -513,7 +570,6 @@ class TestDispatcher:
print(result)
mocked_silent_call_request.assert_awaited()
@pytest.mark.asyncio
async def test_process_update_exception(self, bot: MockedBot, caplog):
dispatcher = Dispatcher()
@ -526,8 +582,8 @@ class TestDispatcher:
assert len(log_records) == 1
assert "Cause exception while process update" in log_records[0]
@pytest.mark.asyncio
async def test_polling(self, bot: MockedBot):
@pytest.mark.parametrize("as_task", [True, False])
async def test_polling(self, bot: MockedBot, as_task: bool):
dispatcher = Dispatcher()
async def _mock_updates(*_):
@ -539,18 +595,23 @@ class TestDispatcher:
"aiogram.dispatcher.dispatcher.Dispatcher._listen_updates"
) as patched_listen_updates:
patched_listen_updates.return_value = _mock_updates()
await dispatcher._polling(bot=bot)
mocked_process_update.assert_awaited()
await dispatcher._polling(bot=bot, handle_as_tasks=as_task)
if as_task:
pass
else:
mocked_process_update.assert_awaited()
@pytest.mark.asyncio
async def test_exception_handler_catch_exceptions(self):
async def test_exception_handler_catch_exceptions(self, bot: MockedBot):
dp = Dispatcher()
router = Router()
dp.include_router(router)
class CustomException(Exception):
pass
@router.message()
async def message_handler(message: Message):
raise Exception("KABOOM")
raise CustomException("KABOOM")
update = Update(
update_id=42,
@ -562,26 +623,25 @@ class TestDispatcher:
from_user=User(id=42, is_bot=False, first_name="Test"),
),
)
with pytest.raises(Exception, match="KABOOM"):
await dp.update.trigger(update)
with pytest.raises(CustomException, match="KABOOM"):
await dp.feed_update(bot, update)
@router.errors()
async def error_handler(event: Update, exception: Exception):
return "KABOOM"
response = await dp.update.trigger(update)
response = await dp.feed_update(bot, update)
assert response == "KABOOM"
@dp.errors()
async def root_error_handler(event: Update, exception: Exception):
return exception
response = await dp.update.trigger(update)
response = await dp.feed_update(bot, update)
assert isinstance(response, Exception)
assert isinstance(response, CustomException)
assert str(response) == "KABOOM"
@pytest.mark.asyncio
async def test_start_polling(self, bot: MockedBot):
dispatcher = Dispatcher()
bot.add_result_for(
@ -615,7 +675,6 @@ class TestDispatcher:
dispatcher.run_polling(bot)
patched_start_polling.assert_awaited_once()
@pytest.mark.asyncio
async def test_feed_webhook_update_fast_process(self, bot: MockedBot):
dispatcher = Dispatcher()
dispatcher.message.register(simple_message_handler)
@ -625,7 +684,6 @@ class TestDispatcher:
assert response["method"] == "sendMessage"
assert response["text"] == "ok"
@pytest.mark.asyncio
async def test_feed_webhook_update_slow_process(self, bot: MockedBot, recwarn):
warnings.simplefilter("always")
@ -641,7 +699,6 @@ class TestDispatcher:
await asyncio.sleep(0.5)
mocked_silent_call_request.assert_awaited()
@pytest.mark.asyncio
async def test_feed_webhook_update_fast_process_error(self, bot: MockedBot, caplog):
warnings.simplefilter("always")
@ -655,19 +712,55 @@ class TestDispatcher:
log_records = [rec.message for rec in caplog.records]
assert "Cause exception while process update" in log_records[0]
@pytest.mark.parametrize(
"strategy,case,expected",
[
[FSMStrategy.USER_IN_CHAT, (-42, 42), (-42, 42)],
[FSMStrategy.CHAT, (-42, 42), (-42, -42)],
[FSMStrategy.GLOBAL_USER, (-42, 42), (42, 42)],
[FSMStrategy.USER_IN_CHAT, (42, 42), (42, 42)],
[FSMStrategy.CHAT, (42, 42), (42, 42)],
[FSMStrategy.GLOBAL_USER, (42, 42), (42, 42)],
],
)
def test_get_current_state_context(self, strategy, case, expected):
dp = Dispatcher(fsm_strategy=strategy)
chat_id, user_id = case
state = dp.current_state(chat_id=chat_id, user_id=user_id)
assert (state.chat_id, state.user_id) == expected
def test_specify_updates_calculation(self):
def simple_msg_handler() -> None:
...
def simple_callback_query_handler() -> None:
...
def simple_poll_handler() -> None:
...
def simple_edited_msg_handler() -> None:
...
dispatcher = Dispatcher()
dispatcher.message.register(simple_msg_handler)
router1 = Router()
router1.callback_query.register(simple_callback_query_handler)
router2 = Router()
router2.poll.register(simple_poll_handler)
router21 = Router()
router21.edited_message.register(simple_edited_msg_handler)
useful_updates1 = get_handlers_in_use(dispatcher)
assert sorted(useful_updates1) == sorted(["message"])
dispatcher.include_router(router1)
useful_updates2 = get_handlers_in_use(dispatcher)
assert sorted(useful_updates2) == sorted(["message", "callback_query"])
dispatcher.include_router(router2)
useful_updates3 = get_handlers_in_use(dispatcher)
assert sorted(useful_updates3) == sorted(["message", "callback_query", "poll"])
router2.include_router(router21)
useful_updates4 = get_handlers_in_use(dispatcher)
assert sorted(useful_updates4) == sorted(
["message", "callback_query", "poll", "edited_message"]
)
useful_updates5 = get_handlers_in_use(router2)
assert sorted(useful_updates5) == sorted(["poll", "edited_message"])

View file

@ -12,6 +12,8 @@ except ImportError:
from unittest.mock import AsyncMock as CoroutineMock # type: ignore
from unittest.mock import patch
pytestmark = pytest.mark.asyncio
async def my_handler(value: str, index: int = 0) -> Any:
return value
@ -39,7 +41,6 @@ class TestEventObserver:
assert registered_handler.callback == wrapped_handler
assert not registered_handler.filters
@pytest.mark.asyncio
async def test_trigger(self):
observer = EventObserver()

View file

@ -5,11 +5,12 @@ import pytest
from aiogram import F
from aiogram.dispatcher.event.handler import CallableMixin, FilterObject, HandlerObject
from aiogram.dispatcher.filters import Text
from aiogram.dispatcher.filters.base import BaseFilter
from aiogram.dispatcher.handler.base import BaseHandler
from aiogram.types import Update
pytestmark = pytest.mark.asyncio
def callback1(foo: int, bar: int, baz: int):
return locals()
@ -23,6 +24,10 @@ async def callback3(foo: int, **kwargs):
return locals()
async def callback4(foo: int, *, bar: int, baz: int):
return locals()
class Filter(BaseFilter):
async def __call__(self, foo: int, bar: int, baz: int) -> Union[bool, Dict[str, Any]]:
return locals()
@ -96,11 +101,21 @@ class TestCallableMixin:
{"foo": 42, "spam": True, "baz": "fuz", "bar": "test"},
{"foo": 42, "baz": "fuz", "bar": "test"},
),
pytest.param(
functools.partial(callback2, bar="test"),
{"foo": 42, "spam": True, "baz": "fuz"},
{"foo": 42, "baz": "fuz"},
),
pytest.param(
callback3,
{"foo": 42, "spam": True, "baz": "fuz", "bar": "test"},
{"foo": 42, "spam": True, "baz": "fuz", "bar": "test"},
),
pytest.param(
callback4,
{"foo": 42, "spam": True, "baz": "fuz", "bar": "test"},
{"foo": 42, "baz": "fuz", "bar": "test"},
),
pytest.param(
Filter(), {"foo": 42, "spam": True, "baz": "fuz"}, {"foo": 42, "baz": "fuz"}
),
@ -113,14 +128,12 @@ class TestCallableMixin:
obj = CallableMixin(callback)
assert obj._prepare_kwargs(kwargs) == result
@pytest.mark.asyncio
async def test_sync_call(self):
obj = CallableMixin(callback1)
result = await obj.call(foo=42, bar="test", baz="fuz", spam=True)
assert result == {"foo": 42, "bar": "test", "baz": "fuz"}
@pytest.mark.asyncio
async def test_async_call(self):
obj = CallableMixin(callback2)
@ -141,14 +154,12 @@ async def simple_handler(*args, **kwargs):
class TestHandlerObject:
@pytest.mark.asyncio
async def test_check_with_bool_result(self):
handler = HandlerObject(simple_handler, [FilterObject(lambda value: True)] * 3)
result, data = await handler.check(42, foo=True)
assert result
assert data == {"foo": True}
@pytest.mark.asyncio
async def test_check_with_dict_result(self):
handler = HandlerObject(
simple_handler,
@ -163,7 +174,6 @@ class TestHandlerObject:
assert result
assert data == {"foo": True, "test0": "ok", "test1": "ok", "test2": "ok"}
@pytest.mark.asyncio
async def test_check_with_combined_result(self):
handler = HandlerObject(
simple_handler,
@ -173,13 +183,11 @@ class TestHandlerObject:
assert result
assert data == {"foo": True, "test": 42}
@pytest.mark.asyncio
async def test_check_rejected(self):
handler = HandlerObject(simple_handler, [FilterObject(lambda value: False)])
result, data = await handler.check(42, foo=True)
assert not result
@pytest.mark.asyncio
async def test_check_partial_rejected(self):
handler = HandlerObject(
simple_handler, [FilterObject(lambda value: True), FilterObject(lambda value: False)]
@ -187,7 +195,6 @@ class TestHandlerObject:
result, data = await handler.check(42, foo=True)
assert not result
@pytest.mark.asyncio
async def test_class_based_handler(self):
class MyHandler(BaseHandler):
event: Update

View file

@ -4,13 +4,16 @@ from typing import Any, Awaitable, Callable, Dict, NoReturn, Union
import pytest
from aiogram.dispatcher.event.bases import SkipHandler
from aiogram.dispatcher.event.bases import REJECTED, SkipHandler
from aiogram.dispatcher.event.handler import HandlerObject
from aiogram.dispatcher.event.telegram import TelegramEventObserver
from aiogram.dispatcher.filters.base import BaseFilter
from aiogram.dispatcher.router import Router
from aiogram.types import Chat, Message, User
pytestmark = pytest.mark.asyncio
# TODO: Test middlewares in routers tree
@ -138,7 +141,6 @@ class TestTelegramEventObserver:
assert len(observer.handlers) == 1
assert observer.handlers[0].callback == my_handler
@pytest.mark.asyncio
async def test_trigger(self):
router = Router(use_builtin_filters=False)
observer = router.message
@ -178,7 +180,6 @@ class TestTelegramEventObserver:
assert registered_handler.callback == wrapped_handler
assert len(registered_handler.filters) == len(filters)
@pytest.mark.asyncio
async def test_trigger_right_context_in_handlers(self):
router = Router(use_builtin_filters=False)
observer = router.message
@ -233,3 +234,46 @@ class TestTelegramEventObserver:
assert my_middleware3 in middlewares
assert middlewares == [my_middleware1, my_middleware2, my_middleware3]
def test_register_global_filters(self):
router = Router(use_builtin_filters=False)
assert isinstance(router.message._handler.filters, list)
assert not router.message._handler.filters
my_filter = MyFilter1(test="pass")
router.message.filter(my_filter)
assert len(router.message._handler.filters) == 1
assert router.message._handler.filters[0].callback is my_filter
router.message._handler.filters = None
router.message.filter(my_filter)
assert len(router.message._handler.filters) == 1
assert router.message._handler.filters[0].callback is my_filter
async def test_global_filter(self):
r1 = Router()
r2 = Router()
async def handler(evt):
return evt
r1.message.filter(lambda evt: False)
r1.message.register(handler)
r2.message.register(handler)
assert await r1.message.trigger(None) is REJECTED
assert await r2.message.trigger(None) is None
async def test_global_filter_in_nested_router(self):
r1 = Router()
r2 = Router()
async def handler(evt):
return evt
r1.include_router(r2)
r1.message.filter(lambda evt: False)
r2.message.register(handler)
assert await r1.message.trigger(None) is REJECTED

View file

@ -10,6 +10,8 @@ except ImportError:
from unittest.mock import AsyncMock as CoroutineMock # type: ignore
from unittest.mock import patch
pytestmark = pytest.mark.asyncio
class MyFilter(BaseFilter):
foo: str
@ -19,7 +21,6 @@ class MyFilter(BaseFilter):
class TestBaseFilter:
@pytest.mark.asyncio
async def test_awaitable(self):
my_filter = MyFilter(foo="bar")

View file

@ -0,0 +1,181 @@
from decimal import Decimal
from enum import Enum, auto
from fractions import Fraction
from typing import Optional
from uuid import UUID
import pytest
from magic_filter import MagicFilter
from pydantic import ValidationError
from aiogram import F
from aiogram.dispatcher.filters.callback_data import CallbackData
from aiogram.types import CallbackQuery, User
pytestmark = pytest.mark.asyncio
class MyIntEnum(Enum):
FOO = auto()
class MyStringEnum(str, Enum):
FOO = "FOO"
class MyCallback(CallbackData, prefix="test"):
foo: str
bar: int
class TestCallbackData:
def test_init_subclass_prefix_required(self):
assert MyCallback.prefix == "test"
with pytest.raises(ValueError, match="prefix required.+"):
class MyInvalidCallback(CallbackData):
pass
def test_init_subclass_sep_validation(self):
assert MyCallback.sep == ":"
class MyCallback2(CallbackData, prefix="test2", sep="@"):
pass
assert MyCallback2.sep == "@"
with pytest.raises(ValueError, match="Separator symbol '@' .+ 'sp@m'"):
class MyInvalidCallback(CallbackData, prefix="sp@m", sep="@"):
pass
@pytest.mark.parametrize(
"value,success,expected",
[
[None, True, ""],
[42, True, "42"],
["test", True, "test"],
[9.99, True, "9.99"],
[Decimal("9.99"), True, "9.99"],
[Fraction("3/2"), True, "3/2"],
[
UUID("123e4567-e89b-12d3-a456-426655440000"),
True,
"123e4567-e89b-12d3-a456-426655440000",
],
[MyIntEnum.FOO, True, "1"],
[MyStringEnum.FOO, True, "FOO"],
[..., False, "..."],
[object, False, "..."],
[object(), False, "..."],
[User(id=42, is_bot=False, first_name="test"), False, "..."],
],
)
def test_encode_value(self, value, success, expected):
callback = MyCallback(foo="test", bar=42)
if success:
assert callback._encode_value("test", value) == expected
else:
with pytest.raises(ValueError):
assert callback._encode_value("test", value) == expected
def test_pack(self):
with pytest.raises(ValueError, match="Separator symbol .+"):
assert MyCallback(foo="te:st", bar=42).pack()
with pytest.raises(ValueError, match=".+is too long.+"):
assert MyCallback(foo="test" * 32, bar=42).pack()
assert MyCallback(foo="test", bar=42).pack() == "test:test:42"
def test_pack_optional(self):
class MyCallback1(CallbackData, prefix="test1"):
foo: str
bar: Optional[int] = None
assert MyCallback1(foo="spam").pack() == "test1:spam:"
assert MyCallback1(foo="spam", bar=42).pack() == "test1:spam:42"
class MyCallback2(CallbackData, prefix="test2"):
foo: Optional[str] = None
bar: int
assert MyCallback2(bar=42).pack() == "test2::42"
assert MyCallback2(foo="spam", bar=42).pack() == "test2:spam:42"
class MyCallback3(CallbackData, prefix="test3"):
foo: Optional[str] = "experiment"
bar: int
assert MyCallback3(bar=42).pack() == "test3:experiment:42"
assert MyCallback3(foo="spam", bar=42).pack() == "test3:spam:42"
def test_unpack(self):
with pytest.raises(TypeError, match=".+ takes 2 arguments but 3 were given"):
MyCallback.unpack("test:test:test:test")
with pytest.raises(ValueError, match="Bad prefix .+"):
MyCallback.unpack("spam:test:test")
assert MyCallback.unpack("test:test:42") == MyCallback(foo="test", bar=42)
def test_unpack_optional(self):
with pytest.raises(ValidationError):
assert MyCallback.unpack("test:test:")
class MyCallback1(CallbackData, prefix="test1"):
foo: str
bar: Optional[int] = None
assert MyCallback1.unpack("test1:spam:") == MyCallback1(foo="spam")
assert MyCallback1.unpack("test1:spam:42") == MyCallback1(foo="spam", bar=42)
class MyCallback2(CallbackData, prefix="test2"):
foo: Optional[str] = None
bar: int
assert MyCallback2.unpack("test2::42") == MyCallback2(bar=42)
assert MyCallback2.unpack("test2:spam:42") == MyCallback2(foo="spam", bar=42)
class MyCallback3(CallbackData, prefix="test3"):
foo: Optional[str] = "experiment"
bar: int
assert MyCallback3.unpack("test3:experiment:42") == MyCallback3(bar=42)
assert MyCallback3.unpack("test3:spam:42") == MyCallback3(foo="spam", bar=42)
def test_build_filter(self):
filter_object = MyCallback.filter(F.foo == "test")
assert isinstance(filter_object.rule, MagicFilter)
assert filter_object.callback_data is MyCallback
class TestCallbackDataFilter:
@pytest.mark.parametrize(
"query,rule,result",
[
["test", F.foo == "test", False],
["test:spam:42", F.foo == "test", False],
["test:test:42", F.foo == "test", {"callback_data": MyCallback(foo="test", bar=42)}],
["test:test:42", None, {"callback_data": MyCallback(foo="test", bar=42)}],
["test:test:777", None, {"callback_data": MyCallback(foo="test", bar=777)}],
["spam:test:777", None, False],
["test:test:", F.foo == "test", False],
["test:test:", None, False],
],
)
async def test_call(self, query, rule, result):
callback_query = CallbackQuery(
id="1",
from_user=User(id=42, is_bot=False, first_name="test"),
data=query,
chat_instance="test",
)
filter_object = MyCallback.filter(rule)
assert await filter_object(callback_query) == result
async def test_invalid_call(self):
filter_object = MyCallback.filter(F.test)
assert not await filter_object(User(id=42, is_bot=False, first_name="test"))

View file

@ -1,14 +1,17 @@
import datetime
import re
from typing import Match
import pytest
from aiogram import F
from aiogram.dispatcher.filters import Command, CommandObject
from aiogram.dispatcher.filters.command import CommandStart
from aiogram.methods import GetMe
from aiogram.types import Chat, Message, User
from tests.mocked_bot import MockedBot
pytestmark = pytest.mark.asyncio
class TestCommandFilter:
def test_convert_to_list(self):
@ -18,47 +21,54 @@ class TestCommandFilter:
assert cmd.commands[0] == "start"
assert cmd == Command(commands=["start"])
@pytest.mark.asyncio
async def test_parse_command(self, bot: MockedBot):
# TODO: parametrize
@pytest.mark.parametrize(
"text,command,result",
[
["/test@tbot", Command(commands=["test"], commands_prefix="/"), True],
["!test", Command(commands=["test"], commands_prefix="/"), False],
["/test@mention", Command(commands=["test"], commands_prefix="/"), False],
["/tests", Command(commands=["test"], commands_prefix="/"), False],
["/", Command(commands=["test"], commands_prefix="/"), False],
["/ test", Command(commands=["test"], commands_prefix="/"), False],
["", Command(commands=["test"], commands_prefix="/"), False],
[" ", Command(commands=["test"], commands_prefix="/"), False],
["test", Command(commands=["test"], commands_prefix="/"), False],
[" test", Command(commands=["test"], commands_prefix="/"), False],
["a", Command(commands=["test"], commands_prefix="/"), False],
["/test@tbot some args", Command(commands=["test"]), True],
["/test42@tbot some args", Command(commands=[re.compile(r"test(\d+)")]), True],
[
"/test42@tbot some args",
Command(commands=[re.compile(r"test(\d+)")], command_magic=F.args == "some args"),
True,
],
[
"/test42@tbot some args",
Command(commands=[re.compile(r"test(\d+)")], command_magic=F.args == "test"),
False,
],
["/start test", CommandStart(), True],
["/start", CommandStart(deep_link=True), False],
["/start test", CommandStart(deep_link=True), True],
["/start test", CommandStart(deep_link=True, deep_link_encoded=True), False],
["/start dGVzdA", CommandStart(deep_link=True, deep_link_encoded=True), True],
],
)
async def test_parse_command(self, bot: MockedBot, text: str, result: bool, command: Command):
# TODO: test ignore case
# TODO: test ignore mention
bot.add_result_for(
GetMe, ok=True, result=User(id=42, is_bot=True, first_name="The bot", username="tbot")
)
command = Command(commands=["test", re.compile(r"test(\d+)")], commands_prefix="/")
assert await command.parse_command("/test@tbot", bot)
assert not await command.parse_command("!test", bot)
assert not await command.parse_command("/test@mention", bot)
assert not await command.parse_command("/tests", bot)
assert not await command.parse_command("/", bot)
assert not await command.parse_command("/ test", bot)
assert not await command.parse_command("", bot)
assert not await command.parse_command(" ", bot)
assert not await command.parse_command("test", bot)
assert not await command.parse_command(" test", bot)
assert not await command.parse_command("a", bot)
message = Message(
message_id=0, text=text, chat=Chat(id=42, type="private"), date=datetime.datetime.now()
)
result = await command.parse_command("/test@tbot some args", bot)
assert isinstance(result, dict)
assert "command" in result
assert isinstance(result["command"], CommandObject)
assert result["command"].command == "test"
assert result["command"].mention == "tbot"
assert result["command"].args == "some args"
response = await command(message, bot)
assert bool(response) is result
result = await command.parse_command("/test42@tbot some args", bot)
assert isinstance(result, dict)
assert "command" in result
assert isinstance(result["command"], CommandObject)
assert result["command"].command == "test42"
assert result["command"].mention == "tbot"
assert result["command"].args == "some args"
assert isinstance(result["command"].match, Match)
@pytest.mark.asyncio
@pytest.mark.parametrize(
"message,result",
[

View file

@ -7,6 +7,8 @@ from pydantic import ValidationError
from aiogram.dispatcher.filters import ContentTypesFilter
from aiogram.types import ContentType, Message
pytestmark = pytest.mark.asyncio
@dataclass
class MinimalMessage:
@ -14,7 +16,6 @@ class MinimalMessage:
class TestContentTypesFilter:
@pytest.mark.asyncio
async def test_validator_empty(self):
filter_ = ContentTypesFilter()
assert not filter_.content_types
@ -53,7 +54,6 @@ class TestContentTypesFilter:
[[ContentType.ANY, ContentType.PHOTO, ContentType.DOCUMENT], ContentType.TEXT, True],
],
)
@pytest.mark.asyncio
async def test_call(self, values, content_type, result):
filter_ = ContentTypesFilter(content_types=values)
assert await filter_(cast(Message, MinimalMessage(content_type=content_type))) == result

View file

@ -4,16 +4,17 @@ import pytest
from aiogram.dispatcher.filters import ExceptionMessageFilter, ExceptionTypeFilter
pytestmark = pytest.mark.asyncio
class TestExceptionMessageFilter:
@pytest.mark.parametrize("value", ["value", re.compile("value")])
def test_converter(self, value):
obj = ExceptionMessageFilter(match=value)
assert isinstance(obj.match, re.Pattern)
obj = ExceptionMessageFilter(pattern=value)
assert isinstance(obj.pattern, re.Pattern)
@pytest.mark.asyncio
async def test_match(self):
obj = ExceptionMessageFilter(match="KABOOM")
obj = ExceptionMessageFilter(pattern="KABOOM")
result = await obj(Exception())
assert not result
@ -32,7 +33,6 @@ class MyAnotherException(MyException):
class TestExceptionTypeFilter:
@pytest.mark.asyncio
@pytest.mark.parametrize(
"exception,value",
[

Some files were not shown because too many files have changed in this diff Show more