mirror of
https://github.com/aiogram/aiogram.git
synced 2025-12-10 17:53:17 +00:00
Rework polling and start covering
This commit is contained in:
parent
38c725db46
commit
db397e3a05
6 changed files with 84 additions and 12 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from contextlib import asynccontextmanager
|
||||||
from typing import Any, Optional, TypeVar
|
from typing import Any, Optional, TypeVar
|
||||||
|
|
||||||
from ...utils.mixins import ContextInstanceMixin, DataMixin
|
from ...utils.mixins import ContextInstanceMixin, DataMixin
|
||||||
|
|
@ -32,11 +33,15 @@ class BaseBot(ContextInstanceMixin, DataMixin):
|
||||||
async def close(self):
|
async def close(self):
|
||||||
await self.session.close()
|
await self.session.close()
|
||||||
|
|
||||||
async def __aenter__(self):
|
@asynccontextmanager
|
||||||
return self
|
async def context(self, auto_close: bool = True):
|
||||||
|
token = self.set_current(self)
|
||||||
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
try:
|
||||||
await self.session.close()
|
yield self
|
||||||
|
finally:
|
||||||
|
if auto_close:
|
||||||
|
await self.close()
|
||||||
|
self.reset_current(token)
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash(self.__token)
|
return hash(self.__token)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ import datetime
|
||||||
import json
|
import json
|
||||||
from typing import Any, Callable, Optional, TypeVar, Union
|
from typing import Any, Callable, Optional, TypeVar, Union
|
||||||
|
|
||||||
|
from aiogram.utils.exceptions import TelegramAPIError
|
||||||
|
|
||||||
from ...methods import Response, TelegramMethod
|
from ...methods import Response, TelegramMethod
|
||||||
from ..telegram import PRODUCTION, TelegramAPIServer
|
from ..telegram import PRODUCTION, TelegramAPIServer
|
||||||
|
|
||||||
|
|
@ -32,7 +34,7 @@ class BaseSession(abc.ABC):
|
||||||
def raise_for_status(self, response: Response[T]) -> None:
|
def raise_for_status(self, response: Response[T]) -> None:
|
||||||
if response.ok:
|
if response.ok:
|
||||||
return
|
return
|
||||||
raise Exception(response.description)
|
raise TelegramAPIError(response.description)
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
async def close(self): # pragma: no cover
|
async def close(self): # pragma: no cover
|
||||||
|
|
|
||||||
|
|
@ -24,3 +24,9 @@ class User(TelegramObject):
|
||||||
"""User‘s or bot’s username"""
|
"""User‘s or bot’s username"""
|
||||||
language_code: Optional[str] = None
|
language_code: Optional[str] = None
|
||||||
"""IETF language tag of the user's language"""
|
"""IETF language tag of the user's language"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def full_name(self):
|
||||||
|
if self.last_name:
|
||||||
|
return f"{self.first_name} {self.last_name}"
|
||||||
|
return self.first_name
|
||||||
|
|
|
||||||
|
|
@ -48,10 +48,16 @@ class TestBaseBot:
|
||||||
mocked_close.assert_awaited()
|
mocked_close.assert_awaited()
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_context_manager(self):
|
@pytest.mark.parametrize("close", [True, False])
|
||||||
|
async def test_context_manager(self, close: bool):
|
||||||
with patch(
|
with patch(
|
||||||
"aiogram.api.client.session.aiohttp.AiohttpSession.close", new_callable=CoroutineMock
|
"aiogram.api.client.session.aiohttp.AiohttpSession.close", new_callable=CoroutineMock
|
||||||
) as mocked_close:
|
) as mocked_close:
|
||||||
async with BaseBot("42:TEST", session=AiohttpSession()) as bot:
|
async with BaseBot("42:TEST", session=AiohttpSession()).context(
|
||||||
|
auto_close=close
|
||||||
|
) as bot:
|
||||||
assert isinstance(bot, BaseBot)
|
assert isinstance(bot, BaseBot)
|
||||||
mocked_close.assert_awaited()
|
if close:
|
||||||
|
mocked_close.assert_awaited()
|
||||||
|
else:
|
||||||
|
mocked_close.assert_not_awaited()
|
||||||
|
|
|
||||||
20
tests/test_api/test_types/test_user.py
Normal file
20
tests/test_api/test_types/test_user.py
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from aiogram.api.types import User
|
||||||
|
|
||||||
|
|
||||||
|
class TestUser:
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"first,last,result",
|
||||||
|
[
|
||||||
|
["User", None, "User"],
|
||||||
|
["", None, ""],
|
||||||
|
[" ", None, " "],
|
||||||
|
["User", "Name", "User Name"],
|
||||||
|
["User", " ", "User "],
|
||||||
|
[" ", " ", " "],
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_full_name(self, first: str, last: str, result: bool):
|
||||||
|
user = User(id=42, is_bot=False, first_name=first, last_name=last)
|
||||||
|
assert user.full_name == result
|
||||||
|
|
@ -4,9 +4,11 @@ import time
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from aiogram import Bot
|
from aiogram import Bot
|
||||||
|
from aiogram.api.methods import GetUpdates, SendMessage
|
||||||
from aiogram.api.types import Chat, Message, Update, User
|
from aiogram.api.types import Chat, Message, Update, User
|
||||||
from aiogram.dispatcher.dispatcher import Dispatcher
|
from aiogram.dispatcher.dispatcher import Dispatcher
|
||||||
from aiogram.dispatcher.router import Router
|
from aiogram.dispatcher.router import Router
|
||||||
|
from tests.mocked_bot import MockedBot
|
||||||
|
|
||||||
|
|
||||||
class TestDispatcher:
|
class TestDispatcher:
|
||||||
|
|
@ -77,12 +79,43 @@ class TestDispatcher:
|
||||||
assert result == "test"
|
assert result == "test"
|
||||||
assert handled
|
assert handled
|
||||||
|
|
||||||
@pytest.mark.skip
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_listen_updates(self):
|
async def test_listen_updates(self, bot: MockedBot):
|
||||||
pass
|
dispatcher = Dispatcher()
|
||||||
|
bot.add_result_for(
|
||||||
|
GetUpdates, ok=True, result=[Update(update_id=update_id) for update_id in range(42)]
|
||||||
|
)
|
||||||
|
index = 0
|
||||||
|
async for update in dispatcher._listen_updates(bot=bot):
|
||||||
|
assert update.update_id == index
|
||||||
|
index += 1
|
||||||
|
if index == 42:
|
||||||
|
break
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_silent_call_request(self, bot: MockedBot, caplog):
|
||||||
|
dispatcher = Dispatcher()
|
||||||
|
bot.add_result_for(SendMessage, ok=False, error_code=400, description="Kaboom")
|
||||||
|
await dispatcher._silent_call_request(SendMessage(chat_id=42, text="test"))
|
||||||
|
log_records = [rec.message for rec in caplog.records]
|
||||||
|
assert len(log_records) == 1
|
||||||
|
assert "Failed to make answer" in log_records[0]
|
||||||
|
|
||||||
@pytest.mark.skip
|
@pytest.mark.skip
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_polling(self):
|
async def test_polling(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@pytest.mark.skip
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_process_update(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@pytest.mark.skip
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_run_polling(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@pytest.mark.skip
|
||||||
|
def test_run(self):
|
||||||
|
pass
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue