mirror of
https://github.com/aiogram/aiogram.git
synced 2025-12-09 01:15:31 +00:00
Add token validation util, fix deepcopy of sessions and make bot hashable and comparable
This commit is contained in:
parent
9adc2f91bd
commit
c674b5547b
11 changed files with 223 additions and 41 deletions
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue