-
-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathdialogs_testing.py
More file actions
135 lines (103 loc) · 4.03 KB
/
Copy pathdialogs_testing.py
File metadata and controls
135 lines (103 loc) · 4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
"""Демонстрация maxo.dialogs.test_tools.
Запуск: python examples/dialogs_testing.py
Не требует токена бота или базы данных.
"""
import asyncio
from maxo import Dispatcher
from maxo.dialogs import Dialog, DialogManager, StartMode, Window, setup_dialogs
from maxo.dialogs.test_tools import BotClient, MockMessageManager
from maxo.dialogs.test_tools.keyboard import InlineButtonTextLocator
from maxo.dialogs.test_tools.memory_storage import JsonMemoryStorage
from maxo.dialogs.widgets.kbd import Back, Button
from maxo.dialogs.widgets.text import Const
from maxo.fsm import State, StatesGroup
from maxo.fsm.key_builder import DefaultKeyBuilder
from maxo.fsm.storages.memory import SimpleEventIsolation
from maxo.routing.filters import CommandStart
from maxo.routing.signals import AfterStartup, BeforeStartup
from maxo.types import CallbackButton, MessageCallback, MessageCreated
class MenuSG(StatesGroup):
main = State()
detail = State()
async def on_detail(
callback: MessageCallback,
button: Button,
manager: DialogManager,
) -> None:
await manager.switch_to(MenuSG.detail)
async def start_handler(
message: MessageCreated,
dialog_manager: DialogManager,
) -> None:
await dialog_manager.start(MenuSG.main, mode=StartMode.RESET_STACK)
def make_dialog() -> Dialog:
return Dialog(
Window(
Const("Главное меню"),
Button(Const("Подробнее"), id="detail", on_click=on_detail),
state=MenuSG.main,
),
Window(
Const("Детальная страница"),
Back(),
state=MenuSG.detail,
),
)
def make_env() -> tuple[Dispatcher, BotClient, MockMessageManager]:
storage = JsonMemoryStorage()
message_manager = MockMessageManager()
key_builder = DefaultKeyBuilder(with_destiny=True)
event_isolation = SimpleEventIsolation(key_builder=key_builder)
test_dp = Dispatcher(
storage=storage,
events_isolation=event_isolation,
key_builder=key_builder,
)
test_dp.message_created.handler(start_handler, CommandStart())
test_dp.include(make_dialog())
setup_dialogs(
test_dp,
message_manager=message_manager,
events_isolation=event_isolation,
)
client = BotClient(test_dp)
return test_dp, client, message_manager
async def startup(dp: Dispatcher, client: BotClient) -> None:
await dp.feed_signal(BeforeStartup(), client.bot)
await dp.feed_signal(AfterStartup(), client.bot)
async def demo_render_window() -> None:
test_dp, client, message_manager = make_env()
await startup(test_dp, client)
await client.send("/start")
message = message_manager.last_message()
if message.body.text != "Главное меню":
raise AssertionError(f"Unexpected text: {message.body.text!r}")
if message.body.keyboard is None:
raise AssertionError("Keyboard is missing")
buttons = [
btn.text
for row in message.body.keyboard.buttons
for btn in row
if isinstance(btn, CallbackButton)
]
if "Подробнее" not in buttons:
raise AssertionError(f"Button not found, got: {buttons}")
print("demo_render_window: OK")
async def demo_render_transition() -> None:
test_dp, client, message_manager = make_env()
await startup(test_dp, client)
await client.send("/start")
menu_message = message_manager.last_message()
message_manager.reset_history()
callback_id = await client.click(menu_message, InlineButtonTextLocator("Подробнее"))
message_manager.assert_answered(callback_id)
detail_msg = message_manager.last_message()
if detail_msg.body.text != "Детальная страница":
raise AssertionError(f"Unexpected text: {detail_msg.body.text!r}")
print("demo_render_transition: OK")
async def main() -> None:
await demo_render_window()
await demo_render_transition()
print("All demos passed.")
if __name__ == "__main__":
asyncio.run(main())