1- from threading import Event
1+ import time
2+ from time import sleep
23from typing import Callable
34
45from slack_sdk .web import WebClient
56
6- from slack_bolt import App , Assistant , BoltContext , BoltRequest , Say , SetStatus , SetSuggestedPrompts
7+ from slack_bolt import App , BoltRequest , Assistant , Say , SetSuggestedPrompts , SetStatus , BoltContext
78from slack_bolt .middleware import Middleware
89from slack_bolt .request import BoltRequest as BoltRequestType
910from slack_bolt .response import BoltResponse
10- from tests .mock_web_api_server import cleanup_mock_web_api_server , setup_mock_web_api_server
11+ from tests .mock_web_api_server import (
12+ setup_mock_web_api_server ,
13+ cleanup_mock_web_api_server ,
14+ )
1115from tests .utils import remove_os_env_temporarily , restore_os_env
1216
1317
18+ def assert_target_called (called : dict , timeout : float = 0.5 ):
19+ deadline = time .time () + timeout
20+ while called ["value" ] is not True and time .time () < deadline :
21+ time .sleep (0.1 )
22+ assert called ["value" ] is True
23+
24+
1425class TestEventsAssistant :
1526 valid_token = "xoxb-valid"
1627 mock_api_server_base_url = "http://localhost:8888"
@@ -30,7 +41,7 @@ def teardown_method(self):
3041 def test_thread_started (self ):
3142 app = App (client = self .web_client )
3243 assistant = Assistant ()
33- listener_called = Event ()
44+ called = { "value" : False }
3445
3546 @assistant .thread_started
3647 def start_thread (say : Say , set_suggested_prompts : SetSuggestedPrompts , set_status : SetStatus , context : BoltContext ):
@@ -43,37 +54,37 @@ def start_thread(say: Say, set_suggested_prompts: SetSuggestedPrompts, set_statu
4354 set_suggested_prompts (
4455 prompts = [{"title" : "What does SLACK stand for?" , "message" : "What does SLACK stand for?" }], title = "foo"
4556 )
46- listener_called . set ()
57+ called [ "value" ] = True
4758
4859 app .assistant (assistant )
4960
5061 request = BoltRequest (body = thread_started_event_body , mode = "socket_mode" )
5162 response = app .dispatch (request )
5263 assert response .status == 200
53- assert listener_called . wait ( timeout = 0.1 ) is True
64+ assert_target_called ( called )
5465
5566 def test_thread_context_changed (self ):
5667 app = App (client = self .web_client )
5768 assistant = Assistant ()
58- listener_called = Event ()
69+ called = { "value" : False }
5970
6071 @assistant .thread_context_changed
6172 def handle_thread_context_changed (context : BoltContext ):
6273 assert context .channel_id == "D111"
6374 assert context .thread_ts == "1726133698.626339"
64- listener_called . set ()
75+ called [ "value" ] = True
6576
6677 app .assistant (assistant )
6778
6879 request = BoltRequest (body = thread_context_changed_event_body , mode = "socket_mode" )
6980 response = app .dispatch (request )
7081 assert response .status == 200
71- assert listener_called . wait ( timeout = 0.1 ) is True
82+ assert_target_called ( called )
7283
7384 def test_user_message (self ):
7485 app = App (client = self .web_client )
7586 assistant = Assistant ()
76- listener_called = Event ()
87+ called = { "value" : False }
7788
7889 @assistant .user_message
7990 def handle_user_message (say : Say , set_status : SetStatus , context : BoltContext ):
@@ -83,7 +94,7 @@ def handle_user_message(say: Say, set_status: SetStatus, context: BoltContext):
8394 try :
8495 set_status ("is typing..." )
8596 say ("Here you are!" )
86- listener_called . set ()
97+ called [ "value" ] = True
8798 except Exception as e :
8899 say (f"Oops, something went wrong (error: { e } )" )
89100
@@ -92,12 +103,12 @@ def handle_user_message(say: Say, set_status: SetStatus, context: BoltContext):
92103 request = BoltRequest (body = user_message_event_body , mode = "socket_mode" )
93104 response = app .dispatch (request )
94105 assert response .status == 200
95- assert listener_called . wait ( timeout = 0.1 ) is True
106+ assert_target_called ( called )
96107
97108 def test_user_message_with_assistant_thread (self ):
98109 app = App (client = self .web_client )
99110 assistant = Assistant ()
100- listener_called = Event ()
111+ called = { "value" : False }
101112
102113 @assistant .user_message
103114 def handle_user_message (say : Say , set_status : SetStatus , context : BoltContext ):
@@ -107,7 +118,7 @@ def handle_user_message(say: Say, set_status: SetStatus, context: BoltContext):
107118 try :
108119 set_status ("is typing..." )
109120 say ("Here you are!" )
110- listener_called . set ()
121+ called [ "value" ] = True
111122 except Exception as e :
112123 say (f"Oops, something went wrong (error: { e } )" )
113124
@@ -116,77 +127,77 @@ def handle_user_message(say: Say, set_status: SetStatus, context: BoltContext):
116127 request = BoltRequest (body = user_message_event_body_with_assistant_thread , mode = "socket_mode" )
117128 response = app .dispatch (request )
118129 assert response .status == 200
119- assert listener_called . wait ( timeout = 0.1 ) is True
130+ assert_target_called ( called )
120131
121132 def test_message_changed (self ):
122133 app = App (client = self .web_client )
123134 assistant = Assistant ()
124- listener_called = Event ()
135+ called = { "value" : False }
125136
126137 @assistant .user_message
127138 def handle_user_message ():
128- listener_called . set ()
139+ called [ "value" ] = True
129140
130141 @assistant .bot_message
131142 def handle_bot_message ():
132- listener_called . set ()
143+ called [ "value" ] = True
133144
134145 app .assistant (assistant )
135146
136147 request = BoltRequest (body = message_changed_event_body , mode = "socket_mode" )
137148 response = app .dispatch (request )
138149 assert response .status == 200
139- assert listener_called . wait ( timeout = 0.1 ) is False
150+ assert called [ "value" ] is False
140151
141152 def test_channel_user_message_ignored (self ):
142153 app = App (client = self .web_client )
143154 assistant = Assistant ()
144- listener_called = Event ()
155+ called = { "value" : False }
145156
146157 @assistant .user_message
147158 def handle_user_message ():
148- listener_called . set ()
159+ called [ "value" ] = True
149160
150161 @assistant .bot_message
151162 def handle_bot_message ():
152- listener_called . set ()
163+ called [ "value" ] = True
153164
154165 app .assistant (assistant )
155166
156167 request = BoltRequest (body = channel_user_message_event_body , mode = "socket_mode" )
157168 response = app .dispatch (request )
158169 assert response .status == 404
159- assert listener_called . wait ( timeout = 0.1 ) is False
170+ assert called [ "value" ] is False
160171
161172 def test_channel_message_changed_ignored (self ):
162173 app = App (client = self .web_client )
163174 assistant = Assistant ()
164- listener_called = Event ()
175+ called = { "value" : False }
165176
166177 @assistant .user_message
167178 def handle_user_message ():
168- listener_called . set ()
179+ called [ "value" ] = True
169180
170181 @assistant .bot_message
171182 def handle_bot_message ():
172- listener_called . set ()
183+ called [ "value" ] = True
173184
174185 app .assistant (assistant )
175186
176187 request = BoltRequest (body = channel_message_changed_event_body , mode = "socket_mode" )
177188 response = app .dispatch (request )
178189 assert response .status == 404
179- assert listener_called . wait ( timeout = 0.1 ) is False
190+ assert called [ "value" ] is False
180191
181192 def test_assistant_with_custom_listener_middleware (self ):
182193 app = App (client = self .web_client )
183194 assistant = Assistant ()
184- listener_called = Event ()
185- middleware_called = Event ()
195+ handler_called = { "value" : False }
196+ middleware_called = { "value" : False }
186197
187198 class TestMiddleware (Middleware ):
188199 def process (self , * , req : BoltRequestType , resp : BoltResponse , next : Callable [[], BoltResponse ]):
189- middleware_called . set ()
200+ middleware_called [ "value" ] = True
190201 # Verify assistant utilities are available
191202 assert req .context .get ("set_status" ) is not None
192203 assert req .context .get ("set_title" ) is not None
@@ -197,52 +208,52 @@ def process(self, *, req: BoltRequestType, resp: BoltResponse, next: Callable[[]
197208
198209 @assistant .thread_started (middleware = [TestMiddleware ()])
199210 def start_thread ():
200- listener_called . set ()
211+ handler_called [ "value" ] = True
201212
202213 @assistant .user_message (middleware = [TestMiddleware ()])
203214 def handle_user_message ():
204- listener_called . set ()
215+ handler_called [ "value" ] = True
205216
206217 app .assistant (assistant )
207218
208219 request = BoltRequest (body = thread_started_event_body , mode = "socket_mode" )
209220 response = app .dispatch (request )
210221 assert response .status == 200
211- assert listener_called . wait ( timeout = 0.1 ) is True
212- assert middleware_called . wait ( timeout = 0.1 ) is True
222+ assert_target_called ( handler_called )
223+ assert_target_called ( middleware_called )
213224
214- listener_called . clear ()
215- middleware_called . clear ()
225+ handler_called = { "value" : False }
226+ middleware_called = { "value" : False }
216227
217228 request = BoltRequest (body = user_message_event_body , mode = "socket_mode" )
218229 response = app .dispatch (request )
219230 assert response .status == 200
220- assert listener_called . wait ( timeout = 0.1 ) is True
221- assert middleware_called . wait ( timeout = 0.1 ) is True
231+ assert_target_called ( handler_called )
232+ assert_target_called ( middleware_called )
222233
223234 def test_assistant_custom_middleware_can_short_circuit (self ):
224235 app = App (client = self .web_client )
225236 assistant = Assistant ()
226- listener_called = Event ()
227- middleware_called = Event ()
237+ handler_called = { "value" : False }
238+ middleware_called = { "value" : False }
228239
229240 class BlockingMiddleware (Middleware ):
230241 def process (self , * , req : BoltRequestType , resp : BoltResponse , next : Callable [[], BoltResponse ]):
231- middleware_called . set ()
242+ middleware_called [ "value" ] = True
232243 # Intentionally not calling next() to short-circuit
233244 return BoltResponse (status = 200 )
234245
235246 @assistant .thread_started (middleware = [BlockingMiddleware ()])
236247 def start_thread (say : Say , context : BoltContext ):
237- listener_called . set ()
248+ handler_called [ "value" ] = True
238249
239250 app .assistant (assistant )
240251
241252 request = BoltRequest (body = thread_started_event_body , mode = "socket_mode" )
242253 response = app .dispatch (request )
243254 assert response .status == 200
244- assert middleware_called . wait ( timeout = 0.1 ) is True
245- assert listener_called . wait ( timeout = 0.1 ) is False
255+ assert_target_called ( middleware_called )
256+ assert handler_called [ "value" ] is False
246257
247258
248259def build_payload (event : dict ) -> dict :
0 commit comments