async def invoke(handler: AnyFunc, request: Request) -> Response: """ Invoke intent handler: awaits the call if handler is a coroutine runs in executor if handler is a simple `def` @param handler: @param request: @return: """ with RequestContextVar(request=request): logger.debug( "Calling intent %s with handler: %s", repr(request.context.intent), repr(handler), ) if inspect.iscoroutinefunction(handler): response = await handler(request) else: loop = asyncio.get_running_loop() response = await loop.run_in_executor( ContextVarExecutor(), handler, request, ) if isinstance(response, str): response = Response(text=response) logger.debug("Intent call result: %s", repr(response)) return response
def test_response_repr(self): """ Test Response representation """ response = Response('Hola', RESPONSE_TYPE_ASK) self.assertEqual( "{'text': 'Hola', 'type_': 'ASK', 'card': None, " "'push_notification': None, 'result': {'data': {}, 'local': True}}", repr(response))
def test_dict_ask_deprecated(self, warn_mock): response = Response('abc123', RESPONSE_TYPE_ASK, ask_for=('location', 'CITY')).dict(self.ctx) self.assertNotIn('askForAttribute', response) warn_mock.assert_called_with('"ask_for" parameter is deprecated.', DeprecationWarning, stacklevel=2)
def test_response_returns_message(self): """ Test if context._ returns l10n.Message """ l10n.translations = {'de': l10n.Translations()} context = create_context('TELEKOM_Demo_Intent') with patch('random.randint', return_value=Response( text=context._('some text'))) as mock_gde: mock_gde.__name__ = 'mock_gde' intent = Intent('TELEKOM_Demo_Intent', random.randint) response = intent(context) self.assertIsInstance(response.text, l10n.Message)
def setUp(self): self.simple_response = Response("abc123", ResponseType.TELL) self.ask_response = Response("abc123", ResponseType.ASK) c = Card("SIMPLE", title_text="cardtitle", text="cardtext") self.card_response = Response( "abc123", ResponseType.TELL, card=c, result={"code": 22} ) self.ctx = create_context("TELEKOM_Clock_GetTime")
def test_message(self): response = Response(l10n.Message('{abc}123', 'KEY', abc='abc')).dict(self.ctx) self.assertEqual(response['text'], 'abc123') self.assertEqual(response['type'], 'TELL') self.assertEqual( response['result']['data'], { 'key': 'KEY', 'value': '{abc}123', 'args': (), 'kwargs': { 'abc': 'abc' } })
def setUp(self): self.simple_response = Response('abc123') self.ask_response = Response('abc123', RESPONSE_TYPE_ASK, ask_for=('location', 'CITY')) card = Card('SIMPLE', title='cardtitle', text='cardtext', token_id={'secret': 'token'}) self.card_response = Response('abc123', RESPONSE_TYPE_TELL, card=card, result={'code': 22}) session = {'attributes': {"key-1": "value-1", "key-2": "value-2"}} self.ctx = create_context("TELEKOM_Clock_GetTime", session=session)
class TestResponse(unittest.TestCase): def setUp(self): self.simple_response = Response('abc123') self.ask_response = Response('abc123', RESPONSE_TYPE_ASK, ask_for=('location', 'CITY')) card = Card('SIMPLE', title='cardtitle', text='cardtext', token_id={'secret': 'token'}) self.card_response = Response('abc123', RESPONSE_TYPE_TELL, card=card, result={'code': 22}) session = {'attributes': {"key-1": "value-1", "key-2": "value-2"}} self.ctx = create_context("TELEKOM_Clock_GetTime", session=session) def test_init_text(self): self.assertEqual(self.simple_response.text, 'abc123') self.assertEqual(self.simple_response.type_, RESPONSE_TYPE_TELL) def test_init_full(self): self.assertEqual(self.card_response.text, 'abc123') self.assertEqual(self.card_response.type_, RESPONSE_TYPE_TELL) self.assertEqual(self.card_response.card.data['title'], 'cardtitle') self.assertEqual(self.card_response.result['code'], 22) self.assertEqual(self.card_response.push_notification, None) def test_init_push_notification(self): self.simple_response.push_notification = {'device': [{'payload': 1}, {'payload': 2}]} response = self.simple_response.dict(self.ctx) self.assertEqual(response['text'], 'abc123') self.assertEqual(response['type'], 'TELL') self.assertEqual(response['pushNotification'], {'device': [{'payload': 1}, {'payload': 2}]}) def test_init_bad_type(self): with self.assertRaises(ValueError): Response('abc123', 'TEL') def test_dict_ask(self): response = self.ask_response.dict(self.ctx) self.assertEqual(response['text'], 'abc123') self.assertEqual(response['type'], 'ASK') @patch('skill_sdk.responses.warn') def test_dict_ask_deprecated(self, warn_mock): response = Response('abc123', RESPONSE_TYPE_ASK, ask_for=('location', 'CITY')).dict(self.ctx) self.assertNotIn('askForAttribute', response) warn_mock.assert_called_with('"ask_for" parameter is deprecated.', DeprecationWarning, stacklevel=2) def test_dict_simple(self): response = self.simple_response.dict(self.ctx) self.assertEqual(response['text'], 'abc123') self.assertEqual(response['type'], 'TELL') self.assertNotIn('pushNotification', response) def test_dict_card(self): response = self.card_response.dict(self.ctx) self.assertEqual(response['text'], 'abc123') self.assertEqual(response['type'], 'TELL') self.assertEqual(response['card']['data']['title'], 'cardtitle') self.assertEqual(response['result']['data']['code'], 22) self.assertEqual(response['card']['tokenId'], {'secret': 'token'}) @patch.object(Response, 'dict', return_value='{}') def test_response(self, dict_mock): response = self.simple_response.as_response(None) self.assertIsInstance(response, HTTPResponse) self.assertEqual(response.status_code, 200) def test_message(self): response = Response(l10n.Message('{abc}123', 'KEY', abc='abc')).dict(self.ctx) self.assertEqual(response['text'], 'abc123') self.assertEqual(response['type'], 'TELL') self.assertEqual(response['result']['data'], {'key': 'KEY', 'value': '{abc}123', 'args': (), 'kwargs': {'abc': 'abc'}}) def test_dict_simple_result_is_none(self): """ Make sure the optional fields are stripped off if empty """ response = self.simple_response.dict(self.ctx) self.assertEqual(response['session'], {'attributes': {'key-1': 'value-1', 'key-2': 'value-2'}}) self.assertNotIn('result', response) self.assertNotIn('card', response) self.assertNotIn('pushNotification', response) # For the coverage sake: request = SimpleNamespace() request.headers = {} request.json = { "context": { "attributes": {...}, "intent": "TELEKOM_Clock_GetTime", "locale": "de", "tokens": {}, "clientAttributes": {} }, "version": 1 } ctx = Context(request) self.assertNotIn('session', self.simple_response.dict(ctx)) def test_tell(self): """ Check if responses.tell returns Response(type_=RESPONSE_TYPE_TELL) """ r = tell('Hello') self.assertIsInstance(r, Response) self.assertEqual(r.type_, RESPONSE_TYPE_TELL) def test_ask(self): """ Check is responses.ask returns Response(type_=RESPONSE_TYPE_ASK) """ r = ask('Question') self.assertIsInstance(r, Response) self.assertEqual(r.type_, RESPONSE_TYPE_ASK) def test_ask_freetext(self): """ Check is responses.ask returns Response(type_=RESPONSE_TYPE_ASK_FREETEXT) """ r = ask_freetext('Question') self.assertIsInstance(r, Response) self.assertEqual(r.type_, RESPONSE_TYPE_ASK_FREETEXT) def test_reprompt_response(self): """ Test responses.Reprompt response """ self.assertIsInstance(Reprompt('abc123'), Response) response = Reprompt('abc123').dict(self.ctx) self.assertEqual(response['session']['attributes']['TELEKOM_Clock_GetTime_reprompt_count'], '1') self.assertEqual(response['text'], 'abc123') self.assertEqual(response['type'], 'ASK') with patch.dict(self.ctx.session, {'TELEKOM_Clock_GetTime_reprompt_count': '1'}): response = Reprompt('abc123').dict(self.ctx) self.assertEqual(response['session']['attributes']['TELEKOM_Clock_GetTime_reprompt_count'], '2') self.assertEqual(response['text'], 'abc123') self.assertEqual(response['type'], 'ASK') response = Reprompt('abc123', '321cba', 2).dict(self.ctx) self.assertNotIn('TELEKOM_Clock_GetTime_reprompt_count', response['session']['attributes']) self.assertEqual(response['text'], '321cba') self.assertEqual(response['type'], 'TELL') with patch.dict(self.ctx.session, {'TELEKOM_Clock_GetTime_reprompt_count': 'not a number'}): response = Reprompt('abc123').dict(self.ctx) self.assertEqual(response['session']['attributes']['TELEKOM_Clock_GetTime_reprompt_count'], '1') response = Reprompt('abc123', entity='Time').dict(self.ctx) self.assertEqual(response['session']['attributes']['TELEKOM_Clock_GetTime_reprompt_count'], '1') self.assertEqual(response['session']['attributes']['TELEKOM_Clock_GetTime_Time_reprompt_count'], '1') def test_response_repr(self): """ Test Response representation """ response = Response('Hola', RESPONSE_TYPE_ASK) self.assertEqual("{'text': 'Hola', 'type_': 'ASK', 'card': None, " "'push_notification': None, 'result': {'data': {}, 'local': True}}", repr(response))
def test_init_bad_type(self): with self.assertRaises(ValueError): Response('abc123', 'TEL')
class TestIntent(unittest.TestCase): def setUp(self): request = SimpleNamespace() request.json = { "context": { "attributes": {}, "intent": "TELEKOM_Demo_Intent", "locale": "de", "tokens": {} }, "session": { "new": True, "id": "12345", "attributes": { "key-1": "value-1", "key-2": "value-2" } }, } request.headers = {} self.ctx = Context(request) self.ctx.tracer = Tracer(request) @patch.object(logging.Logger, 'warning') def test_init_exceptions(self, warn_mock): with self.assertRaises(TypeError): Intent({}) with self.assertRaises(ValueError): Intent('', None) with self.assertRaises(ValueError): Intent('demo_intent', 'random.does_not_exist') @patch('random.randint', return_value=1) def test_call_bad_return_type(self, mock_gde): mock_gde.__name__ = 'mock_gde' intent = Intent('TELEKOM_Demo_Intent', random.randint) with self.assertRaises(ValueError): intent(self.ctx).dict(self.ctx) @patch('random.randint', return_value=ErrorResponse(999, 'some error')) def test_call_error_999(self, mock_gde): mock_gde.__name__ = 'mock_gde' intent = Intent('TELEKOM_Demo_Intent', random.randint) self.assertIsInstance(intent(self.ctx), ErrorResponse) @patch('random.randint', side_effect=RequestException()) def test_call_requests_error(self, mock_gde): mock_gde.__name__ = 'mock_gde' intent = Intent('TELEKOM_Demo_Intent', random.randint) response = intent(self.ctx) self.assertIsInstance(response, Response) self.assertEqual(response.text, 'GENERIC_HTTP_ERROR_RESPONSE') @patch('random.randint', side_effect=CircuitBreakerError(CircuitBreaker())) def test_call_circuit_breaker_open(self, mock_gde): mock_gde.__name__ = 'mock_gde' intent = Intent('TELEKOM_Demo_Intent', random.randint) response = intent(self.ctx) self.assertIsInstance(response, Response) self.assertEqual(response.text, 'GENERIC_HTTP_ERROR_RESPONSE') @patch('random.randint', return_value=Response(text='some text', type_=RESPONSE_TYPE_TELL)) def test_append_push_messages_empty(self, mock_gde): mock_gde.__name__ = 'mock_gde' context = create_context('TELEKOM_Demo_Intent') intent = Intent('TELEKOM_Demo_Intent', random.randint) response = intent(context) response = intent._append_push_messages(context, response) self.assertEqual(response.push_notification, None) @patch('random.randint', return_value=Response(text='some text', type_=RESPONSE_TYPE_TELL)) def test_append_push_messages_one(self, mock_gde): mock_gde.__name__ = 'mock_gde' context = create_context('TELEKOM_Demo_Intent') intent = Intent('TELEKOM_Demo_Intent', random.randint) response = intent(context) context.push_messages = {'device': [{'payload': 1}]} response = intent._append_push_messages(context, response) self.assertEqual(response.push_notification, { 'targetName': 'device', 'messagePayload': { 'payload': 1 } }) @patch('random.randint', return_value=Response(text='some text', type_=RESPONSE_TYPE_TELL)) def test_append_push_messages_two_messages(self, mock_gde): mock_gde.__name__ = 'mock_gde' context = create_context('TELEKOM_Demo_Intent') intent = Intent('TELEKOM_Demo_Intent', random.randint) response = intent(context) context.push_messages = {'device': [{'payload': 1}, {'payload': 2}]} with self.assertRaises(ValueError): _ = intent._append_push_messages(context, response) @patch('random.randint', return_value=Response(text='some text', type_=RESPONSE_TYPE_TELL)) def test_append_push_messages_two_devices(self, mock_gde): mock_gde.__name__ = 'mock_gde' context = create_context('TELEKOM_Demo_Intent') intent = Intent('TELEKOM_Demo_Intent', random.randint) response = intent(context) context.push_messages = { 'device': [{ 'payload': 1 }], 'device2': [{ 'payload': 2 }] } with self.assertRaises(ValueError): _ = intent._append_push_messages(context, response) def test_repr(self): self.assertIn('TELEKOM_Demo_Intent', repr(Intent('TELEKOM_Demo_Intent', random.randint))) def test_response_returns_message(self): """ Test if context._ returns l10n.Message """ l10n.translations = {'de': l10n.Translations()} context = create_context('TELEKOM_Demo_Intent') with patch('random.randint', return_value=Response( text=context._('some text'))) as mock_gde: mock_gde.__name__ = 'mock_gde' intent = Intent('TELEKOM_Demo_Intent', random.randint) response = intent(context) self.assertIsInstance(response.text, l10n.Message)
def test_init_bad_type(self): with self.assertRaises(ValueError): Response("abc123", "TEL")
class TestResponse(unittest.TestCase): def setUp(self): self.simple_response = Response("abc123", ResponseType.TELL) self.ask_response = Response("abc123", ResponseType.ASK) c = Card("SIMPLE", title_text="cardtitle", text="cardtext") self.card_response = Response( "abc123", ResponseType.TELL, card=c, result={"code": 22} ) self.ctx = create_context("TELEKOM_Clock_GetTime") def test_init_text(self): self.assertEqual(self.simple_response.text, "abc123") self.assertEqual(self.simple_response.type, "TELL") def test_init_full(self): self.assertEqual(self.card_response.text, "abc123") self.assertEqual(self.card_response.type, "TELL") self.assertEqual(self.card_response.card.title_text, "cardtitle") self.assertEqual(self.card_response.result.data["code"], 22) self.assertEqual(self.card_response.push_notification, None) def test_init_bad_type(self): with self.assertRaises(ValueError): Response("abc123", "TEL") def test_dict_ask(self): response = self.ask_response.dict() self.assertEqual("abc123", response["text"]) self.assertEqual("ASK", response["type"]) def test_dict_simple(self): response = self.simple_response.dict() self.assertEqual("abc123", response["text"]) self.assertEqual("TELL", response["type"]) self.assertNotIn("pushNotification", response) def test_dict_card(self): response = self.card_response.dict() self.assertEqual(response["text"], "abc123") self.assertEqual(response["type"], "TELL") self.assertEqual(response["card"]["data"]["titleText"], "cardtitle") self.assertEqual(response["result"]["data"]["code"], 22) def test_response_with_card(self): response = ( tell("Hola") .with_card( title_text="Title", text="Text", action=CardAction.INTERNAL_RESPONSE_TEXT, ) .dict() ) self.assertEqual( { "type": "TELL", "text": "Hola", "card": { "type": "GENERIC_DEFAULT", "version": 1, "data": { "titleText": "Title", "text": "Text", "action": "internal://showResponseText", }, }, }, response, ) def test_response_with_command(self): response = tell("Hola").with_command(AudioPlayer.play_stream("URL")).dict() self.assertEqual( { "text": "Hola", "type": "TELL", "result": { "data": { "use_kit": { "kit_name": "audio_player", "action": "play_stream", "parameters": {"url": "URL"}, } }, "local": True, }, }, response, ) def test_response_with_session(self): response = ask("Hola?").with_session( attr1="attr-1", attr2="attr-2", ) self.assertEqual( { "text": "Hola?", "type": "ASK", "session": {"attributes": {"attr1": "attr-1", "attr2": "attr-2"}}, }, response.dict(), ) with self.assertRaises(ValidationError): tell("Hola").with_session( attr1="attr-1", attr2="attr-2", ) def test_tell(self): r = tell("Hello") self.assertIsInstance(r, Response) self.assertEqual("TELL", r.type) def test_ask(self): r = ask("Question") self.assertIsInstance(r, Response) self.assertEqual("ASK", r.type) def test_ask_freetext(self): r = ask_freetext("Question") self.assertIsInstance(r, Response) self.assertEqual("ASK_FREETEXT", r.type) def test_init_push_notification(self): response = self.simple_response.with_notification( target_name="device", message_payload="payload" ).dict() self.assertEqual("abc123", response["text"]) self.assertEqual("TELL", response["type"]) self.assertEqual( {"messagePayload": "payload", "targetName": "device"}, response["pushNotification"], ) # # TODO: double check if this functionality requested by skills, remove if not needed # """