4
4
import json
5
5
import unittest
6
6
from os import path
7
+ from typing import Tuple
7
8
from unittest .mock import Mock , patch
8
9
9
10
import requests
11
+ from azure .cognitiveservices .language .luis .runtime import LUISRuntimeClient
12
+ from azure .cognitiveservices .language .luis .runtime .luis_runtime_client import (
13
+ LUISRuntimeClientConfiguration ,
14
+ )
10
15
from msrest import Deserializer
11
16
from requests .models import Response
12
17
18
23
RecognizerResult ,
19
24
TopIntent ,
20
25
)
21
- from botbuilder .core import TurnContext
26
+ from botbuilder .core import BotAdapter , TurnContext
22
27
from botbuilder .core .adapters import TestAdapter
23
28
from botbuilder .schema import (
24
29
Activity ,
27
32
ConversationAccount ,
28
33
)
29
34
35
+ from .null_adapter import NullAdapter
36
+
30
37
31
38
class LuisRecognizerTest (unittest .TestCase ):
32
39
_luisAppId : str = "b31aeaf3-3511-495b-a07f-571fc873214b"
@@ -88,47 +95,10 @@ def test_luis_recognizer_none_luis_app_arg(self):
88
95
89
96
def test_single_intent_simply_entity (self ):
90
97
utterance : str = "My name is Emad"
91
- response_str : str = """{
92
- "query": "my name is Emad",
93
- "topScoringIntent": {
94
- "intent": "SpecifyName",
95
- "score": 0.8785189
96
- },
97
- "intents": [
98
- {
99
- "intent": "SpecifyName",
100
- "score": 0.8785189
101
- }
102
- ],
103
- "entities": [
104
- {
105
- "entity": "emad",
106
- "type": "Name",
107
- "startIndex": 11,
108
- "endIndex": 14,
109
- "score": 0.8446753
110
- }
111
- ]
112
- }"""
113
- response_json = json .loads (response_str )
98
+ response_path : str = "SingleIntent_SimplyEntity.json"
99
+
100
+ _ , result = LuisRecognizerTest ._get_recognizer_result (utterance , response_path )
114
101
115
- my_app = LuisApplication (
116
- LuisRecognizerTest ._luisAppId ,
117
- LuisRecognizerTest ._subscriptionKey ,
118
- endpoint = "" ,
119
- )
120
- recognizer = LuisRecognizer (my_app , prediction_options = None )
121
- context = LuisRecognizerTest ._get_context (utterance )
122
- response = Mock (spec = Response )
123
- response .status_code = 200
124
- response .headers = {}
125
- response .reason = ""
126
- with patch ("requests.Session.send" , return_value = response ):
127
- with patch (
128
- "msrest.serialization.Deserializer._unpack_content" ,
129
- return_value = response_json ,
130
- ):
131
- result = recognizer .recognize (context )
132
102
self .assertIsNotNone (result )
133
103
self .assertIsNone (result .altered_text )
134
104
self .assertEqual (utterance , result .text )
@@ -149,7 +119,7 @@ def test_null_utterance(self):
149
119
utterance : str = None
150
120
response_path : str = "SingleIntent_SimplyEntity.json" # The path is irrelevant in this case
151
121
152
- result = LuisRecognizerTest ._get_recognizer_result (utterance , response_path )
122
+ _ , result = LuisRecognizerTest ._get_recognizer_result (utterance , response_path )
153
123
154
124
self .assertIsNotNone (result )
155
125
self .assertIsNone (result .altered_text )
@@ -165,7 +135,7 @@ def test_multiple_intents_prebuilt_entity(self):
165
135
utterance : str = "Please deliver February 2nd 2001"
166
136
response_path : str = "MultipleIntents_PrebuiltEntity.json"
167
137
168
- result = LuisRecognizerTest ._get_recognizer_result (utterance , response_path )
138
+ _ , result = LuisRecognizerTest ._get_recognizer_result (utterance , response_path )
169
139
170
140
self .assertIsNotNone (result )
171
141
self .assertEqual (utterance , result .text )
@@ -202,7 +172,7 @@ def test_multiple_intents_prebuilt_entities_with_multi_values(self):
202
172
utterance : str = "Please deliver February 2nd 2001 in room 201"
203
173
response_path : str = "MultipleIntents_PrebuiltEntitiesWithMultiValues.json"
204
174
205
- result = LuisRecognizerTest ._get_recognizer_result (utterance , response_path )
175
+ _ , result = LuisRecognizerTest ._get_recognizer_result (utterance , response_path )
206
176
207
177
self .assertIsNotNone (result )
208
178
self .assertIsNotNone (result .text )
@@ -221,7 +191,7 @@ def test_multiple_intents_list_entity_with_single_value(self):
221
191
utterance : str = "I want to travel on united"
222
192
response_path : str = "MultipleIntents_ListEntityWithSingleValue.json"
223
193
224
- result = LuisRecognizerTest ._get_recognizer_result (utterance , response_path )
194
+ _ , result = LuisRecognizerTest ._get_recognizer_result (utterance , response_path )
225
195
226
196
self .assertIsNotNone (result )
227
197
self .assertIsNotNone (result .text )
@@ -241,7 +211,7 @@ def test_multiple_intents_list_entity_with_multi_values(self):
241
211
utterance : str = "I want to travel on DL"
242
212
response_path : str = "MultipleIntents_ListEntityWithMultiValues.json"
243
213
244
- result = LuisRecognizerTest ._get_recognizer_result (utterance , response_path )
214
+ _ , result = LuisRecognizerTest ._get_recognizer_result (utterance , response_path )
245
215
246
216
self .assertIsNotNone (result )
247
217
self .assertIsNotNone (result .text )
@@ -263,7 +233,7 @@ def test_multiple_intents_composite_entity_model(self):
263
233
utterance : str = "Please deliver it to 98033 WA"
264
234
response_path : str = "MultipleIntents_CompositeEntityModel.json"
265
235
266
- result = LuisRecognizerTest ._get_recognizer_result (utterance , response_path )
236
+ _ , result = LuisRecognizerTest ._get_recognizer_result (utterance , response_path )
267
237
268
238
self .assertIsNotNone (result )
269
239
self .assertIsNotNone (result .text )
@@ -313,7 +283,7 @@ def test_multiple_date_time_entities(self):
313
283
utterance : str = "Book a table on Friday or tomorrow at 5 or tomorrow at 4"
314
284
response_path : str = "MultipleDateTimeEntities.json"
315
285
316
- result = LuisRecognizerTest ._get_recognizer_result (utterance , response_path )
286
+ _ , result = LuisRecognizerTest ._get_recognizer_result (utterance , response_path )
317
287
318
288
self .assertIsNotNone (result .entities ["datetime" ])
319
289
self .assertEqual (3 , len (result .entities ["datetime" ]))
@@ -332,7 +302,7 @@ def test_v1_datetime_resolution(self):
332
302
utterance : str = "at 4"
333
303
response_path : str = "V1DatetimeResolution.json"
334
304
335
- result = LuisRecognizerTest ._get_recognizer_result (utterance , response_path )
305
+ _ , result = LuisRecognizerTest ._get_recognizer_result (utterance , response_path )
336
306
337
307
self .assertIsNotNone (result .entities ["datetime_time" ])
338
308
self .assertEqual (1 , len (result .entities ["datetime_time" ]))
@@ -367,28 +337,41 @@ def test_top_intent_returns_top_intent_if_score_equals_min_score(self):
367
337
)
368
338
self .assertEqual (default_intent , "Greeting" )
369
339
340
+ def test_user_agent_contains_product_version (self ):
341
+ utterance : str = "please book from May 5 to June 6"
342
+ response_path : str = "MultipleDateTimeEntities.json" # it doesn't matter to use which file.
343
+
344
+ recognizer , _ = LuisRecognizerTest ._get_recognizer_result (
345
+ utterance , response_path , bot_adapter = NullAdapter ()
346
+ )
347
+
348
+ runtime : LUISRuntimeClient = recognizer ._runtime
349
+ config : LUISRuntimeClientConfiguration = runtime.config
350
+ user_agent = config .user_agent
351
+
352
+ # Verify we didn't unintentionally stamp on the user-agent from the client.
353
+ self .assertTrue ("azure-cognitiveservices-language-luis" in user_agent )
354
+
355
+ # And that we added the bot.builder package details.
356
+ self .assertTrue ("botbuilder-ai/4" in user_agent )
357
+
370
358
def assert_score (self , score : float ) -> None :
371
359
self .assertTrue (score >= 0 )
372
360
self .assertTrue (score <= 1 )
373
361
374
362
@classmethod
375
363
def _get_recognizer_result (
376
- cls , utterance : str , response_file : str
377
- ) -> RecognizerResult :
378
- curr_dir = path .dirname (path .abspath (__file__ ))
379
- response_path = path .join (curr_dir , "test_data" , response_file )
380
-
381
- with open (response_path , "r" , encoding = "utf-8-sig" ) as f :
382
- response_str = f .read ()
383
- response_json = json .loads (response_str )
364
+ cls , utterance : str , response_file : str , bot_adapter : BotAdapter = TestAdapter ()
365
+ ) -> Tuple [LuisRecognizer , RecognizerResult ]:
366
+ response_json = LuisRecognizerTest ._get_json_for_file (response_file )
384
367
385
368
my_app = LuisApplication (
386
369
LuisRecognizerTest ._luisAppId ,
387
370
LuisRecognizerTest ._subscriptionKey ,
388
371
endpoint = "" ,
389
372
)
390
373
recognizer = LuisRecognizer (my_app , prediction_options = None )
391
- context = LuisRecognizerTest ._get_context (utterance )
374
+ context = LuisRecognizerTest ._get_context (utterance , bot_adapter )
392
375
response = Mock (spec = Response )
393
376
response .status_code = 200
394
377
response .headers = {}
@@ -399,7 +382,17 @@ def _get_recognizer_result(
399
382
return_value = response_json ,
400
383
):
401
384
result = recognizer .recognize (context )
402
- return result
385
+ return recognizer , result
386
+
387
+ @classmethod
388
+ def _get_json_for_file (cls , response_file : str) -> object :
389
+ curr_dir = path .dirname (path .abspath (__file__ ))
390
+ response_path = path .join (curr_dir , "test_data" , response_file )
391
+
392
+ with open (response_path , "r" , encoding = "utf-8-sig" ) as f :
393
+ response_str = f .read ()
394
+ response_json = json .loads (response_str )
395
+ return response_json
403
396
404
397
@classmethod
405
398
def _get_luis_recognizer (
@@ -409,13 +402,12 @@ def _get_luis_recognizer(
409
402
return LuisRecognizer (luis_app , options , verbose )
410
403
411
404
@staticmethod
412
- def _get_context (utterance : str ) -> TurnContext :
413
- test_adapter = TestAdapter ()
405
+ def _get_context (utterance : str , bot_adapter : BotAdapter ) -> TurnContext :
414
406
activity = Activity (
415
407
type = ActivityTypes .message ,
416
408
text = utterance ,
417
409
conversation = ConversationAccount (),
418
410
recipient = ChannelAccount (),
419
411
from_property = ChannelAccount (),
420
412
)
421
- return TurnContext (test_adapter , activity )
413
+ return TurnContext (bot_adapter , activity )
0 commit comments