Add token validation util, fix deepcopy of sessions and make bot hashable and comparable

This commit is contained in:
Alex Root Junior 2019-11-28 23:12:44 +02:00
parent 9adc2f91bd
commit c674b5547b
11 changed files with 223 additions and 41 deletions

View file

@ -3,9 +3,9 @@ from aiogram.api.client.telegram import PRODUCTION
class TestAPIServer:
def test_method_url(self):
method_url = PRODUCTION.api_url(token="TOKEN", method="apiMethod")
assert method_url == "https://api.telegram.org/botTOKEN/apiMethod"
method_url = PRODUCTION.api_url(token="42:TEST", method="apiMethod")
assert method_url == "https://api.telegram.org/bot42:TEST/apiMethod"
def test_file_url(self):
file_url = PRODUCTION.file_url(token="TOKEN", path="path")
assert file_url == "https://api.telegram.org/file/botTOKEN/path"
file_url = PRODUCTION.file_url(token="42:TEST", path="path")
assert file_url == "https://api.telegram.org/file/bot42:TEST/path"

View file

@ -1,3 +1,5 @@
import copy
import pytest
from asynctest import CoroutineMock, patch
@ -9,12 +11,21 @@ from aiogram.api.methods import GetMe
class TestBaseBot:
def test_init(self):
base_bot = BaseBot("TOKEN")
base_bot = BaseBot("42:TEST")
assert isinstance(base_bot.session, AiohttpSession)
assert base_bot.id == 42
def test_hashable(self):
base_bot = BaseBot("42:TEST")
assert hash(base_bot) == hash("42:TEST")
def test_equals(self):
base_bot = BaseBot("42:TEST")
assert base_bot == BaseBot("42:TEST")
@pytest.mark.asyncio
async def test_emit(self):
base_bot = BaseBot("TOKEN")
base_bot = BaseBot("42:TEST")
method = GetMe()
@ -23,11 +34,11 @@ class TestBaseBot:
new_callable=CoroutineMock,
) as mocked_make_request:
await base_bot.emit(method)
mocked_make_request.assert_awaited_with("TOKEN", method)
mocked_make_request.assert_awaited_with("42:TEST", method)
@pytest.mark.asyncio
async def test_close(self):
base_bot = BaseBot("TOKEN", session=AiohttpSession())
base_bot = BaseBot("42:TEST", session=AiohttpSession())
await base_bot.session.create_session()
with patch(
@ -41,6 +52,6 @@ class TestBaseBot:
with patch(
"aiogram.api.client.session.aiohttp.AiohttpSession.close", new_callable=CoroutineMock
) as mocked_close:
async with BaseBot("TOKEN", session=AiohttpSession()) as bot:
async with BaseBot("42:TEST", session=AiohttpSession()) as bot:
assert isinstance(bot, BaseBot)
mocked_close.assert_awaited()

View file

@ -1,3 +1,6 @@
import copy
from typing import AsyncContextManager
import aiohttp
import pytest
from aresponses import ResponsesMockServer
@ -74,7 +77,7 @@ class TestAiohttpSession:
async def test_make_request(self, aresponses: ResponsesMockServer):
aresponses.add(
aresponses.ANY,
"/botTOKEN/method",
"/bot42:TEST/method",
"post",
aresponses.Response(
status=200,
@ -95,8 +98,32 @@ class TestAiohttpSession:
with patch(
"aiogram.api.client.session.base.BaseSession.raise_for_status"
) as patched_raise_for_status:
result = await session.make_request("TOKEN", call)
result = await session.make_request("42:TEST", call)
assert isinstance(result, int)
assert result == 42
assert patched_raise_for_status.called_once()
@pytest.mark.asyncio
async def test_context_manager(self):
session = AiohttpSession()
assert isinstance(session, AsyncContextManager)
with patch(
"aiogram.api.client.session.aiohttp.AiohttpSession.create_session",
new_callable=CoroutineMock,
) as mocked_create_session, patch(
"aiogram.api.client.session.aiohttp.AiohttpSession.close", new_callable=CoroutineMock
) as mocked_close:
async with session as ctx:
assert session == ctx
mocked_close.awaited_once()
mocked_create_session.awaited_once()
@pytest.mark.asyncio
async def test_deepcopy(self):
# Session should be copied without aiohttp.ClientSession
async with AiohttpSession() as session:
cloned_session = copy.deepcopy(session)
assert cloned_session != session
assert cloned_session._session is None

View file

@ -1,23 +1,27 @@
import datetime
from typing import AsyncContextManager
import pytest
from asynctest import CoroutineMock, patch
from aiogram.api.client.session.base import BaseSession
from aiogram.api.client.session.base import BaseSession, T
from aiogram.api.client.telegram import PRODUCTION, TelegramAPIServer
from aiogram.api.methods import GetMe, Response
from aiogram.api.methods import GetMe, Response, TelegramMethod
from aiogram.utils.mixins import DataMixin
class CustomSession(BaseSession):
async def close(self):
pass
async def make_request(self, token: str, method: TelegramMethod[T]) -> None: # type: ignore
assert isinstance(token, str)
assert isinstance(method, TelegramMethod)
class TestBaseSession(DataMixin):
def setup(self):
self["__abstractmethods__"] = BaseSession.__abstractmethods__
BaseSession.__abstractmethods__ = set()
def teardown(self):
BaseSession.__abstractmethods__ = self["__abstractmethods__"]
def test_init_api(self):
session = BaseSession()
session = CustomSession()
assert session.api == PRODUCTION
def test_init_custom_api(self):
@ -25,11 +29,11 @@ class TestBaseSession(DataMixin):
base="http://example.com/{token}/{method}",
file="http://example.com/{token}/file/{path{",
)
session = BaseSession(api=api)
session = CustomSession(api=api)
assert session.api == api
def test_prepare_value(self):
session = BaseSession()
session = CustomSession()
now = datetime.datetime.now()
@ -41,7 +45,7 @@ class TestBaseSession(DataMixin):
assert session.prepare_value(42) == "42"
def test_clean_json(self):
session = BaseSession()
session = CustomSession()
cleaned_dict = session.clean_json({"key": "value", "null": None})
assert "key" in cleaned_dict
@ -54,7 +58,7 @@ class TestBaseSession(DataMixin):
assert cleaned_list[0] == "kaboom"
def test_clean_json_with_nested_json(self):
session = BaseSession()
session = CustomSession()
cleaned = session.clean_json(
{
@ -75,12 +79,12 @@ class TestBaseSession(DataMixin):
assert cleaned["nested_dict"] == {"key": "value"}
def test_clean_json_not_json(self):
session = BaseSession()
session = CustomSession()
assert session.clean_json(42) == 42
def test_raise_for_status(self):
session = BaseSession()
session = CustomSession()
session.raise_for_status(Response[bool](ok=True, result=True))
with pytest.raises(Exception):
@ -88,6 +92,19 @@ class TestBaseSession(DataMixin):
@pytest.mark.asyncio
async def test_make_request(self):
session = BaseSession()
session = CustomSession()
assert await session.make_request("TOKEN", GetMe()) is None
assert await session.make_request("42:TEST", GetMe()) is None
@pytest.mark.asyncio
async def test_context_manager(self):
session = CustomSession()
assert isinstance(session, AsyncContextManager)
with patch(
"tests.test_api.test_client.test_session.test_base_session.CustomSession.close",
new_callable=CoroutineMock,
) as mocked_close:
async with session as ctx:
assert session == ctx
mocked_close.awaited_once()