def test_intent_resolver_as_arg(): # init dr = MyDialogRouter(timezone=timezone("Asia/Tokyo"), default_dialog_service=EchoDialogService, intent_resolver={ "PizzaIntent": PizzaDialogService, "SobaIntent": SobaDialogService, }) assert dr.timezone == timezone("Asia/Tokyo") assert dr.default_dialog_service is EchoDialogService # route context = Context("TEST", "test_user") request = Message(channel="TEST", channel_user_id="test_user", text="Hello", intent="PizzaIntent") assert dr.route(request, context, None) is PizzaDialogService context = Context("TEST", "test_user") request = Message(channel="TEST", channel_user_id="test_user", text="Hello", intent="SobaIntent") assert dr.route(request, context, None) is SobaDialogService context = Context("TEST", "test_user") request = Message(channel="TEST", channel_user_id="test_user", text="Hello") assert dr.route(request, context, None) is EchoDialogService
def test_set_error(): context = Context(channel="TEST", channel_user_id="user_id") try: 1 / 0 except Exception as ex: context.set_error(ex, info="this is test error") assert context.error["exception"] == "division by zero" assert "Traceback" in context.error["traceback"] assert context.error["info"] == "this is test error"
def test_handle_exception(): ds = MyDialog() context = Context("TEST", "test_user") request = Message(channel="TEST", channel_user_id="test_user", text="Hello") message = ds.handle_exception(request, context, ValueError("test error"), None) assert message.text == "?" assert context.error["exception"] == "test error"
def test_execute_error(): ds = ErrorDialogService(timezone=timezone("Asia/Tokyo")) performance = PerformanceInfo() context = Context("TEST", "test_user") context.topic.is_new = True request = Message(channel="TEST", channel_user_id="test_user", text="hello") response = ds.execute(request, context, None, performance) assert response.messages[0].text == "?"
def test_init(): context = Context(channel="TEST", channel_user_id="user_id") assert context.channel == "TEST" assert context.channel_user_id == "user_id" assert context.timestamp is None assert context.is_new is True assert isinstance(context.topic, Topic) assert context.data == {} assert context.error == {}
def test_handle_exception(): dr = MyDialogRouter(timezone=timezone("Asia/Tokyo"), default_dialog_service=EchoDialogService) context = Context("TEST", "test_user") request = Message(channel="TEST", channel_user_id="test_user", text="Hello") ds = dr.handle_exception(request, context, ValueError("test error"), None) assert isinstance(ds, ErrorDialogService) assert context.error["exception"] == "test error"
def test_execute_default(): ds = MyDialog() performance = PerformanceInfo() context = Context("TEST", "test_user") context.topic.is_new = True request = Message(channel="TEST", channel_user_id="test_user", text="hello") response = ds.execute(request, context, None, performance) assert response.messages == [] assert request.entities == {} assert context.data == {}
def test_extract_intent(): dr = DialogRouter(timezone=timezone("Asia/Tokyo")) context = Context("TEST", "test_user") request = Message(channel="TEST", channel_user_id="test_user", text="Hello") request.intent = "PizzaIntent" request.entities = {"key1": "value1"} intent, entities = dr.extract_intent(request, context, None) assert intent == "PizzaIntent" assert entities == {"key1": "value1"}
def test_save(datastore_class, connection_str): if not datastore_class: pytest.skip("Unable to import DataStoreSet") if not connection_str: pytest.skip( "Connection string for {} is not provided" .format(datastore_class.connection_provider.__name__)) cs = datastore_class.context_store( table_name=table_name, timezone=timezone("Asia/Tokyo")) with datastore_class.connection_provider(connection_str).get_connection() as connection: ctx = cs.get("TEST", user_id, connection) ctx.data["strvalue"] = "value1" ctx.data["intvalue"] = 2 ctx.data["dtvalue"] = now ctx.data["dictvalue"] = { "k1": "v1", "k2": 2, } cs.save(ctx, connection) ctx = cs.get("TEST", user_id, connection) assert ctx.channel == "TEST" assert ctx.channel_user_id == user_id assert ctx.is_new is False assert ctx.data == { "strvalue": "value1", "intvalue": 2, "dtvalue": now, "dictvalue": { "k1": "v1", "k2": 2, } } # save (not saved) cs.save(Context(), connection) # timeout cs_timeout = datastore_class.context_store( table_name=table_name, timezone=timezone("Asia/Tokyo"), timeout=3) with datastore_class.connection_provider(connection_str).get_connection() as connection: ctx = cs_timeout.get("TEST", user_id + "_to", connection) assert ctx.is_new is True ctx.data["strvalue"] = "value1" cs.save(ctx, connection) sleep(1) # shorter than timeout ctx = cs_timeout.get("TEST", user_id + "_to", connection) assert ctx.is_new is False assert ctx.data["strvalue"] == "value1" sleep(5) # longer than timeout ctx = cs_timeout.get("TEST", user_id + "_to", connection) assert ctx.is_new is True assert ctx.data == {}
def test_execute(): ds = PizzaDialogService(timezone=timezone("Asia/Tokyo")) performance = PerformanceInfo() # first contact context = Context("TEST", "test_user") context.topic.is_new = True request = Message(channel="TEST", channel_user_id="test_user", text="Give me pizza") response = ds.execute(request, context, None, performance) assert response.messages[0].text == "Which pizza?" assert request.entities == {"pizza_name": ""} assert context.data == { "pizza_name": "", "pizza_count": 0 } # say pizza name context.is_new = False context.topic.is_new = False request = Message(channel="TEST", channel_user_id="test_user", text="seafood pizza") response = ds.execute(request, context, None, performance) assert response.messages[0].text == "Your order is Seafood Pizza?" # confirmation request = Message(channel="TEST", channel_user_id="test_user", text="yes") response = ds.execute(request, context, None, performance) assert response.messages[0].text == "Thank you!" assert response.messages[1].text == "We will deliver Seafood Pizza in 30min." # raise error request = Message(channel="TEST", channel_user_id="test_user", text="error") response = ds.execute(request, context, None, performance) assert response.messages[0].text == "?" assert context.error["exception"] == "division by zero" # no response messages request = Message(channel="TEST", channel_user_id="test_user", text="no message") response = ds.execute(request, context, None, performance) assert response.messages == []
def test_from_dict(): context_dict = { "channel": "TEST", "channel_user_id": "user_id", "data": { "fruit": "Apple" }, "topic": { "name": "favorite_fruit", "status": "continue" } } context = Context.from_dict(context_dict) assert context.channel == "TEST" assert context.channel_user_id == "user_id" assert context.timestamp is None assert context.is_new is True assert context.topic.name == "favorite_fruit" assert context.topic.status == "continue" assert context.data == {"fruit": "Apple"} assert context.error == {}
def test_reset(): # setup context context = Context(channel="TEST", channel_user_id="user_id") context.data = {"fruit": "Apple"} context.topic.name = "favorite_fruit" context.topic.status = "continue" context.topic.keep_on = True # reset context.reset() assert context.topic.name == "favorite_fruit" assert context.topic.status == "continue" assert context.topic.previous.name == "favorite_fruit" assert context.topic.previous.status == "continue" assert context.data == {"fruit": "Apple"} # update context.topic.status = "finish" context.topic.keep_on = False # reset context.reset() assert context.topic.name == "" assert context.topic.status == "" assert context.topic.previous.name == "favorite_fruit" assert context.topic.previous.status == "finish" assert context.data == {}
def test_save(datastore_class, connection_str): if not datastore_class: pytest.skip("Unable to import DataStoreSet") if not connection_str: pytest.skip("Connection string for {} is not provided".format( datastore_class.connection_provider.__name__)) ms = datastore_class.messagelog_store(table_name=table_name, timezone=timezone("Asia/Tokyo")) with datastore_class.connection_provider( connection_str).get_connection() as connection: # request request = Message(id=str(date_to_unixtime(now)), channel="TEST", channel_user_id=user_id, text="request message {}".format( str(date_to_unixtime(now)))) # response response = Response(messages=[ Message(channel="TEST", channel_user_id=user_id, text="response message {}".format( str(date_to_unixtime(now)))) ]) # context context = Context("TEST", user_id) context.data = { "strvalue": "value1", "intvalue": 2, "dtvalue": date_to_str(now), "dictvalue": { "k1": "v1", "k2": 2, } } # save save_res = ms.save(request, response, context, connection) # check if AzureTableConnection and isinstance(connection, AzureTableConnection): record = connection.get_entity(table_name, user_id, save_res) elif SQLAlchemyConnection and isinstance(connection, SQLAlchemyConnection): record = connection.query(SQLAlchemyMessageLog).filter( SQLAlchemyMessageLog.request_id == str(date_to_unixtime( now))).first() record = dumpd(record) else: cursor = connection.cursor() if MySQLConnection and isinstance(connection, MySQLConnection): sql = "select * from {} where request_id = %s" else: sql = "select * from {} where request_id = ?" cursor.execute(sql.format(table_name), (str(date_to_unixtime(now)), )) row = cursor.fetchone() if isinstance(row, dict): record = row else: record = dict( zip([column[0] for column in cursor.description], row)) assert record["request_text"] == "request message {}".format( str(date_to_unixtime(now))) assert record["response_text"] == "response message {}".format( str(date_to_unixtime(now)))
def test_route(): # update topic dr = MyDialogRouter(timezone=timezone("Asia/Tokyo"), default_dialog_service=EchoDialogService) context = Context("TEST", "test_user") request = Message(channel="TEST", channel_user_id="test_user", text="Hello") request.intent = "PizzaIntent" ds = dr.route(request, context, None) assert ds is PizzaDialogService # adhoc topic context = Context("TEST", "test_user") request = Message(channel="TEST", channel_user_id="test_user", text="Hello") request.intent = "AdhocIntent" request.is_adhoc = True ds = dr.route(request, context, None) assert ds is AdhocDialogService assert context.topic.name == "" # adhoc topic (keep previous topic) context = Context("TEST", "test_user") context.topic.name = "pizza" request = Message(channel="TEST", channel_user_id="test_user", text="Hello") request.intent = "AdhocIntent" request.is_adhoc = True request.intent_priority = Priority.High ds = dr.route(request, context, None) assert ds is AdhocDialogService assert context.topic.name == "pizza" assert context.topic.keep_on is True # continue topic context = Context("TEST", "test_user") context.topic.name = "pizza" request = Message(channel="TEST", channel_user_id="test_user", text="Hello") ds = dr.route(request, context, None) assert ds is PizzaDialogService assert context.topic.priority == Priority.Normal # not updated by same priority request = Message(channel="TEST", channel_user_id="test_user", text="Hello") request.intent = "SobaIntent" ds = dr.route(request, context, None) assert ds is PizzaDialogService assert context.topic.priority == Priority.Normal # highest topic updated by highest intent context = Context("TEST", "test_user") request = Message(channel="TEST", channel_user_id="test_user", text="Hello") request.intent = "PizzaIntent" request.intent_priority = Priority.Highest ds = dr.route(request, context, None) assert ds is PizzaDialogService assert context.topic.priority == Priority.Highest - 1 # next message (not updated by lower than highest) request = Message(channel="TEST", channel_user_id="test_user", text="Hello") request.intent = "SobaIntent" request.intent_priority = Priority.Highest - 1 ds = dr.route(request, context, None) assert ds is PizzaDialogService assert context.topic.priority == Priority.Highest - 1 # last message (updated by highest) request = Message(channel="TEST", channel_user_id="test_user", text="Hello") request.intent = "SobaIntent" request.intent_priority = Priority.Highest ds = dr.route(request, context, None) assert ds is SobaDialogService assert context.topic.priority == Priority.Highest - 1 # no intent context = Context("TEST", "test_user") request = Message(channel="TEST", channel_user_id="test_user", text="Hello") ds = dr.route(request, context, None) assert ds is dr.default_dialog_service # unknown intent context = Context("TEST", "test_user") request = Message(channel="TEST", channel_user_id="test_user", text="Hello") request.intent = "UnknownIntent" ds = dr.route(request, context, None) assert ds is dr.default_dialog_service # dialog for intent not registered context = Context("TEST", "test_user") request = Message(channel="TEST", channel_user_id="test_user", text="Hello") request.intent = "NotRegisteredIntent" ds = dr.route(request, context, None) assert ds is DialogService # update topic by higher priority intent context = Context("TEST", "test_user") request = Message(channel="TEST", channel_user_id="test_user", text="Hello") request.intent = "PizzaIntent" ds = dr.route(request, context, None) assert ds is PizzaDialogService context.topic.keep_on = True # intent continue without intent request = Message(channel="TEST", channel_user_id="test_user", text="Hello") ds = dr.route(request, context, None) assert ds is PizzaDialogService context.topic.keep_on = True # soba intent with normal priority (not updated) request = Message(channel="TEST", channel_user_id="test_user", text="Hello") request.intent = "SobaIntent" ds = dr.route(request, context, None) assert ds is PizzaDialogService context.topic.keep_on = True # soba intent with higher priority (updated) request = Message(channel="TEST", channel_user_id="test_user", text="Hello") request.intent = "SobaIntent" request.intent_priority = Priority.High ds = dr.route(request, context, None) assert ds is SobaDialogService # update topic by normal priority intent context = Context("TEST", "test_user") request = Message(channel="TEST", channel_user_id="test_user", text="Hello") request.intent = "PizzaIntent" request.intent_priority = Priority.Low ds = dr.route(request, context, None) assert ds is PizzaDialogService context.topic.keep_on = True # intent continue without intent request = Message(channel="TEST", channel_user_id="test_user", text="Hello") ds = dr.route(request, context, None) assert ds is PizzaDialogService context.topic.keep_on = True # soba intent with normal priority (updated) request = Message(channel="TEST", channel_user_id="test_user", text="Hello") request.intent = "SobaIntent" ds = dr.route(request, context, None) assert ds is SobaDialogService
def test_execute(): dr = MyDialogRouter(timezone=timezone("Asia/Tokyo"), default_dialog_service=EchoDialogService) performance = PerformanceInfo() # default context = Context("TEST", "test_user") context.topic.is_new = True request = Message(channel="TEST", channel_user_id="test_user", text="Hello") ds = dr.execute(request, context, None, performance) assert isinstance(ds, dr.default_dialog_service) # pizza context = Context("TEST", "test_user") context.topic.is_new = True request = Message(channel="TEST", channel_user_id="test_user", text="give me pizza") ds = dr.execute(request, context, None, performance) assert isinstance(ds, PizzaDialogService) # continue pizza request = Message(channel="TEST", channel_user_id="test_user", text="seafood") ds = dr.execute(request, context, None, performance) assert isinstance(ds, PizzaDialogService) # soba lower priority (continume pizza) request = Message(channel="TEST", channel_user_id="test_user", text="lower") ds = dr.execute(request, context, None, performance) assert isinstance(ds, PizzaDialogService) # soba higher priority (update to soba) request = Message(channel="TEST", channel_user_id="test_user", text="give me soba") ds = dr.execute(request, context, None, performance) assert isinstance(ds, SobaDialogService) # pizza highest (update pizza) request = Message(channel="TEST", channel_user_id="test_user", text="highest p") ds = dr.execute(request, context, None, performance) assert isinstance(ds, PizzaDialogService) assert context.topic.priority == Priority.Highest - 1 # soba with high priority (continue pizza) request = Message(channel="TEST", channel_user_id="test_user", text="give me soba") ds = dr.execute(request, context, None, performance) assert isinstance(ds, PizzaDialogService) assert context.topic.priority == Priority.Highest - 1 # soba with highest priority (update soba) request = Message(channel="TEST", channel_user_id="test_user", text="highest s") ds = dr.execute(request, context, None, performance) assert isinstance(ds, SobaDialogService) # adhoc context = Context("TEST", "test_user") context.topic.is_new = True request = Message(channel="TEST", channel_user_id="test_user", text="pizza") # start pizza ds = dr.execute(request, context, None, performance) assert isinstance(ds, PizzaDialogService) request = Message(channel="TEST", channel_user_id="test_user", text="adhoc") # adhoc ds = dr.execute(request, context, None, performance) assert isinstance(ds, AdhocDialogService) request = Message(channel="TEST", channel_user_id="test_user", text="seafood") # continue pizza ds = dr.execute(request, context, None, performance) assert isinstance(ds, PizzaDialogService) # no intent context = Context("TEST", "test_user") context.topic.is_new = True request = Message(channel="TEST", channel_user_id="test_user", text="_") ds = dr.execute(request, context, None, performance) assert isinstance(ds, dr.default_dialog_service) # unknown context = Context("TEST", "test_user") context.topic.is_new = True request = Message(channel="TEST", channel_user_id="test_user", text="unknown") ds = dr.execute(request, context, None, performance) assert isinstance(ds, dr.default_dialog_service) # dialog for intent not registered context = Context("TEST", "test_user") context.topic.is_new = True request = Message(channel="TEST", channel_user_id="test_user", text="not_registered") ds = dr.execute(request, context, None, performance) assert isinstance(ds, DialogService) # error context = Context("TEST", "test_user") context.topic.is_new = True request = Message(channel="TEST", channel_user_id="test_user", text="error") ds = dr.execute(request, context, None, performance) assert isinstance(ds, ErrorDialogService)