Cover Command filter

This commit is contained in:
jrootjunior 2019-12-04 18:04:29 +02:00
parent 1cd993009e
commit 9d78e82f8c
7 changed files with 161 additions and 8 deletions

View file

@ -1,6 +1,8 @@
import datetime
from typing import List, Optional, Union
from async_lru import alru_cache
from ..methods import (
AddStickerToSet,
AnswerCallbackQuery,
@ -103,10 +105,9 @@ class Bot(BaseBot):
Class where located all API methods
"""
@alru_cache()
async def me(self) -> User:
if self not in self:
self[self] = await self.get_me()
return self[self]
return await self.get_me()
# =============================================================================================
# Group: Getting updates

11
poetry.lock generated
View file

@ -50,6 +50,14 @@ version = "1.1.1"
aiohttp = ">=3.1.0,<4.0.0"
pytest-asyncio = "*"
[[package]]
category = "main"
description = "Simple lru_cache for asyncio"
name = "async-lru"
optional = false
python-versions = "*"
version = "1.0.2"
[[package]]
category = "main"
description = "Timeout context manager for asyncio programs"
@ -778,7 +786,7 @@ more-itertools = "*"
fast = ["uvloop"]
[metadata]
content-hash = "17ddf5163aca6e27a1a83c6f23cfde2f807a3e97ca366fe081666503f2a7b992"
content-hash = "827efd3cbbd07f5795145b39a5f25e92619a62c48121f4fa142dafb93eaa89db"
python-versions = "^3.7"
[metadata.hashes]
@ -787,6 +795,7 @@ aiohttp = ["1e984191d1ec186881ffaed4581092ba04f7c61582a177b187d3a2f07ed9719e", "
appdirs = ["9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92", "d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"]
appnope = ["5b26757dc6f79a3b7dc9fab95359328d5747fcb2409d331ea66d0272b90ab2a0", "8b995ffe925347a2138d7ac0fe77155e4311a0ea6d6da4f5128fe4b3cbe5ed71"]
aresponses = ["d1d6ef52b9a97142d106688cf9b112602ef3dc66f6368de8f91f47241d8cfc9c", "f62bcdd739612b6254dd552467b5897a81dcf785e4bb48463bf71e40df398580"]
async-lru = ["baa898027619f5cc31b7966f96f00e4fc0df43ba206a8940a5d1af5336a477cb"]
async-timeout = ["0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", "4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3"]
asynctest = ["5da6118a7e6d6b54d83a8f7197769d046922a44d2a99c21382f0a6e4fadae676", "c27862842d15d83e6a34eb0b2866c323880eb3a75e4485b079ea11748fd77fac"]
atomicwrites = ["03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", "75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"]

View file

@ -27,6 +27,7 @@ pydantic = "^1.1"
Babel = "^2.7"
aiofiles = "^0.4.0"
uvloop = {version = "^0.14.0", optional = true}
async_lru = "^1.0"
[tool.poetry.dev-dependencies]
uvloop = "^0.14.0"

View file

@ -10,3 +10,4 @@ def bot():
token = Bot.set_current(bot)
yield bot
Bot.reset_current(token)
bot.me.invalidate(bot)

View file

@ -28,3 +28,28 @@ class TestGetMe:
assert request.method == "getMe"
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")
)
response: User = await bot.me()
request: Request = bot.get_request()
assert isinstance(response, User)
assert request.method == "getMe"
assert request.data == {}
assert response == prepare_result.result
response2: User = await bot.me()
assert response2 == response
response3: User = await bot.me()
assert response3 == response
assert response2 == response3
cache_info = bot.me.cache_info()
assert cache_info.hits == 2
assert cache_info.misses == 1

View file

@ -1,6 +1,109 @@
from aiogram.dispatcher.filters import Command
import datetime
import re
from typing import Match
import pytest
from aiogram.api.methods import GetMe
from aiogram.api.types import User, Message, Chat
from aiogram.dispatcher.filters import CommandObject, Command
from tests.mocked_bot import MockedBot
class TestCommandFilter:
def test_validator(self):
pass
@pytest.mark.asyncio
async def test_parse_command(self, bot: MockedBot):
# TODO: parametrize
# 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 not await command.parse_command("!test", bot)
assert not await command.parse_command("/test@mention", bot)
assert await command.parse_command("/test@tbot", bot)
assert not await command.parse_command("/tests", bot)
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"
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",
[
[
Message(
message_id=42,
date=datetime.datetime.now(),
chat=Chat(id=42, type="private"),
from_user=User(id=42, is_bot=False, first_name="Test"),
),
False,
],
[
Message(
message_id=42,
date=datetime.datetime.now(),
text="/test",
chat=Chat(id=42, type="private"),
from_user=User(id=42, is_bot=False, first_name="Test"),
),
True,
],
],
)
async def test_call(self, message: Message, result: bool, bot: MockedBot):
command = Command(commands=["test"])
assert bool(await command(message=message, bot=bot)) is result
class TestCommandObject:
@pytest.mark.parametrize(
"obj,result",
[
[CommandObject(prefix="/", command="command", mention="mention", args="args"), True],
[CommandObject(prefix="/", command="command", args="args"), False],
],
)
def test_mentioned(self, obj: CommandObject, result: bool):
assert isinstance(obj.mentioned, bool)
assert obj.mentioned is result
@pytest.mark.parametrize(
"obj,result",
[
[
CommandObject(prefix="/", command="command", mention="mention", args="args"),
"/command@mention args",
],
[
CommandObject(prefix="/", command="command", mention="mention", args=None),
"/command@mention",
],
[
CommandObject(prefix="/", command="command", mention=None, args="args"),
"/command args",
],
[CommandObject(prefix="/", command="command", mention=None, args=None), "/command"],
[CommandObject(prefix="!", command="command", mention=None, args=None), "!command"],
],
)
def test_text(self, obj: CommandObject, result: str):
assert obj.text == result

View file

@ -40,7 +40,7 @@ class TestBaseMessageHandlerCommandMixin:
Message(
message_id=42,
date=datetime.datetime.now(),
text="test",
text="/test args",
chat=Chat(id=42, type="private"),
from_user=User(id=42, is_bot=False, first_name="Test"),
),
@ -49,3 +49,16 @@ class TestBaseMessageHandlerCommandMixin:
assert isinstance(handler.command, CommandObject)
assert handler.command.command == "command"
def test_command_not_presented(self):
handler = HandlerWithCommand(
Message(
message_id=42,
date=datetime.datetime.now(),
text="test",
chat=Chat(id=42, type="private"),
from_user=User(id=42, is_bot=False, first_name="Test"),
)
)
assert handler.command is None