from unittest.mock import AsyncMock, MagicMock, patch import pytest from aiogram.exceptions import CallbackAnswerException from aiogram.methods import AnswerCallbackQuery from aiogram.types import CallbackQuery, User from aiogram.utils.callback_answer import CallbackAnswer, CallbackAnswerMiddleware class TestCallbackAnswer: @pytest.mark.parametrize( "name,value", [ ["answered", True], ["answered", False], ["disabled", True], ["disabled", False], ["text", "test"], ["text", None], ["show_alert", True], ["show_alert", False], ["show_alert", None], ["url", "https://example.com"], ["url", None], ["cache_time", None], ["cache_time", 10], ], ) def test_getters(self, name, value): kwargs = { "answered": False, name: value, } instance = CallbackAnswer(**kwargs) result = getattr(instance, name) assert result == value @pytest.mark.parametrize( "name,value", [ ["disabled", True], ["disabled", False], ["text", None], ["text", ""], ["text", "test"], ["show_alert", None], ["show_alert", True], ["show_alert", False], ["url", None], ["url", "https://example.com"], ["cache_time", None], ["cache_time", 0], ["cache_time", 10], ], ) def test_setter_allowed(self, name, value): instance = CallbackAnswer(answered=False) setattr(instance, name, value) assert getattr(instance, name) == value @pytest.mark.parametrize( "name", [ "disabled", "text", "show_alert", "url", "cache_time", ], ) def test_setter_blocked(self, name): instance = CallbackAnswer(answered=True) with pytest.raises(CallbackAnswerException): setattr(instance, name, "test") def test_disable(self): instance = CallbackAnswer(answered=False) assert not instance.disabled instance.disable() assert instance.disabled def test_str(self): instance = CallbackAnswer(answered=False, text="test") assert str(instance) == "CallbackAnswer(answered=False, disabled=False, text='test')" class TestCallbackAnswerMiddleware: @pytest.mark.parametrize( "init_kwargs,flag_properties,expected", [ [ {}, True, { "answered": False, "disabled": False, "text": None, "show_alert": None, "url": None, "cache_time": None, }, ], [ { "pre": True, "text": "test", "show_alert": True, "url": "https://example.com", "cache_time": 5, }, True, { "answered": True, "disabled": False, "text": "test", "show_alert": True, "url": "https://example.com", "cache_time": 5, }, ], [ { "pre": False, "text": "test", "show_alert": True, "url": "https://example.com", "cache_time": 5, }, { "pre": True, "disabled": True, "text": "another test", "show_alert": False, "url": "https://example.com/game.html", "cache_time": 10, }, { "answered": True, "disabled": True, "text": "another test", "show_alert": False, "url": "https://example.com/game.html", "cache_time": 10, }, ], ], ) def test_construct_answer(self, init_kwargs, flag_properties, expected): middleware = CallbackAnswerMiddleware(**init_kwargs) callback_answer = middleware.construct_callback_answer(properties=flag_properties) for key, value in expected.items(): assert getattr(callback_answer, key) == value def test_answer(self): middleware = CallbackAnswerMiddleware() event = CallbackQuery( id="1", from_user=User(id=42, first_name="Test", is_bot=False), chat_instance="test", ) callback_answer = CallbackAnswer( answered=False, disabled=False, text="another test", show_alert=False, url="https://example.com/game.html", cache_time=10, ) method = middleware.answer(event=event, callback_answer=callback_answer) assert isinstance(method, AnswerCallbackQuery) assert method.text == callback_answer.text assert method.show_alert == callback_answer.show_alert assert method.url == callback_answer.url assert method.cache_time == callback_answer.cache_time @pytest.mark.parametrize( "properties,expected_stack", [ [{"answered": False}, ["handler", "answer"]], [{"answered": True}, ["answer", "handler"]], [{"disabled": True}, ["handler"]], ], ) async def test_call(self, properties, expected_stack): stack = [] event = CallbackQuery( id="1", from_user=User(id=42, first_name="Test", is_bot=False), chat_instance="test", ) async def handler(*args, **kwargs): stack.append("handler") async def answer(*args, **kwargs): stack.append("answer") middleware = CallbackAnswerMiddleware() with patch( "aiogram.utils.callback_answer.CallbackAnswerMiddleware.construct_callback_answer", new_callable=MagicMock, side_effect=lambda **kwargs: CallbackAnswer(**{"answered": False, **properties}), ), patch( "aiogram.utils.callback_answer.CallbackAnswerMiddleware.answer", new=answer, ): await middleware(handler, event, {}) assert stack == expected_stack async def test_invalid_event_type(self): middleware = CallbackAnswerMiddleware() handler = AsyncMock() await middleware(handler, None, {}) handler.assert_awaited()