def test_append_db_entry(self):

        content = 'Question'
        options = ['choice', 'not choice']

        choice1 = options[1]
        choice2 = options[0]
        choices = [choice1, choice2]

        db_key = 'out'
        self._db.create_key(db_key)
        self.assertTrue(db_key in self._db.get_keys())
        self.assertFalse(self._db.is_set(db_key))

        message = Message(
            content=content,
            options=options,
            message_type=Message.Type.MULTIPLE_CHOICE,
            result_db_key=db_key,
        )
        self._io.set_input(choices)
        self._interface.run(message)
        self._interface.run(message)

        self.assertTrue(db_key in self._db.get_keys())

        truth_out = choices
        out = self._db.create_key(db_key)
        for i in range(len(truth_out)):
            self.assertEqual(truth_out[i], out[i])
    def test_write_db_entry(self):

        content = 'Question'
        options = 'choice'
        choice = options

        db_key = 'out'
        message = Message(
            content=content,
            options=options,
            message_type=Message.Type.MULTIPLE_CHOICE,
            result_db_key=db_key,
        )
        self._io.set_input(choice)
        self.assertRaises(
            KeyError,
            self._interface.run,
            message,
        )

        self._db.create_key(db_key)
        self.assertTrue(db_key in self._db.get_keys())
        self.assertFalse(self._db.is_set(db_key))

        self._io.set_input(choice)
        self._interface.run(message)
        self.assertTrue(db_key in self._db.get_keys())
        self.assertEqual(choice, self._db[db_key])
    class Messages:

        no_sync = Message(
            content=(
                    "I haven't heard from your Fitbit in a while. " +
                    "Try syncing your phone, and then check back with me again."
            ),
            options=[
                "{affirmative_plus_button_response}",
                "{Ill_try_that_button_response}",
            ],
            message_type=Message.Type.MULTIPLE_CHOICE,
            text_populator=text_populator,
        )
        give_status = Message(
            content=(
                    "You've done {'db': '%s'} steps so far today. " % state_db.Keys.STEPS_TODAY +
                    "Think you can meet your goal of {'db': '%s'} steps before our checkin at {'db': '%s'}?"
                    % (state_db.Keys.STEPS_GOAL, state_db.Keys.PM_CHECKIN_TIME)
            ),
            options=[
                '{affirmative_plus_button_response}',
                '{affirmative_button_response}',
                "{Ill_try_that_button_response}",
                "I don't think that I can today"
            ],
            message_type=Message.Type.MULTIPLE_CHOICE,
            text_populator=text_populator,
        )

        give_status_met_goal = Message(
            content=(
                    "Your goal was {'db': '%s'} steps today and " % state_db.Keys.STEPS_GOAL +
                    "you've done {'db': '%s'} steps already. " % state_db.Keys.STEPS_TODAY +
                    "Nice job.  We'll review your total progress at our evening checkin at {'db': '%s'}."
                    % state_db.Keys.PM_CHECKIN_TIME
            ),
            options=[
                '{affirmative_button_response}',
            ],
            message_type=Message.Type.MULTIPLE_CHOICE,
            text_populator=text_populator,
        )
 def test_string_markup(self):
     greetings = ['Hi', 'Hello', 'Hola', "{'var': 'greeting'}"]
     message = Message(
         content='{greeting}',
         options=greetings,
         message_type=Message.Type.MULTIPLE_CHOICE,
         text_populator=self._text_populator
     )
     for _ in range(10):
         self.assertTrue(message.content in greetings)
         for o in message.options:
             self.assertTrue(o in greetings)
 class Messages:
     no_sync = Message(
         content=(
             "It's time for our evening checkin, but I haven't heard from your Fitbit in a while. " +
             "Try syncing your phone, and then check back with me again."
         ),
         options=[
             "{affirmative_plus_button_response}",
             "{Ill_try_that_button_response}",
         ],
         message_type=Message.Type.MULTIPLE_CHOICE,
         text_populator=text_populator,
     )
    def test_multiple_choice(self):

        content = 'Question'
        options = ['choice', 'not choice']
        choice = options[0]
        message = Message(
            content=content,
            options=options,
            message_type=Message.Type.MULTIPLE_CHOICE,
        )
        self._io.set_input(choice)
        self.assertIsNone(self._io.get_output())
        self.assertEqual(choice, self._interface.run(message))
        self.assertEqual(content, self._io.get_output())
    def test_confirm(self):

        content = 'Question'
        options = ['choice', 'not choice']
        choice = options[0]
        message = Message(
            content=content,
            options=options,
            message_type=Message.Type.MULTIPLE_CHOICE,
            is_confirm=True,
        )
        self._io.set_input([choice, 'Yes'])
        self._interface.run(message)
        out = self._io.get_output()
        truth_out = [content, f"'{str(choice)}', right?"]
        for i in range(len(truth_out)):
            self.assertEqual(truth_out[i], out[i])
    def test_function_markup(self):
        greetings_fn_return = ['Foo']
        message = Message(
            content=lambda: random.choice(greetings_fn_return),
            options=lambda: greetings_fn_return,
            message_type=Message.Type.MULTIPLE_CHOICE,
            text_populator=self._text_populator
        )
        greetings_fn_return = ['Hi', 'Hello', 'Hola', "{'var': 'greeting'}"]

        true_greetings = ['Hi', 'Hello', 'Hola']
        for _ in range(1):
            content = message.content
            self.assertTrue(content in true_greetings)
            options = message.options
            for o in options:
                self.assertTrue(o in true_greetings)
    def test_step_through_nodes(self) -> None:
        nodes_ = [node1, node2, node3]
        directed_graph = DirectedGraph(name='graph1',
                                       nodes=nodes_,
                                       start_node='node1')

        for _ in range(10):
            self.assertEqual(
                Message(**message_kwargs).content,
                directed_graph.get_message().content)

            for _ in range(10):
                self.assertTrue(directed_graph.is_active)
                directed_graph.transition(right_option())
                self.assertEqual(
                    node1.name,
                    directed_graph.current_node,
                )

            self.assertTrue(directed_graph.is_active)
            directed_graph.transition(left_option())

            for _ in range(10):
                directed_graph.transition(left_option())
                directed_graph.transition(left_option())
                self.assertEqual(
                    node2.name,
                    directed_graph.current_node,
                )
                self.assertTrue(directed_graph.is_active)

            directed_graph.transition(right_option())
            self.assertTrue(directed_graph.is_active)
            directed_graph.transition(left_option())
            self.assertFalse(directed_graph.is_active)

            for _ in range(10):
                self.assertRaises(RuntimeError, directed_graph.transition,
                                  left_option())
                self.assertIsNone(directed_graph.current_node)

            directed_graph.reset()
    def test_create_new_db_entry(self):

        content = 'Question'
        options = 'choice'
        choice = options

        db_key = 'out'
        self.assertFalse(db_key in self._db.get_keys())

        message = Message(
            content=content,
            options=options,
            message_type=Message.Type.MULTIPLE_CHOICE,
            result_db_key=db_key,
        )
        self._io.set_input(choice)
        self._interface._is_create_db_key_if_not_exist = True
        self._interface.run(message)

        self.assertTrue(db_key in self._db.get_keys())
        self.assertEqual(choice, self._db[db_key])
    def test_error_message(self):

        content = 'Question'
        options = ['choice', 'not choice']
        error_message = 'Error'
        error_options = 'Oops'
        choice = options[0]
        message = Message(
            content=content,
            options=options,
            message_type=Message.Type.MULTIPLE_CHOICE,
            error_message=error_message,
            error_options=error_options,
            tests=lambda x: x in options,
        )
        self._io.set_input([
            "invalid option", error_options, "invalid option", error_options,
            choice
        ])
        self._interface.run(message)
        out = self._io.get_output()
        truth_out = [content, error_message, content, error_message, content]
        for i in range(len(truth_out)):
            self.assertEqual(truth_out[i], out[i])
 class Messages:
     set_name = Message(
         content="What's your name?",
         options='Okay',
         args=['Your name'],
         message_type=Message.Type.DIRECT_INPUT,
         result_db_key=state_db.Keys.USER_NAME,
         result_convert_from_str_fn=str,
         tests=lambda x: len(x) > 1,
         error_message='Enter something with at least two letters',
         text_populator=text_populator,
     )
     confirm_name = Message(
         content="{transitional_statement} I'll call you {'db': '%s'} then." % state_db.Keys.USER_NAME,
         options='Okay',
         message_type=Message.Type.MULTIPLE_CHOICE,
         text_populator=text_populator,
     )
     set_am_checkin = Message(
         content="When would you like to checkin in the morning?",
         options='Okay',
         message_type=Message.Type.TIME_ENTRY,
         args=['15', '8:30'],
         result_db_key=state_db.Keys.AM_CHECKIN_TIME,
         result_convert_from_str_fn=lambda x: datetime.datetime.strptime(x, '%I:%M %p').time(),
         tests=lambda x: x.hour < 12,
         error_message="Please pick a time in the morning",
         is_confirm=False,
         text_populator=text_populator,
     )
     confirm_am_checkin = Message(
         content="{transitional_statement} See you for our morning checkin at {'db': '%s'} then." % state_db.Keys.AM_CHECKIN_TIME,
         options='Okay',
         message_type=Message.Type.MULTIPLE_CHOICE,
         text_populator=text_populator,
     )
     set_pm_checkin = Message(
         content="When should we checkin in the evening?",
         options='Okay',
         message_type=Message.Type.TIME_ENTRY,
         args=['15', '16:00'],
         result_db_key=state_db.Keys.PM_CHECKIN_TIME,
         result_convert_from_str_fn=lambda x: datetime.datetime.strptime(x, '%I:%M %p').time(),
         tests=lambda x: x.hour >= 12,
         error_message="Please pick a time after noon",
         is_confirm=False,
         text_populator=text_populator,
     )
     confirm_pm_checkin = Message(
         content="{transitional_statement} I'll see you for our evening checkin at {'db': '%s'} then." % state_db.Keys.PM_CHECKIN_TIME,
         options='Okay',
         message_type=Message.Type.MULTIPLE_CHOICE,
         text_populator=text_populator,
     )
     set_day_off = Message(
         content="Would you like a day off",
         options=['No', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
         message_type=Message.Type.MULTIPLE_CHOICE,
         result_db_key=state_db.Keys.DAY_OFF,
         text_populator=text_populator,
     )
     confirm_day_off = Message(
         content="{transitional_statement} I'll remember that your day off is {'db': '%s'}!" % state_db.Keys.DAY_OFF,
         options="Okay",
         message_type=Message.Type.MULTIPLE_CHOICE,
         text_populator=text_populator,
     )
from interaction_engine.planner.messanger_planner import MessagerPlanner
from interaction_engine.messager import Message

import unittest

m = Message(
    content='name',
    options='foo',
    message_type=Message.Type.MULTIPLE_CHOICE,
)


class TestMessagePlanner(unittest.TestCase):
    def test_get_names(self):

        possible_plans = [m]
        message_planner = MessagerPlanner(possible_plans)
        self.assertEqual([], message_planner.plan)
        message_planner.insert(m)
        message_planner.insert(m)
        message_planner.insert(m)
        self.assertEqual(['name'] * 3, message_planner.plan)

    def test_hooks(self):

        var = 0

        def set_var_fn(value):
            nonlocal var

            def fn():
Exemple #14
0
class FirstMeeting:
    class Messages:
        introduce_self = Message(
            content=
            ("*QT/hi*Nice to meet you, {'db': '%s'}. " %
             state_db.Keys.USER_NAME +
             "*QT/show_QT*My name is QT. I'm a robot made by LuxAI in Luxembourg, a country in Europe. "
             + "I'm going to try to help you walk more regularly. " +
             "I won't go on walks with you*wink*. " +
             "Instead, I'll ask you questions about your plans to walk and " +
             "keep track of your daily steps by wirelessly talking to your Fitbit watch. "
             ),
            message_type=Message.Type.MULTIPLE_CHOICE,
            text_populator=text_populator,
            options=['Sure thing!', 'Sure', 'No thanks'],
        )
        explain_checkin = Message(
            content=
            ("To help you walk regularly, *QT/bored* we'll talk at least twice a day: "
             + "once in the morning and once in the evening. " +
             "In the morning, we'll set a walking goal for the day and I'll ask you some questions. "
             +
             "These questions will be about your plans to walk or about you. "
             +
             "In the evening, we'll review the day. If you don't meet your walking goal, I may ask you why. "
             ),
            options='Sounds good',
            message_type=Message.Type.MULTIPLE_CHOICE,
            text_populator=text_populator,
        )
        explain_off_checkin = Message(
            content=(
                "You can also talk to me any other time. " +
                # "I'll be happy to see you. *nod* I can tell you jokes or tell you good things. " +
                # "You can ask me to introduce myself, if you'd like me to meet someone new. " +
                # "I can also explain how we'll work together again. " +
                "Lastly, you can change what I call you or when we have our morning and evening checkins. "
            ),
            options='Okay',
            message_type=Message.Type.MULTIPLE_CHOICE,
            text_populator=text_populator,
        )
        explain_fitbit = Message(
            content=
            ("Now, I'll tell you about how I'll work with your Fitbit watch. "
             + "This part is important.*nod* " +
             "To know how much you walk, I'll talk to your Fitbit watch. " +
             "Unfortunately, this can take some time. " +
             "Since I want to give you credit for all the steps you do, " +
             "please try to have your watch sync with the phone before our evening checkin. "
             + "Can you try to do that?"),
            options=['Definitely', 'Alright', "I'll try"],
            message_type=Message.Type.MULTIPLE_CHOICE,
            text_populator=text_populator,
        )

    first_meeting = DirectedGraph(
        name='first meeting',
        start_node='ask name',
        nodes=[
            Node(
                name='ask name',
                message=Options.Messages.set_name,
                options='Okay',
                transitions='introduce self',
            ),
            Node(name='introduce self',
                 message=Messages.introduce_self,
                 options=['Nice to meet you', 'Sounds great', 'Okay'],
                 transitions='can explain?'),
            Node(
                name='can explain?',
                content="Can I explain how we'll work together?",
                message_type=Message.Type.MULTIPLE_CHOICE,
                options=['Sure thing', 'Okay', 'No thanks'],
                transitions=[
                    'explain checkins', 'explain checkins', 'set am checkin'
                ],
                text_populator=text_populator,
            ),
            Node(
                name='explain checkins',
                message=Messages.explain_checkin,
                transitions='explain off-checkins',
            ),
            Node(
                name='explain off-checkins',
                message=Messages.explain_off_checkin,
                transitions='explain fitbit',
            ),
            Node(
                name='explain fitbit',
                message=Messages.explain_fitbit,
                transitions='set am checkin',
            ),
            Node(
                name='set am checkin',
                message=Options.Messages.set_am_checkin,
                transitions='confirm am checkin',
            ),
            Node(
                name='confirm am checkin',
                message=Options.Messages.confirm_am_checkin,
                options=[
                    '{affirmative_button_response}', '{oops_button_response}'
                ],
                transitions=['set pm checkin', 'set am checkin'],
            ),
            Node(
                name='set pm checkin',
                message=Options.Messages.set_pm_checkin,
                transitions='confirm pm checkin',
            ),
            Node(
                name='confirm pm checkin',
                message=Options.Messages.confirm_pm_checkin,
                options=[
                    '{affirmative_button_response}', '{oops_button_response}'
                ],
                transitions=['set steps goal', 'set pm checkin'],
            ),
            # THIS NODE IS SKIPPED
            Node(
                name='set day off',
                message=Options.Messages.set_day_off,
                transitions='set steps goal',
            ),
            Node(
                name='confirm day off',
                message=Options.Messages.confirm_day_off,
                options=[
                    '{affirmative_button_response}', '{oops_button_response}'
                ],
                transitions=['set steps goal', 'set day off'],
            ),
            # ---------------------
            Node(
                name='set steps goal',
                content=(
                    lambda:
                    "The last thing to do is to set walking goals for today. "
                    + "You did {'db': '%s'} steps last week. " % state_db.Keys.
                    STEPS_LAST_WEEK +
                    "To work towards the goal of %s steps in %s weeks, " %
                    (param_db.get(param_db.Keys.FINAL_STEPS_GOAL),
                     param_db.get(param_db.Keys.WEEKS_WITH_ROBOT)
                     ) + "I suggest that you do {'db': '%s'} steps today. " %
                    state_db.Keys.SUGGESTED_STEPS_TODAY +
                    "How many steps would you like to do today?"),
                options='steps',
                message_type=Message.Type.SLIDER,
                args=[
                    lambda: "{'db': '%s'}" % state_db.Keys.
                    MIN_SUGGESTED_STEPS_TODAY,
                    lambda: "{'db': '%s'}" % state_db.Keys.
                    MAX_SUGGESTED_STEPS_TODAY,
                    '1',
                    lambda: "{'db': '%s'}" % state_db.Keys.
                    SUGGESTED_STEPS_TODAY,
                ],
                result_convert_from_str_fn=int,
                result_db_key=state_db.Keys.STEPS_GOAL,
                tests=lambda x: x >= state_db.get(state_db.Keys.
                                                  MIN_SUGGESTED_STEPS_TODAY),
                error_message=
                "Please select a goal that is at least {'db': '%s'} steps" %
                state_db.Keys.MIN_SUGGESTED_STEPS_TODAY,
                text_populator=text_populator,
                transitions='set when walk',
            ),
            Node(
                name='set when walk',
                message=Message(
                    content="{when_question}",
                    options='is when',
                    message_type=Message.Type.TIME_ENTRY,
                    args=[
                        '15',
                        lambda: (datetime.datetime.now() + datetime.timedelta(
                            hours=1)).strftime("%H:%M"),
                    ],
                    result_db_key=state_db.Keys.WALK_TIME,
                    result_convert_from_str_fn=lambda x: datetime.datetime.
                    strptime(x, '%I:%M %p').time(),
                    tests=lambda x:
                    (state_db.get(state_db.Keys.AM_CHECKIN_TIME) <= x <=
                     state_db.get(state_db.Keys.PM_CHECKIN_TIME)),
                    error_message=
                    "Please pick a time after now and before our evening checkin",
                    text_populator=text_populator,
                ),
                transitions=['first closing'],
            ),
            Node(name='first closing',
                 content=("*QT/bye*Alright, we're all setup! " +
                          "I'll see you for checkin this evening!"),
                 message_type=Message.Type.MULTIPLE_CHOICE,
                 options=['Bye', 'Talk to you later'],
                 transitions='exit')
        ],
    )