2
2
# Licensed under the MIT License.
3
3
import uuid
4
4
from http import HTTPStatus
5
- from typing import Callable , Union
5
+ from typing import Callable , Union , List
6
6
from unittest .mock import Mock
7
7
8
8
import aiounittest
46
46
class SimpleConversationIdFactory (ConversationIdFactoryBase ):
47
47
def __init__ (self ):
48
48
self .conversation_refs = {}
49
+ self .create_count = 0
49
50
50
51
async def create_skill_conversation_id (
51
52
self ,
52
53
options_or_conversation_reference : Union [
53
54
SkillConversationIdFactoryOptions , ConversationReference
54
55
],
55
56
) -> str :
57
+ self .create_count += 1
56
58
key = (
57
59
options_or_conversation_reference .activity .conversation .id
58
60
+ options_or_conversation_reference .activity .service_url
@@ -72,7 +74,8 @@ async def get_conversation_reference(
72
74
return self .conversation_refs [skill_conversation_id ]
73
75
74
76
async def delete_conversation_reference (self , skill_conversation_id : str ):
75
- raise NotImplementedError ()
77
+ self .conversation_refs .pop (skill_conversation_id , None )
78
+ return
76
79
77
80
78
81
class SkillDialogTests (aiounittest .AsyncTestCase ):
@@ -506,6 +509,57 @@ async def post_return():
506
509
self .assertIsNotNone (final_activity )
507
510
self .assertEqual (len (final_activity .attachments ), 1 )
508
511
512
+ async def test_end_of_conversation_from_expect_replies_calls_delete_conversation_reference (
513
+ self ,
514
+ ):
515
+ activity_sent : Activity = None
516
+
517
+ # Callback to capture the parameters sent to the skill
518
+ async def capture_action (
519
+ from_bot_id : str , # pylint: disable=unused-argument
520
+ to_bot_id : str , # pylint: disable=unused-argument
521
+ to_uri : str , # pylint: disable=unused-argument
522
+ service_url : str , # pylint: disable=unused-argument
523
+ conversation_id : str , # pylint: disable=unused-argument
524
+ activity : Activity ,
525
+ ):
526
+ # Capture values sent to the skill so we can assert the right parameters were used.
527
+ nonlocal activity_sent
528
+ activity_sent = activity
529
+
530
+ eoc = Activity .create_end_of_conversation_activity ()
531
+ expected_replies = list ([eoc ])
532
+
533
+ # Create a mock skill client to intercept calls and capture what is sent.
534
+ mock_skill_client = self ._create_mock_skill_client (
535
+ capture_action , expected_replies = expected_replies
536
+ )
537
+
538
+ # Use Memory for conversation state
539
+ conversation_state = ConversationState (MemoryStorage ())
540
+ dialog_options = self .create_skill_dialog_options (
541
+ conversation_state , mock_skill_client
542
+ )
543
+
544
+ # Create the SkillDialogInstance and the activity to send.
545
+ sut = SkillDialog (dialog_options , dialog_id = "dialog" )
546
+ activity_to_send = Activity .create_message_activity ()
547
+ activity_to_send .delivery_mode = DeliveryModes .expect_replies
548
+ activity_to_send .text = str (uuid .uuid4 ())
549
+ client = DialogTestClient (
550
+ "test" ,
551
+ sut ,
552
+ BeginSkillDialogOptions (activity_to_send ),
553
+ conversation_state = conversation_state ,
554
+ )
555
+
556
+ # Send something to the dialog to start it
557
+ await client .send_activity ("hello" )
558
+
559
+ simple_id_factory : SimpleConversationIdFactory = dialog_options .conversation_id_factory
560
+ self .assertEqual (0 , len (simple_id_factory .conversation_refs ))
561
+ self .assertEqual (1 , simple_id_factory .create_count )
562
+
509
563
@staticmethod
510
564
def create_skill_dialog_options (
511
565
conversation_state : ConversationState ,
@@ -547,9 +601,15 @@ def create_oauth_card_attachment_activity(uri: str) -> Activity:
547
601
return attachment_activity
548
602
549
603
def _create_mock_skill_client (
550
- self , callback : Callable , return_status : Union [Callable , int ] = 200
604
+ self ,
605
+ callback : Callable ,
606
+ return_status : Union [Callable , int ] = 200 ,
607
+ expected_replies : List [Activity ] = None ,
551
608
) -> BotFrameworkClient :
552
609
mock_client = Mock ()
610
+ activity_list = ExpectedReplies (
611
+ activities = expected_replies or [MessageFactory .text ("dummy activity" )]
612
+ )
553
613
554
614
async def mock_post_activity (
555
615
from_bot_id : str ,
@@ -572,7 +632,7 @@ async def mock_post_activity(
572
632
573
633
if isinstance (return_status , Callable ):
574
634
return await return_status ()
575
- return InvokeResponse (status = return_status )
635
+ return InvokeResponse (status = return_status , body = activity_list )
576
636
577
637
mock_client .post_activity .side_effect = mock_post_activity
578
638
0 commit comments