Forum topic in FSM (#1161)

* Base implementation

* Added tests, fixed arguments priority

* Use `Optional[X]` instead of `X | None`

* Added changelog

* Added tests
This commit is contained in:
Alex Root Junior 2023-04-22 19:35:41 +03:00 committed by GitHub
parent 1538bc2e2d
commit 942ba0d520
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 164 additions and 60 deletions

View file

@ -14,7 +14,7 @@ from aiogram import Bot
from aiogram.dispatcher.dispatcher import Dispatcher
from aiogram.dispatcher.event.bases import UNHANDLED, SkipHandler
from aiogram.dispatcher.router import Router
from aiogram.methods import GetMe, GetUpdates, Request, SendMessage, TelegramMethod
from aiogram.methods import GetMe, GetUpdates, SendMessage, TelegramMethod
from aiogram.types import (
CallbackQuery,
Chat,
@ -462,9 +462,9 @@ class TestDispatcher:
async def my_handler(event: Any, **kwargs: Any):
assert event == getattr(update, event_type)
if has_chat:
assert Chat.get_current(False)
assert kwargs["event_chat"]
if has_user:
assert User.get_current(False)
assert kwargs["event_from_user"]
return kwargs
result = await router.feed_update(bot, update, test="PASS")

View file

@ -1,6 +1,9 @@
from unittest.mock import patch
import pytest
from aiogram.dispatcher.middlewares.user_context import UserContextMiddleware
from aiogram.types import Update
async def next_handler(*args, **kwargs):
@ -11,3 +14,13 @@ class TestUserContextMiddleware:
async def test_unexpected_event_type(self):
with pytest.raises(RuntimeError):
await UserContextMiddleware()(next_handler, object(), {})
async def test_call(self):
middleware = UserContextMiddleware()
data = {}
with patch.object(UserContextMiddleware, "resolve_event_context", return_value=[1, 2, 3]):
await middleware(next_handler, Update(update_id=42), data)
assert data["event_chat"] == 1
assert data["event_from_user"] == 2
assert data["event_thread_id"] == 3

View file

@ -11,6 +11,7 @@ PREFIX = "test"
BOT_ID = 42
CHAT_ID = -1
USER_ID = 2
THREAD_ID = 3
FIELD = "data"
@ -46,6 +47,19 @@ class TestRedisDefaultKeyBuilder:
with pytest.raises(ValueError):
key_builder.build(key, FIELD)
def test_thread_id(self):
key_builder = DefaultKeyBuilder(
prefix=PREFIX,
)
key = StorageKey(
chat_id=CHAT_ID,
user_id=USER_ID,
bot_id=BOT_ID,
thread_id=THREAD_ID,
destiny=DEFAULT_DESTINY,
)
assert key_builder.build(key, FIELD) == f"{PREFIX}:{CHAT_ID}:{THREAD_ID}:{USER_ID}:{FIELD}"
def test_create_isolation(self):
fake_redis = object()
storage = RedisStorage(redis=fake_redis)

View file

@ -2,19 +2,41 @@ import pytest
from aiogram.fsm.strategy import FSMStrategy, apply_strategy
CHAT_ID = -42
USER_ID = 42
THREAD_ID = 1
PRIVATE = (USER_ID, USER_ID, None)
CHAT = (CHAT_ID, USER_ID, None)
THREAD = (CHAT_ID, USER_ID, THREAD_ID)
class TestStrategy:
@pytest.mark.parametrize(
"strategy,case,expected",
[
[FSMStrategy.USER_IN_CHAT, (-42, 42), (-42, 42)],
[FSMStrategy.CHAT, (-42, 42), (-42, -42)],
[FSMStrategy.GLOBAL_USER, (-42, 42), (42, 42)],
[FSMStrategy.USER_IN_CHAT, (42, 42), (42, 42)],
[FSMStrategy.CHAT, (42, 42), (42, 42)],
[FSMStrategy.GLOBAL_USER, (42, 42), (42, 42)],
[FSMStrategy.USER_IN_CHAT, CHAT, CHAT],
[FSMStrategy.USER_IN_CHAT, PRIVATE, PRIVATE],
[FSMStrategy.USER_IN_CHAT, THREAD, CHAT],
[FSMStrategy.CHAT, CHAT, (CHAT_ID, CHAT_ID, None)],
[FSMStrategy.CHAT, PRIVATE, (USER_ID, USER_ID, None)],
[FSMStrategy.CHAT, THREAD, (CHAT_ID, CHAT_ID, None)],
[FSMStrategy.GLOBAL_USER, CHAT, PRIVATE],
[FSMStrategy.GLOBAL_USER, PRIVATE, PRIVATE],
[FSMStrategy.GLOBAL_USER, THREAD, PRIVATE],
[FSMStrategy.USER_IN_THREAD, CHAT, CHAT],
[FSMStrategy.USER_IN_THREAD, PRIVATE, PRIVATE],
[FSMStrategy.USER_IN_THREAD, THREAD, THREAD],
],
)
def test_strategy(self, strategy, case, expected):
chat_id, user_id = case
assert apply_strategy(chat_id=chat_id, user_id=user_id, strategy=strategy) == expected
chat_id, user_id, thread_id = case
assert (
apply_strategy(
chat_id=chat_id,
user_id=user_id,
thread_id=thread_id,
strategy=strategy,
)
== expected
)