mirror of
https://github.com/aiogram/aiogram.git
synced 2025-12-12 10:11:52 +00:00
PoC: Bot instance inside method shortcuts using pydantic Validation Context (#1210)
* PoC: Mount objects to the Bot instance, bind shortcuts to configured instance * Fixe docstring of the bind method * Pass Bot instance explicitly to the URLInputFile * Added tests * Added changelog * Refactor aiogram client and update tests Refactored base.py to improve code readability by separating response_type operation from model_validate(). Also, adjusted the parameters in URLInputFile() within test_input_file.py for better test coverage. Updated input_file.py to streamline read method and avoid unnecessary instantiation of Bot class. Lastly, adjusted typing in methods/base.py to enhance code clarity. * Update changelog
This commit is contained in:
parent
c39a803747
commit
a7b92bb050
19 changed files with 228 additions and 111 deletions
|
|
@ -35,7 +35,7 @@ class MockedSession(BaseSession):
|
|||
self.requests.append(method)
|
||||
response: Response[TelegramType] = self.responses.pop()
|
||||
self.check_response(
|
||||
method=method, status_code=response.error_code, content=response.json()
|
||||
bot=bot, method=method, status_code=response.error_code, content=response.json()
|
||||
)
|
||||
return response.result # type: ignore
|
||||
|
||||
|
|
|
|||
36
tests/test_api/test_client/test_context_controller.py
Normal file
36
tests/test_api/test_client/test_context_controller.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
from aiogram.client.context_controller import BotContextController
|
||||
from tests.mocked_bot import MockedBot
|
||||
|
||||
|
||||
class MyModel(BotContextController):
|
||||
id: int
|
||||
|
||||
|
||||
class TestBotContextController:
|
||||
def test_via_model_validate(self, bot: MockedBot):
|
||||
my_model = MyModel.model_validate({"id": 1}, context={"bot": bot})
|
||||
assert my_model.id == 1
|
||||
assert my_model._bot == bot
|
||||
|
||||
def test_via_model_validate_none(self):
|
||||
my_model = MyModel.model_validate({"id": 1}, context={})
|
||||
assert my_model.id == 1
|
||||
assert my_model._bot is None
|
||||
|
||||
def test_as(self, bot: MockedBot):
|
||||
my_model = MyModel(id=1).as_(bot)
|
||||
assert my_model.id == 1
|
||||
assert my_model._bot == bot
|
||||
|
||||
def test_as_none(self):
|
||||
my_model = MyModel(id=1).as_(None)
|
||||
assert my_model.id == 1
|
||||
assert my_model._bot is None
|
||||
|
||||
def test_replacement(self, bot: MockedBot):
|
||||
my_model = MyModel(id=1).as_(bot)
|
||||
assert my_model.id == 1
|
||||
assert my_model._bot == bot
|
||||
my_model = my_model.as_(None)
|
||||
assert my_model.id == 1
|
||||
assert my_model._bot is None
|
||||
|
|
@ -170,9 +170,11 @@ class TestBaseSession:
|
|||
)
|
||||
def test_check_response(self, status_code, content, error):
|
||||
session = CustomSession()
|
||||
bot = MockedBot()
|
||||
method = DeleteMessage(chat_id=42, message_id=42)
|
||||
if error is None:
|
||||
session.check_response(
|
||||
bot=bot,
|
||||
method=method,
|
||||
status_code=status_code,
|
||||
content=content,
|
||||
|
|
@ -180,6 +182,7 @@ class TestBaseSession:
|
|||
else:
|
||||
with pytest.raises(error) as exc_info:
|
||||
session.check_response(
|
||||
bot=bot,
|
||||
method=method,
|
||||
status_code=status_code,
|
||||
content=content,
|
||||
|
|
@ -191,10 +194,12 @@ class TestBaseSession:
|
|||
|
||||
def test_check_response_json_decode_error(self):
|
||||
session = CustomSession()
|
||||
bot = MockedBot()
|
||||
method = DeleteMessage(chat_id=42, message_id=42)
|
||||
|
||||
with pytest.raises(ClientDecodeError, match="JSONDecodeError"):
|
||||
session.check_response(
|
||||
bot=bot,
|
||||
method=method,
|
||||
status_code=200,
|
||||
content="is not a JSON object",
|
||||
|
|
@ -202,10 +207,12 @@ class TestBaseSession:
|
|||
|
||||
def test_check_response_validation_error(self):
|
||||
session = CustomSession()
|
||||
bot = MockedBot()
|
||||
method = DeleteMessage(chat_id=42, message_id=42)
|
||||
|
||||
with pytest.raises(ClientDecodeError, match="ValidationError"):
|
||||
session.check_response(
|
||||
bot=bot,
|
||||
method=method,
|
||||
status_code=200,
|
||||
content='{"ok": "test"}',
|
||||
|
|
|
|||
|
|
@ -22,6 +22,14 @@ class TestTelegramMethodRemoveUnset:
|
|||
|
||||
|
||||
class TestTelegramMethodCall:
|
||||
async def test_async_emit_unsuccessful(self, bot: MockedBot):
|
||||
with pytest.raises(
|
||||
RuntimeError,
|
||||
match="This method is not mounted to a any bot instance.+",
|
||||
):
|
||||
await GetMe()
|
||||
|
||||
async def test_async_emit(self, bot: MockedBot):
|
||||
bot.add_result_for(GetMe, ok=True, result=User(id=42, is_bot=True, first_name="Test"))
|
||||
assert isinstance(await GetMe(), User)
|
||||
method = GetMe().as_(bot)
|
||||
assert isinstance(await method, User)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from aresponses import ResponsesMockServer
|
|||
|
||||
from aiogram import Bot
|
||||
from aiogram.types import BufferedInputFile, FSInputFile, InputFile, URLInputFile
|
||||
from tests.mocked_bot import MockedBot
|
||||
|
||||
|
||||
class TestInputFile:
|
||||
|
|
@ -72,10 +73,8 @@ class TestInputFile:
|
|||
aresponses.add(
|
||||
aresponses.ANY, aresponses.ANY, "get", aresponses.Response(status=200, body=b"\f" * 10)
|
||||
)
|
||||
|
||||
Bot.set_current(Bot("42:TEST"))
|
||||
|
||||
file = URLInputFile("https://test.org/", chunk_size=1)
|
||||
bot = Bot(token="42:TEST")
|
||||
file = URLInputFile("https://test.org/", bot, chunk_size=1)
|
||||
|
||||
size = 0
|
||||
async for chunk in file:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue