Skip to content

Commit

Permalink
Merge pull request #160 from IvanKirpichnikov/aiogram-dialog-integran…
Browse files Browse the repository at this point in the history
…tion

Aiogram dialog integrantion
  • Loading branch information
Tishka17 authored May 29, 2024
2 parents 47af5a7 + 0b35ff5 commit 0f16514
Show file tree
Hide file tree
Showing 8 changed files with 207 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/integrations/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Built-in frameworks integrations:
* Litestar
* Starlette
* Aiogram
* Aiogram_dialog
* pyTelegramBotAPI
* Arq
* FastStream
Expand Down
2 changes: 2 additions & 0 deletions requirements/aiogram-dialog-210.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-r test.txt
aiogram_dialog==2.1.0
2 changes: 2 additions & 0 deletions requirements/aiogram-dialog-latest.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-r test.txt
aiogram_dialog
23 changes: 23 additions & 0 deletions src/dishka/integrations/aiogram_dialog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
__all__ = ["inject"]

from dishka.integrations.base import wrap_injection

TWO = 2
CONTAINER_NAME = "dishka_container"

def _container_getter(args, kwargs):
if len(args) == 0:
return kwargs[CONTAINER_NAME]
elif len(args) == TWO:
return args[-1].middleware_data[CONTAINER_NAME]
else:
return args[2].middleware_data[CONTAINER_NAME]


def inject(func):
return wrap_injection(
func=func,
is_async=True,
remove_depends=True,
container_getter=_container_getter,
)
Empty file.
37 changes: 37 additions & 0 deletions tests/integrations/aiogram_dialog/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from collections.abc import Iterable
from typing import NewType
from unittest.mock import Mock

from dishka import Provider, Scope, provide

AppDep = NewType("AppDep", str)
APP_DEP_VALUE = "APP"

RequestDep = NewType("RequestDep", str)
REQUEST_DEP_VALUE = "REQUEST"

WebSocketDep = NewType("WebSocketDep", str)
WS_DEP_VALUE = "WS"


class AppProvider(Provider):
def __init__(self):
super().__init__()
self.app_released = Mock()
self.request_released = Mock()
self.websocket_released = Mock()
self.mock = Mock()

@provide(scope=Scope.APP)
def app(self) -> Iterable[AppDep]:
yield APP_DEP_VALUE
self.app_released()

@provide(scope=Scope.REQUEST)
def request(self) -> Iterable[RequestDep]:
yield REQUEST_DEP_VALUE
self.request_released()

@provide(scope=Scope.REQUEST)
def mock(self) -> Mock:
return self.mock
138 changes: 138 additions & 0 deletions tests/integrations/aiogram_dialog/test_aiogram_dialog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
from unittest.mock import Mock

import pytest
from aiogram import Dispatcher
from aiogram.filters import CommandStart
from aiogram.fsm.state import State, StatesGroup
from aiogram_dialog import Dialog, StartMode, Window, setup_dialogs
from aiogram_dialog.test_tools import BotClient, MockMessageManager
from aiogram_dialog.test_tools.keyboard import InlineButtonTextLocator
from aiogram_dialog.widgets.kbd import Cancel, Start
from aiogram_dialog.widgets.text import Const
from tests.integrations.aiogram_dialog.conftest import AppProvider, RequestDep

from dishka import FromDishka, make_async_container
from dishka.integrations.aiogram import setup_dishka
from dishka.integrations.aiogram_dialog import inject


class MainSG(StatesGroup):
start = State()


class SubSG(StatesGroup):
start = State()


async def start(message, dialog_manager):
await dialog_manager.start(MainSG.start, mode=StartMode.RESET_STACK)


@inject
async def on_click(
event,
widget,
manager,
a: FromDishka[RequestDep],
mock: FromDishka[Mock],
):
mock(a)


@inject
async def on_start(
data,
manager,
a: FromDishka[RequestDep],
mock: FromDishka[Mock],
):
mock(a)


@inject
async def on_close(
data,
manager,
a: FromDishka[RequestDep],
mock: FromDishka[Mock],
):
mock(a)


@inject
async def on_process_result(
_, __, manager,
a: FromDishka[RequestDep],
mock: FromDishka[Mock],
):
mock(a)


@inject
async def getter(
a: FromDishka[RequestDep],
mock: FromDishka[Mock],
**kwargs,
):
mock(a)
return {}


dialog = Dialog(
Window(
Const("test"),
Start(
Const("test"),
id="sub",
state=SubSG.start,
on_click=on_click,
),
getter=getter,
state=MainSG.start,
),
on_start=on_start,
on_close=on_close,
on_process_result=on_process_result,
)
sub_dialog = Dialog(
Window(
Const("test"),
Cancel(),
state=SubSG.start,
),
)


@pytest.fixture()
def message_manager() -> MockMessageManager:
return MockMessageManager()


@pytest.fixture
def dp(message_manager):
dp = Dispatcher()
dp.message.register(start, CommandStart())
dp.include_routers(dialog, sub_dialog)
setup_dialogs(dp, message_manager=message_manager)
setup_dishka(make_async_container(AppProvider()), dp)
return dp


@pytest.fixture
def bot(dp):
return BotClient(dp)


@pytest.mark.asyncio
async def test_dialog(
bot: BotClient,
message_manager: MockMessageManager,
):
await bot.send("/start")
first_message = message_manager.one_message()
assert first_message.text == "test"
assert first_message.reply_markup

await bot.click(first_message, InlineButtonTextLocator("test"))
last_message = message_manager.last_message()
await bot.click(last_message, InlineButtonTextLocator("Cancel"))
4 changes: 4 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ env_list =
arq-0250
taskiq-0110
sanic-23121
aiogram-dialog-210

[pytest]
addopts = --cov=dishka --cov-append --cov-report term-missing -v
Expand Down Expand Up @@ -46,6 +47,8 @@ deps =
taskiq-0110: -r requirements/taskiq-0110.txt
sanic-latest: -r requirements/sanic-latest.txt
sanic-23121: -r requirements/sanic-23121.txt
aiogram-dialog-210: -r requirements/aiogram-dialog-210.txt
aiogram-dialog-latest: -r requirements/aiogram-dialog-latest.txt

commands =
aiohttp: pytest tests/integrations/aiohttp
Expand All @@ -59,6 +62,7 @@ commands =
arq: pytest tests/integrations/arq
taskiq: pytest tests/integrations/taskiq
sanic: pytest tests/integrations/sanic
aiogram_dialog: pytest tests/integrations/aiogram_dialog

package = editable

Expand Down

0 comments on commit 0f16514

Please sign in to comment.