From 5734a6f0747cc4df92aefc3c5442d3f33500acca Mon Sep 17 00:00:00 2001 From: KuroAngel <145038102+KuroKoka551@users.noreply.github.com> Date: Fri, 24 May 2024 01:49:07 +0500 Subject: [PATCH 1/5] fixed double cast Radio, added reset method --- src/aiogram_dialog/widgets/kbd/select.py | 25 +++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/aiogram_dialog/widgets/kbd/select.py b/src/aiogram_dialog/widgets/kbd/select.py index 18d919dd..cb53b019 100644 --- a/src/aiogram_dialog/widgets/kbd/select.py +++ b/src/aiogram_dialog/widgets/kbd/select.py @@ -182,7 +182,7 @@ async def _process_click( await self.on_item_click.process_event( callback, select, manager, self.type_factory(item_id), ) - await self._on_click(callback, select, manager, str(item_id)) + await self._on_click(callback, select, manager, item_id) @abstractmethod async def _on_click( @@ -194,6 +194,21 @@ async def _on_click( ): raise NotImplementedError + async def _process_item_callback( + self, + callback: CallbackQuery, + data: str, + dialog: DialogProtocol, + manager: DialogManager, + ) -> bool: + await self.on_click.process_event( + callback, + self.managed(manager), + manager, + data, + ) + return True + class Radio(StatefulSelect[T], Generic[T]): def __init__( @@ -237,9 +252,9 @@ def _get_checked(self, manager: DialogManager) -> Optional[str]: return self.get_widget_data(manager, None) async def set_checked( - self, event: ChatEvent, item_id: Optional[T], + self, event: ChatEvent, item_id: T, manager: DialogManager, - ): + ) -> None: checked = self._get_checked(manager) item_id_str = str(item_id) self.set_widget_data(manager, item_id_str) @@ -282,6 +297,10 @@ def get_checked(self) -> Optional[T]: """Get an id of selected item.""" return self.widget.get_checked(self.manager) + def reset_checked(self) -> None: + """Reset which item is selected.""" + return self.widget.set_widget_data(self.manager, None) + async def set_checked(self, item_id: T): """Get set which item is selected.""" return await self.widget.set_checked( From 4c822ef1f87f57b00c93cec9701a3464c2641f70 Mon Sep 17 00:00:00 2001 From: KuroAngel <145038102+KuroKoka551@users.noreply.github.com> Date: Fri, 24 May 2024 16:32:57 +0500 Subject: [PATCH 2/5] changed reset, added check optional --- src/aiogram_dialog/widgets/kbd/select.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/aiogram_dialog/widgets/kbd/select.py b/src/aiogram_dialog/widgets/kbd/select.py index cb53b019..c7743d76 100644 --- a/src/aiogram_dialog/widgets/kbd/select.py +++ b/src/aiogram_dialog/widgets/kbd/select.py @@ -38,7 +38,7 @@ async def __call__( event: ChatEvent, select: ManagedT, # noqa: F841 dialog_manager: DialogManager, - data: T, + data: Optional[T], /, ): raise NotImplementedError @@ -252,11 +252,14 @@ def _get_checked(self, manager: DialogManager) -> Optional[str]: return self.get_widget_data(manager, None) async def set_checked( - self, event: ChatEvent, item_id: T, + self, event: ChatEvent, item_id: Optional[T], manager: DialogManager, ) -> None: checked = self._get_checked(manager) - item_id_str = str(item_id) + if item_id is None: + item_id_str = None + else: + item_id_str = str(item_id) self.set_widget_data(manager, item_id_str) if checked != item_id_str: await self._process_on_state_changed(event, item_id_str, manager) @@ -297,11 +300,7 @@ def get_checked(self) -> Optional[T]: """Get an id of selected item.""" return self.widget.get_checked(self.manager) - def reset_checked(self) -> None: - """Reset which item is selected.""" - return self.widget.set_widget_data(self.manager, None) - - async def set_checked(self, item_id: T): + async def set_checked(self, item_id: Optional[T]) -> None: """Get set which item is selected.""" return await self.widget.set_checked( self.manager.event, item_id, self.manager, From 14dfa8fceb10b1ee91c3ad5e14991335e4f2e604 Mon Sep 17 00:00:00 2001 From: KuroAngel <145038102+KuroKoka551@users.noreply.github.com> Date: Sun, 26 May 2024 15:17:44 +0500 Subject: [PATCH 3/5] radio validation test, fix errors --- src/aiogram_dialog/widgets/kbd/select.py | 11 ++++----- tests/widgets/kbd/test_radio.py | 29 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/aiogram_dialog/widgets/kbd/select.py b/src/aiogram_dialog/widgets/kbd/select.py index c7743d76..b3959760 100644 --- a/src/aiogram_dialog/widgets/kbd/select.py +++ b/src/aiogram_dialog/widgets/kbd/select.py @@ -38,7 +38,7 @@ async def __call__( event: ChatEvent, select: ManagedT, # noqa: F841 dialog_manager: DialogManager, - data: Optional[T], + data: T, /, ): raise NotImplementedError @@ -252,14 +252,11 @@ def _get_checked(self, manager: DialogManager) -> Optional[str]: return self.get_widget_data(manager, None) async def set_checked( - self, event: ChatEvent, item_id: Optional[T], + self, event: ChatEvent, item_id: T, manager: DialogManager, ) -> None: checked = self._get_checked(manager) - if item_id is None: - item_id_str = None - else: - item_id_str = str(item_id) + item_id_str = str(item_id) self.set_widget_data(manager, item_id_str) if checked != item_id_str: await self._process_on_state_changed(event, item_id_str, manager) @@ -300,7 +297,7 @@ def get_checked(self) -> Optional[T]: """Get an id of selected item.""" return self.widget.get_checked(self.manager) - async def set_checked(self, item_id: Optional[T]) -> None: + async def set_checked(self, item_id: T) -> None: """Get set which item is selected.""" return await self.widget.set_checked( self.manager.event, item_id, self.manager, diff --git a/tests/widgets/kbd/test_radio.py b/tests/widgets/kbd/test_radio.py index d52fc0eb..2f7a8a66 100644 --- a/tests/widgets/kbd/test_radio.py +++ b/tests/widgets/kbd/test_radio.py @@ -1,4 +1,5 @@ import operator +from datetime import datetime from unittest.mock import AsyncMock import pytest @@ -26,6 +27,34 @@ async def test_check_radio(mock_manager) -> None: assert radio.is_checked("2", mock_manager) +@pytest.mark.asyncio +async def test_validation_radio(mock_manager) -> None: + def validate_datetime(text: str) -> datetime: + return datetime.fromtimestamp(int(text)) + + radio = Radio( + Format("🔘 {item[1]}"), + Format("⚪️ {item[1]}"), + id="datetime", + item_id_getter=operator.itemgetter(0), + type_factory=validate_datetime, + items=[ + (int(datetime(2024, 5, 26).timestamp()), datetime(2024, 5, 26)), + (int(datetime(2024, 5, 30).timestamp()), datetime(2024, 5, 30)), + (int(datetime(2022, 3, 11).timestamp()), datetime(2022, 3, 11)), + ], + ) + + current_checked_date = radio.get_checked(mock_manager) + assert current_checked_date is None + + await radio.set_checked( + TelegramObject(), int(datetime(2024, 5, 30).timestamp()), mock_manager + ) + + assert radio.is_checked(int(datetime(2024, 5, 30).timestamp()), mock_manager) + + @pytest.mark.asyncio async def test_on_state_changed_radio(mock_manager) -> None: on_state_changed = AsyncMock() From 196fda41c55a64d808d1a85c594ade0155e69b0d Mon Sep 17 00:00:00 2001 From: KuroAngel <145038102+KuroKoka551@users.noreply.github.com> Date: Sun, 26 May 2024 15:21:25 +0500 Subject: [PATCH 4/5] fixed flake --- tests/widgets/kbd/test_radio.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/widgets/kbd/test_radio.py b/tests/widgets/kbd/test_radio.py index 2f7a8a66..39bfd744 100644 --- a/tests/widgets/kbd/test_radio.py +++ b/tests/widgets/kbd/test_radio.py @@ -49,10 +49,12 @@ def validate_datetime(text: str) -> datetime: assert current_checked_date is None await radio.set_checked( - TelegramObject(), int(datetime(2024, 5, 30).timestamp()), mock_manager + TelegramObject(), int(datetime(2024, 5, 30).timestamp()), + mock_manager ) - assert radio.is_checked(int(datetime(2024, 5, 30).timestamp()), mock_manager) + assert radio.is_checked(int(datetime(2024, 5, 30).timestamp()), + mock_manager) @pytest.mark.asyncio From 5a7a381df46c97a2cbafd5856e41cd93e3f21753 Mon Sep 17 00:00:00 2001 From: KuroAngel <145038102+KuroKoka551@users.noreply.github.com> Date: Sun, 26 May 2024 15:24:56 +0500 Subject: [PATCH 5/5] improved test --- tests/widgets/kbd/test_radio.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/widgets/kbd/test_radio.py b/tests/widgets/kbd/test_radio.py index 39bfd744..3753a65c 100644 --- a/tests/widgets/kbd/test_radio.py +++ b/tests/widgets/kbd/test_radio.py @@ -56,6 +56,9 @@ def validate_datetime(text: str) -> datetime: assert radio.is_checked(int(datetime(2024, 5, 30).timestamp()), mock_manager) + current_checked_date = radio.get_checked(mock_manager) + assert current_checked_date == datetime(2024, 5, 30) + @pytest.mark.asyncio async def test_on_state_changed_radio(mock_manager) -> None: