22# Licensed under the MIT License.
33
44import aiounittest
5- from botbuilder .dialogs .prompts import AttachmentPrompt , PromptOptions , PromptRecognizerResult
6- from botbuilder .schema import Activity , InputHints
5+ from botbuilder .dialogs .prompts import AttachmentPrompt , PromptOptions , PromptRecognizerResult , PromptValidatorContext
6+ from botbuilder .schema import Activity , ActivityTypes , Attachment , InputHints
77
8- from botbuilder .core import TurnContext , ConversationState
8+ from botbuilder .core import TurnContext , ConversationState , MemoryStorage , MessageFactory
99from botbuilder .core .adapters import TestAdapter
10+ from botbuilder .dialogs import DialogSet , DialogTurnStatus
1011
1112class AttachmentPromptTests (aiounittest .AsyncTestCase ):
1213 def test_attachment_prompt_with_empty_id_should_fail (self ):
@@ -18,6 +19,245 @@ def test_attachment_prompt_with_empty_id_should_fail(self):
1819 def test_attachment_prompt_with_none_id_should_fail (self ):
1920 with self .assertRaises (TypeError ):
2021 AttachmentPrompt (None )
21-
22- # TODO other tests require TestFlow
23-
22+
23+ async def test_basic_attachment_prompt (self ):
24+ async def exec_test (turn_context : TurnContext ):
25+ dc = await dialogs .create_context (turn_context )
26+
27+ results = await dc .continue_dialog ()
28+ if results .status == DialogTurnStatus .Empty :
29+ options = PromptOptions (prompt = Activity (type = ActivityTypes .message , text = 'please add an attachment.' ))
30+ await dc .prompt ('AttachmentPrompt' , options )
31+ elif results .status == DialogTurnStatus .Complete :
32+ attachment = results .result [0 ]
33+ content = MessageFactory .text (attachment .content )
34+ await turn_context .send_activity (content )
35+
36+ await convo_state .save_changes (turn_context )
37+
38+ # Initialize TestAdapter.
39+ adapter = TestAdapter (exec_test )
40+
41+ # Create ConversationState with MemoryStorage and register the state as middleware.
42+ convo_state = ConversationState (MemoryStorage ())
43+
44+ # Create a DialogState property, DialogSet and AttachmentPrompt.
45+ dialog_state = convo_state .create_property ('dialog_state' )
46+ dialogs = DialogSet (dialog_state )
47+ dialogs .add (AttachmentPrompt ('AttachmentPrompt' ))
48+
49+ # Create incoming activity with attachment.
50+ attachment = Attachment (content = 'some content' , content_type = 'text/plain' )
51+ attachment_activity = Activity (type = ActivityTypes .message , attachments = [attachment ])
52+
53+ step1 = await adapter .send ('hello' )
54+ step2 = await step1 .assert_reply ('please add an attachment.' )
55+ step3 = await step2 .send (attachment_activity )
56+ await step3 .assert_reply ('some content' )
57+
58+ async def test_attachment_prompt_with_validator (self ):
59+ async def exec_test (turn_context : TurnContext ):
60+ dc = await dialogs .create_context (turn_context )
61+
62+ results = await dc .continue_dialog ()
63+ if results .status == DialogTurnStatus .Empty :
64+ options = PromptOptions (prompt = Activity (type = ActivityTypes .message , text = 'please add an attachment.' ))
65+ await dc .prompt ('AttachmentPrompt' , options )
66+ elif results .status == DialogTurnStatus .Complete :
67+ attachment = results .result [0 ]
68+ content = MessageFactory .text (attachment .content )
69+ await turn_context .send_activity (content )
70+
71+ await convo_state .save_changes (turn_context )
72+
73+ # Initialize TestAdapter.
74+ adapter = TestAdapter (exec_test )
75+
76+ # Create ConversationState with MemoryStorage and register the state as middleware.
77+ convo_state = ConversationState (MemoryStorage ())
78+
79+ # Create a DialogState property, DialogSet and AttachmentPrompt.
80+ dialog_state = convo_state .create_property ('dialog_state' )
81+ dialogs = DialogSet (dialog_state )
82+
83+ async def aux_validator (prompt_context : PromptValidatorContext ):
84+ assert prompt_context , 'Validator missing prompt_context'
85+ return prompt_context .recognized .succeeded
86+
87+ dialogs .add (AttachmentPrompt ('AttachmentPrompt' , aux_validator ))
88+
89+ # Create incoming activity with attachment.
90+ attachment = Attachment (content = 'some content' , content_type = 'text/plain' )
91+ attachment_activity = Activity (type = ActivityTypes .message , attachments = [attachment ])
92+
93+ step1 = await adapter .send ('hello' )
94+ step2 = await step1 .assert_reply ('please add an attachment.' )
95+ step3 = await step2 .send (attachment_activity )
96+ await step3 .assert_reply ('some content' )
97+
98+ async def test_retry_attachment_prompt (self ):
99+ async def exec_test (turn_context : TurnContext ):
100+ dc = await dialogs .create_context (turn_context )
101+
102+ results = await dc .continue_dialog ()
103+ if results .status == DialogTurnStatus .Empty :
104+ options = PromptOptions (prompt = Activity (type = ActivityTypes .message , text = 'please add an attachment.' ))
105+ await dc .prompt ('AttachmentPrompt' , options )
106+ elif results .status == DialogTurnStatus .Complete :
107+ attachment = results .result [0 ]
108+ content = MessageFactory .text (attachment .content )
109+ await turn_context .send_activity (content )
110+
111+ await convo_state .save_changes (turn_context )
112+
113+ # Initialize TestAdapter.
114+ adapter = TestAdapter (exec_test )
115+
116+ # Create ConversationState with MemoryStorage and register the state as middleware.
117+ convo_state = ConversationState (MemoryStorage ())
118+
119+ # Create a DialogState property, DialogSet and AttachmentPrompt.
120+ dialog_state = convo_state .create_property ('dialog_state' )
121+ dialogs = DialogSet (dialog_state )
122+ dialogs .add (AttachmentPrompt ('AttachmentPrompt' ))
123+
124+ # Create incoming activity with attachment.
125+ attachment = Attachment (content = 'some content' , content_type = 'text/plain' )
126+ attachment_activity = Activity (type = ActivityTypes .message , attachments = [attachment ])
127+
128+ step1 = await adapter .send ('hello' )
129+ step2 = await step1 .assert_reply ('please add an attachment.' )
130+ step3 = await step2 .send ('hello again' )
131+ step4 = await step3 .assert_reply ('please add an attachment.' )
132+ step5 = await step4 .send (attachment_activity )
133+ await step5 .assert_reply ('some content' )
134+
135+ async def test_attachment_prompt_with_custom_retry (self ):
136+ async def exec_test (turn_context : TurnContext ):
137+ dc = await dialogs .create_context (turn_context )
138+
139+ results = await dc .continue_dialog ()
140+ if results .status == DialogTurnStatus .Empty :
141+ options = PromptOptions (
142+ prompt = Activity (type = ActivityTypes .message , text = 'please add an attachment.' ),
143+ retry_prompt = Activity (type = ActivityTypes .message , text = 'please try again.' )
144+ )
145+ await dc .prompt ('AttachmentPrompt' , options )
146+ elif results .status == DialogTurnStatus .Complete :
147+ attachment = results .result [0 ]
148+ content = MessageFactory .text (attachment .content )
149+ await turn_context .send_activity (content )
150+
151+ await convo_state .save_changes (turn_context )
152+
153+ # Initialize TestAdapter.
154+ adapter = TestAdapter (exec_test )
155+
156+ # Create ConversationState with MemoryStorage and register the state as middleware.
157+ convo_state = ConversationState (MemoryStorage ())
158+
159+ # Create a DialogState property, DialogSet and AttachmentPrompt.
160+ dialog_state = convo_state .create_property ('dialog_state' )
161+ dialogs = DialogSet (dialog_state )
162+
163+ async def aux_validator (prompt_context : PromptValidatorContext ):
164+ assert prompt_context , 'Validator missing prompt_context'
165+ return prompt_context .recognized .succeeded
166+
167+ dialogs .add (AttachmentPrompt ('AttachmentPrompt' , aux_validator ))
168+
169+ # Create incoming activity with attachment.
170+ attachment = Attachment (content = 'some content' , content_type = 'text/plain' )
171+ attachment_activity = Activity (type = ActivityTypes .message , attachments = [attachment ])
172+ invalid_activty = Activity (type = ActivityTypes .message , text = 'invalid' )
173+
174+ step1 = await adapter .send ('hello' )
175+ step2 = await step1 .assert_reply ('please add an attachment.' )
176+ step3 = await step2 .send (invalid_activty )
177+ step4 = await step3 .assert_reply ('please try again.' )
178+ step5 = await step4 .send (attachment_activity )
179+ await step5 .assert_reply ('some content' )
180+
181+ async def test_should_send_ignore_retry_rompt_if_validator_replies (self ):
182+ async def exec_test (turn_context : TurnContext ):
183+ dc = await dialogs .create_context (turn_context )
184+
185+ results = await dc .continue_dialog ()
186+ if results .status == DialogTurnStatus .Empty :
187+ options = PromptOptions (
188+ prompt = Activity (type = ActivityTypes .message , text = 'please add an attachment.' ),
189+ retry_prompt = Activity (type = ActivityTypes .message , text = 'please try again.' )
190+ )
191+ await dc .prompt ('AttachmentPrompt' , options )
192+ elif results .status == DialogTurnStatus .Complete :
193+ attachment = results .result [0 ]
194+ content = MessageFactory .text (attachment .content )
195+ await turn_context .send_activity (content )
196+
197+ await convo_state .save_changes (turn_context )
198+
199+ # Initialize TestAdapter.
200+ adapter = TestAdapter (exec_test )
201+
202+ # Create ConversationState with MemoryStorage and register the state as middleware.
203+ convo_state = ConversationState (MemoryStorage ())
204+
205+ # Create a DialogState property, DialogSet and AttachmentPrompt.
206+ dialog_state = convo_state .create_property ('dialog_state' )
207+ dialogs = DialogSet (dialog_state )
208+
209+ async def aux_validator (prompt_context : PromptValidatorContext ):
210+ assert prompt_context , 'Validator missing prompt_context'
211+
212+ if not prompt_context .recognized .succeeded :
213+ await prompt_context .context .send_activity ('Bad input.' )
214+
215+ return prompt_context .recognized .succeeded
216+
217+ dialogs .add (AttachmentPrompt ('AttachmentPrompt' , aux_validator ))
218+
219+ # Create incoming activity with attachment.
220+ attachment = Attachment (content = 'some content' , content_type = 'text/plain' )
221+ attachment_activity = Activity (type = ActivityTypes .message , attachments = [attachment ])
222+ invalid_activty = Activity (type = ActivityTypes .message , text = 'invalid' )
223+
224+ step1 = await adapter .send ('hello' )
225+ step2 = await step1 .assert_reply ('please add an attachment.' )
226+ step3 = await step2 .send (invalid_activty )
227+ step4 = await step3 .assert_reply ('Bad input.' )
228+ step5 = await step4 .send (attachment_activity )
229+ await step5 .assert_reply ('some content' )
230+
231+ async def test_should_not_send_retry_if_not_specified (self ):
232+ async def exec_test (turn_context : TurnContext ):
233+ dc = await dialogs .create_context (turn_context )
234+
235+ results = await dc .continue_dialog ()
236+ if results .status == DialogTurnStatus .Empty :
237+ await dc .begin_dialog ('AttachmentPrompt' , PromptOptions ())
238+ elif results .status == DialogTurnStatus .Complete :
239+ attachment = results .result [0 ]
240+ content = MessageFactory .text (attachment .content )
241+ await turn_context .send_activity (content )
242+
243+ await convo_state .save_changes (turn_context )
244+
245+ # Initialize TestAdapter.
246+ adapter = TestAdapter (exec_test )
247+
248+ # Create ConversationState with MemoryStorage and register the state as middleware.
249+ convo_state = ConversationState (MemoryStorage ())
250+
251+ # Create a DialogState property, DialogSet and AttachmentPrompt.
252+ dialog_state = convo_state .create_property ('dialog_state' )
253+ dialogs = DialogSet (dialog_state )
254+ dialogs .add (AttachmentPrompt ('AttachmentPrompt' ))
255+
256+ # Create incoming activity with attachment.
257+ attachment = Attachment (content = 'some content' , content_type = 'text/plain' )
258+ attachment_activity = Activity (type = ActivityTypes .message , attachments = [attachment ])
259+
260+ step1 = await adapter .send ('hello' )
261+ step2 = await step1 .send ('what?' )
262+ step3 = await step2 .send (attachment_activity )
263+ await step3 .assert_reply ('some content' )
0 commit comments