def test_intent_handler(self): # Test single decorator @intent_handler('Test_Intent') def decorated_test(date_str: str = None, date_date: datetime.date = None): return date_str, date_date ctx = create_context('Test_Intent', date_str=[ '2001-12-31', '2001-12-31', ], date_date=[ '2001-12-31', '1001-12-31', ]) result = decorated_test(ctx) self.assertEqual(result, ('2001-12-31', datetime.date(2001, 12, 31))) # Test stacked decorators @intent_handler('Test_Intent1') @intent_handler('Test_Intent2') @intent_handler('Test_Intent3') def decorated_test(date: datetime.date = None): return date ctx = create_context('Test_Intent1', date=['2001-12-31']) result = decorated_test(ctx) self.assertEqual(result, datetime.date(2001, 12, 31)) from skill_sdk.services.location import Location @intent_handler('Test_Intent4') def decorated_test(on_off: bool = False, date: datetime.date = None, location: Location = None): return f"It is {on_off} in {location.text} at {location.coordinates} on {date.strftime('%c')}" ctx = create_context('Test_Intent4', on_off=['Yes', 'No'], date=['2012-12-31', '2022-01-31'], location=['Berlin']) with requests_mock.Mocker() as req_mock: req_mock.get( 'http://*****:*****@intent_handler('Test_Intent4') def dummy(): pass
def run(): now = self.now.astimezone( datetime.timezone(datetime.timedelta(hours=1))) create_context("TELEKOM_Demo_Intent", timezone=['Europe/Berlin']) self.assertEqual( context.today().timestamp(), now.replace(hour=0, minute=0, tzinfo=None).timestamp()) self.assertEqual(context.now().timestamp(), self.now.timestamp())
def test_thread_local_now(self): next_day = datetime.datetime(year=2100, month=12, day=20, hour=0, minute=0) create_context("TELEKOM_Demo_Intent", timezone=['Europe/Athens']) self.assertEqual(context.today().timestamp(), next_day.timestamp()) self.assertEqual(context.now().timestamp(), self.now.timestamp())
def test_with_error_handler(self): """ Test conversion failure if error_handler supplied """ def error_handler(name, exception): return name, exception.value, str(exception.__cause__) @intent_handler(error_handler=error_handler) def date_test(context: Context, date: datetime.date): return None result = date_test(create_context('TEST_CONTEXT', date=['not a date'])) self.assertEqual( result, ('date', 'not a date', str(ValueError('Unknown string format: not a date')))) self.assertIsNone(date_test(create_context('TEST_CONTEXT', date=[])))
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)
def test_create_context_remove_none_values(self): """ Do not add "None" values to test context (https://gard.telekom.de/gard/browse/HMPOP-402) """ result = create_context('Test_Helper_Intent', none_value=None) self.assertEqual({'timezone': [ {'id': 0, 'value': 'Europe/Berlin', 'extras': {}, 'nestedIn': [], 'overlapsWith': []} ]}, result.attributesV2)
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)
def test_handler_context(self): @intent_handler def decorated_test(context: Context, timezone: str): return context, timezone ctx = create_context('TEST_CONTEXT') result = decorated_test(ctx) self.assertEqual(result, (ctx, 'Europe/Berlin'))
def test_stacked_decorators(self): import functools m = unittest.mock.MagicMock() @intent_handler @functools.lru_cache(2) def test(date: datetime.date): m(date) ctx = create_context('TEST_CONTEXT', date=['2012-12-12']) test(ctx) test(ctx) ctx = create_context('TEST_CONTEXT', date=['2012-12-14']) test(ctx) test(ctx) self.assertEqual(m.call_count, 2)
def test_handler_fail_silent(self): """ Test date conversion of invalid date in "silent" mode """ @intent_handler def date_test(context: Context, date: datetime.date): return date ctx = create_context('TEST_CONTEXT', date=['not a date']) result = date_test(ctx) self.assertIsInstance(result, intents.EntityValueException) @intent_handler def int_test(context: Context, integer: int): return integer ctx = create_context('TEST_CONTEXT', integer=['not a number']) result = int_test(ctx) self.assertIsInstance(result, intents.EntityValueException)
def test_handler_date_fail(self): """ Test date conversion of invalid date """ @intent_handler(False) def decorated_test(context: Context, date: datetime.date): return date ctx = create_context('TEST_CONTEXT', date=['not a date']) with self.assertRaises(intents.EntityValueException): result = decorated_test(ctx)
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_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_fallback_intent_invoke_response(self): """ Get response to FALLBACK_INTENT """ payload = test_helpers.create_context("UNKNOWN_INTENT", arg1=["arg1"], arg2=["arg2"]).request.json response = requests.post(SKILL_URL, json=payload) self.assertTrue(response.ok) self.assertEqual( response.json()['text'], f"Python Skill SDK v{__version__} Fallback Handler: " f"{{'arg1': ['arg1'], 'arg2': ['arg2'], 'timezone': ['Europe/Berlin']}}" )
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 } })
def test_handler_date_array(self): """ Check usage with date array """ @intent_handler def decorated_test(context: Context, date_arr: [datetime.date]): return date_arr ctx = create_context('TEST_CONTEXT', date_arr=[ '2001-12-31', '1001-12-31', ]) result = decorated_test(ctx) self.assertEqual( result, [datetime.date(2001, 12, 31), datetime.date(1001, 12, 31)])
def test_handler_array(self): """ Check simple usage with no conversion """ @intent_handler def decorated_test(context: Context, arr: List[str]): return arr ctx = create_context('TEST_CONTEXT', arr=[ '31-12-2001', '31-12-1001', ]) result = decorated_test(ctx) self.assertEqual(result, [ '31-12-2001', '31-12-1001', ])
def test_attributesV2_list_subtypes(self): """ Test conversion of List of AttributesV2 with subtypes """ attr_v2 = { "id": 1, "value": "123456", "nestedIn": [], "overlapsWith": [] } context = create_context('TEST_CONTEXT', attr=attr_v2) @intent_handler def attr_v2_test(attr: List[entities.AttributeV2[int]]): return attr result = attr_v2_test(context) self.assertEqual(result, [entities.AttributeV2(attr_v2, int)])
def test_handler_dates(self): """ Check handler usage with date conversion """ @intent_handler def decorated_test(context: Context, date_str: str = None, date_date: datetime.date = None): return date_str, date_date ctx = create_context('TEST_CONTEXT', date_str=[ '2001-12-31', '2001-12-31', ], date_date=[ '2001-12-31', '1001-12-31', ]) result = decorated_test(ctx) self.assertEqual(result, ('2001-12-31', datetime.date(2001, 12, 31)))
def test_tread_local_context(self, err_mock): session = {'attributes': {"key-1": "value-1", "key-2": "value-2"}} ctx = create_context("TELEKOM_Demo_Intent", session=session) context.set_current(None) self.assertIsNone(context.intent_name) err_mock.assert_called_with('Accessing context outside of request.') context.intent_name = 'NoMore_Demo_Intent' err_mock.assert_called_with('Accessing context outside of request.') ctx = Context(ctx.request) self.assertEqual(context.intent_name, 'TELEKOM_Demo_Intent') self.assertEqual(context.session, { "key-1": "value-1", "key-2": "value-2" }) self.assertEqual(context._('HELLO'), 'HELLO') self.assertEqual(context._n('HELLO', 'HOLA', 1), 'HELLO') self.assertEqual(context._a('HELLO'), ['HELLO']) context.intent_name = 'NoMore_Demo_Intent' self.assertEqual(context.intent_name, 'NoMore_Demo_Intent')
def test_create_context(self): """ Test `create_context` helper and `test_context` manager """ from skill_sdk.intents import context attr_v2 = dict(id=1, value='value', extras={}, nestedIn=[], overlapsWith=[]) result = create_context('Test_Helper_Intent', attr=attr_v2, session={'id': '12345', 'new': False}) self.assertEqual('Test_Helper_Intent', context.intent_name) self.assertEqual({'attr': ['value'], 'timezone': ['Europe/Berlin']}, result.attributes) self.assertEqual(attr_v2, result.attributesV2['attr'][0]) with test_context('Another_Test_Helper_Intent', attribute=['value']): self.assertEqual('Another_Test_Helper_Intent', context.intent_name) with test_context('Third_Test_Helper_Intent', attribute='value'): self.assertEqual('Third_Test_Helper_Intent', context.intent_name) self.assertEqual('Another_Test_Helper_Intent', context.intent_name) self.assertEqual('Test_Helper_Intent', context.intent_name)
def test_push_message(self): device = Device('some_device') context = create_context('DEMO_INTENT') device.send_push_message(context, {'a': 1}) self.assertEqual(context.push_messages['some_device'], [{'a': 1}])
class TestPersistenceService(unittest.TestCase): ctx = create_context('INTENT') @requests_mock.mock() def test_persistence_get(self, mocker): mocker.get(PERSISTENCE_URL + '/data', text=skillData) service = PersistenceService() result = service.get() self.assertIsInstance(result, Hasher) self.assertEqual(result, {'attrs': { 'attr1': 'value1', 'attr2': 'value2' }}) @requests_mock.mock() def test_persistence_get_invalid_data(self, mocker): mocker.get(PERSISTENCE_URL + '/data', text=skillData[:50]) service = PersistenceService() with self.assertLogs(logger, level="ERROR"): result = service.get() self.assertFalse(result) @requests_mock.mock() def test_persistence_get_not_authorized(self, mocker): mocker.get(PERSISTENCE_URL + '/data', text='Not Authorized', status_code=401) service = PersistenceService() with self.assertLogs(logger, level="ERROR"): result = service.get() self.assertFalse(result) @requests_mock.mock() def test_persistence_get_response_timeout(self, mocker): mocker.get(PERSISTENCE_URL + '/data', exc=requests.exceptions.ConnectTimeout) service = PersistenceService() with self.assertLogs(logger, level="ERROR"): result = service.get() self.assertFalse(result) @requests_mock.mock() def test_persistence_get_all(self, mocker): mocker.get(PERSISTENCE_URL, text=allSkillData) service = PersistenceService() result = service.get_all() self.assertIsInstance(result, Hasher) self.assertEqual( result, {'data': { 'attrs': { 'attr1': 'value1', 'attr2': 'value2' } }}) @requests_mock.mock() def test_persistence_get_all_invalid_data(self, mocker): mocker.get(PERSISTENCE_URL, text=skillData[:50]) service = PersistenceService() with self.assertLogs(logger, level="ERROR"): result = service.get_all() self.assertFalse(result) @requests_mock.mock() def test_persistence_get_all_request_exception(self, mocker): mocker.get(PERSISTENCE_URL, exc=requests.exceptions.RequestException) service = PersistenceService() with self.assertLogs(logger, level="ERROR"): result = service.get_all() self.assertFalse(result) @requests_mock.mock() def test_persistence_set(self, mocker): import json mocker.post(PERSISTENCE_URL, text=setResponse) service = PersistenceService() result = service.set(json.loads(skillData)) self.assertIsInstance(result, requests.Response) self.assertEqual(result.json()['data'], json.loads(skillData)) @requests_mock.mock() def test_persistence_set_wrong_order(self, mocker): import json mocker.post(PERSISTENCE_URL, text=setResponse) service = PersistenceService() result = service.set({"attr1": "value1", "attr2": "value2"}) self.assertIsInstance(result, requests.Response) self.assertEqual(result.json()['data'], json.loads(skillData)) @requests_mock.mock() def test_persistence_set_fail(self, mocker): mocker.post(PERSISTENCE_URL, exc=requests.exceptions.ConnectTimeout) service = PersistenceService() with self.assertLogs(logger, level="ERROR"): result = service.set(skillData) self.assertEqual(result, None) @requests_mock.mock() def test_persistence_delete(self, mocker): mocker.delete(PERSISTENCE_URL, text="[]") service = PersistenceService() result = service.delete() self.assertIsInstance(result, requests.Response) @requests_mock.mock() def test_persistence_delete_fail(self, mocker): mocker.delete(PERSISTENCE_URL, exc=requests.exceptions.ConnectTimeout) service = PersistenceService() with self.assertLogs(logger, level="ERROR"): result = service.delete() self.assertEqual(result, None)
class TestNotificationService(unittest.TestCase): ctx = create_context('INTENT') @requests_mock.mock() def test_persistence_get(self, mocker): mocker.get(SERVICE_URL_PROVIDER, text=all_notifications) service = NotificationService() result = service.get() self.assertIsInstance(result, Dict) self.assertEqual( result, { '45e37e4b-4b2c-42a6-9e3c-21c973f40e0d': Notification(add_up_text='CALLHISTORY_NOTIFICATION_TEXT', provider='telephony', mode='push_soft', valid_by=datetime.datetime( 9999, 12, 31, 23, 59, 59, 999999), provider_enabler_setting=None, read=False, id='45e37e4b-4b2c-42a6-9e3c-21c973f40e0d'), 'ca1d8fbc-9ce9-4146-9234-fc6a57422319': Notification(add_up_text='CALLHISTORY_NOTIFICATION_TEXT', provider='telephony', mode='push_soft', valid_by=datetime.datetime( 9999, 12, 31, 23, 59, 59, 999999), provider_enabler_setting=None, read=True, id='ca1d8fbc-9ce9-4146-9234-fc6a57422319') }) @requests_mock.mock() def test_persistence_get_invalid_data(self, mocker): mocker.get(SERVICE_URL_PROVIDER, text=all_notifications[:50]) with self.assertLogs(logger, level="ERROR"): with self.assertRaises(MalformedResponseException): result = NotificationService().get() @requests_mock.mock() def test_persistence_get_not_authorized(self, mocker): mocker.get(SERVICE_URL_PROVIDER, text='Not Authorized', status_code=401) with self.assertLogs(logger, level="ERROR"): with self.assertRaises(requests.exceptions.RequestException): NotificationService().get() @requests_mock.mock() def test_persistence_get_response_timeout(self, mocker): mocker.get(SERVICE_URL_PROVIDER, exc=requests.exceptions.ConnectTimeout) with self.assertLogs(logger, level="ERROR"): with self.assertRaises(requests.exceptions.RequestException): NotificationService().get() @requests_mock.mock() def test_persistence_add(self, mocker): mocker.post(SERVICE_URL, text=notification) result = Notification(add_up_text='HELLO').add() self.assertEqual( result, {'45e37e4b-4b2c-42a6-9e3c-21c973f40e0d': json.loads(notification)}) @requests_mock.mock() def test_persistence_add_fail(self, mocker): mocker.post(SERVICE_URL, exc=requests.exceptions.ConnectTimeout) with self.assertLogs(logger, level="ERROR"): with self.assertRaises(requests.exceptions.ConnectTimeout): NotificationService().add(Notification(add_up_text='HELLO')) mocker.post(SERVICE_URL, text=notification[10:]) with self.assertLogs(logger, level="ERROR"): with self.assertRaises(MalformedResponseException): NotificationService().add(Notification(add_up_text='HELLO')) @requests_mock.mock() def test_persistence_mark_read(self, mocker): mocker.patch(SERVICE_URL_ITEM, text="[]") n = Notification(add_up_text='HELLO', id=str(UUID_ZERO)) result = n.mark_as_read() self.assertIsInstance(result, requests.Response) @requests_mock.mock() def test_persistence_mark_read_fail(self, mocker): mocker.patch(SERVICE_URL_ITEM, exc=requests.exceptions.ConnectTimeout) service = NotificationService() with self.assertLogs(logger, level="ERROR"): with self.assertRaises(requests.exceptions.ConnectTimeout): result = service.mark_as_read(UUID_ZERO) self.assertEqual(result, {}) @requests_mock.mock() def test_persistence_delete(self, mocker): mocker.delete(SERVICE_URL_ITEM, text="[]") n = Notification(add_up_text='HELLO', id=str(UUID_ZERO)) result = n.delete() self.assertIsInstance(result, requests.Response) @requests_mock.mock() def test_persistence_delete_all(self, mocker): mocker.delete(SERVICE_URL_PROVIDER, text="[]") result = NotificationService().delete() self.assertIsInstance(result, requests.Response) self.assertEqual(result.status_code, 200) @requests_mock.mock() def test_persistence_delete_fail(self, mocker): mocker.delete(SERVICE_URL_ITEM, exc=requests.exceptions.ConnectTimeout) service = NotificationService() with self.assertLogs(logger, level="ERROR"): with self.assertRaises(requests.exceptions.ConnectTimeout): result = service.delete(UUID_ZERO) self.assertEqual(result, {})
def test_no_translations(self): from unittest import mock with mock.patch('skill_sdk.l10n.logger') as fake_log: self.ctx = create_context('TELEKOM_Clock_GetTime', locale='fr') fake_log.error.assert_called_with( 'A translation for locale %s is not available.', 'fr')
def setUp(self): configuration = {'a': ['123'], 'b': [1, 2, 3]} session = {'attributes': {"key-1": "value-1", "key-2": "value-2"}} self.ctx = create_context('TELEKOM_Clock_GetTime', configuration=configuration, session=session)
class TestAttributesV2(unittest.TestCase): attr_v2 = {"id": 1, "value": "value", "nestedIn": [], "overlapsWith": []} context = create_context('TEST_CONTEXT', attr=attr_v2) def test_attributesV2(self): """ Test conversions to AttributesV2 """ @intent_handler def attr_v2_test(attr: entities.AttributeV2): return attr self.assertEqual(attr_v2_test(self.context), entities.AttributeV2(self.attr_v2)) def test_attributesV2_list(self): """ Test conversions to List of AttributesV2 """ @intent_handler def attr_v2_test(attr: [entities.AttributeV2]): return attr[0] self.assertEqual(attr_v2_test(self.context), entities.AttributeV2(self.attr_v2)) @intent_handler def attr_v2_test(attr: List[entities.AttributeV2]): return attr[0] self.assertEqual(attr_v2_test(self.context), entities.AttributeV2(self.attr_v2)) def test_attributesV2_subtypes(self): """ Test conversions of AttributesV2 with subtypes """ attr_v2 = { "id": 1, "value": "123456", "nestedIn": [], "overlapsWith": [] } context = create_context('TEST_CONTEXT', attr=attr_v2) @intent_handler def attr_v2_test(attr: entities.AttributeV2[int]): return attr self.assertEqual(attr_v2_test(context), entities.AttributeV2(attr_v2, int)) def test_attributesV2_list_subtypes(self): """ Test conversion of List of AttributesV2 with subtypes """ attr_v2 = { "id": 1, "value": "123456", "nestedIn": [], "overlapsWith": [] } context = create_context('TEST_CONTEXT', attr=attr_v2) @intent_handler def attr_v2_test(attr: List[entities.AttributeV2[int]]): return attr result = attr_v2_test(context) self.assertEqual(result, [entities.AttributeV2(attr_v2, int)])