コード例 #1
0
    def test_run_dialog(self):
        """Test run_dialog properly handle order states"""

        states = 'idle', 'size_picked', 'payment_picked'
        handler_names = 'handle_idle', 'handle_size_pick', 'handle_payment_pick'

        matrix = [
            (1, 0, 0),
            (1, 1, 0),
            (1, 1, 1),
        ]
        self.bot.get_value = M()
        self.bot.start_dialog(self.dialog)
        order, machine = self.bot.dialogs[self.dialog]

        # Patch handlers
        mocks = []
        for handler_name in handler_names:
            m = M()
            mocks.append(m)
            setattr(self.bot, handler_name, m)

        # Do Checks for each of them
        for method, state, calls in zip(mocks, states, matrix):
            self.bot.get_value.return_value = value = object()
            order.state = state
            self.bot.run_dialog(self.dialog)
            self.assertEqual(method.call_args_list,
                             [call(self.dialog, order, value)])
            self.assertEqual(calls, tuple(m.call_count for m in mocks))
コード例 #2
0
 def test_get_value(self):
     self.bot.variants = {
         'state_1': {
             'kkz': 'l',
             'mfp': 'n'
         },
         'state_2': {
             'aek': 'b',
             'chv': 'd'
         }
     }
     dialog = self.dialog
     order = M()
     order.state = 'state_1'
     self.bot.dialogs[dialog] = order, M()
     '''
     None input - returns None
     Invalid(at all) input - returns INVALID
     Invalid(depending on state) input - returns INVALID
     Valid input - returns matching variant
     Valid(wrong case) input - returns matching variant
     '''
     asserts = {
         None: None,
         'dfkFFhk': self.bot.INVALID,
         'aek': self.bot.INVALID,
         'kkz': 'l',
         'MFP': 'n',
     }
     for inp, out in asserts.items():
         with self.subTest('Test get_value for input {}'.format(inp)):
             dialog.get_input.return_value = inp
             rv = self.bot.get_value(dialog)
             self.assertEqual(order.state, 'state_1')
             self.assertEqual(out, rv)
コード例 #3
0
 def test_handle_size_pick(self):
     '''
     invalid - send_message, send_variants
     valid - set_payment, send_message
     '''
     dialog = self.dialog
     positive_input = 3463
     self.bot.send_variants = send_variants = M()
     order = M()
     order.size_description = 'kkkk'
     order.payment_description = 'fffffff'
     args = dict(pizza_size=order.size_description,
                 payment_type=order.payment_description)
     mocks = dialog.send_message, send_variants, order.set_payment
     asserts = {
         self.bot.INVALID: [[call(self.bot.messages.get('pick_payment'))],
                            [call(dialog)], []],
         positive_input:
         [[call(self.bot.messages.get('confirm_pick').format(**args))], [],
          [call(positive_input)]],
     }
     for chat_input, expected in asserts.items():
         for mock in mocks:
             mock.reset_mock()
         with self.subTest(
                 'Test handle_size_pick against {}'.format(chat_input)):
             self.bot.handle_size_pick(dialog, order, chat_input)
             for mock, value in zip(mocks, expected):
                 self.assertEqual(mock.call_args_list, value)
コード例 #4
0
    def test_handle_idle(self):
        order = M()
        self.bot.send_variants = send_variants = M()
        dialog = self.dialog
        positive_input = 12345
        mocks = dialog.send_message, send_variants, order.set_size
        ignore = object()
        pick_size_call = call(self.bot.messages.get('pick_size'))
        pick_payment_call = call(self.bot.messages.get('pick_payment'))
        asserts = {
            # dialog.send_message, send_variants, order.set_size
            None: [[pick_size_call], [], []],
            self.bot.INVALID: [[pick_size_call], [call(self.dialog)], []],
            positive_input: [[pick_payment_call], [],
                             [call.set_size(positive_input)]],
        }

        for chat_input, expected in asserts.items():
            for mock in mocks:
                mock.reset_mock()
            with self.subTest(
                    'Test handle_idle against {}'.format(chat_input)):
                self.bot.handle_idle(dialog, order, chat_input)
                for mock, value in zip(mocks, expected):
                    self.assertEqual(mock.call_args_list, value)
コード例 #5
0
 def test_handle_payment_pick(self):
     '''
     invalid - send_message,send_variants
     valid - confirm, start_dialog, send_message
     valid(is_confirmed) - confirm, send_message, create_order, start_dialog, send_message
     '''
     dialog = self.dialog
     positive_input = 3463
     positive_input_2 = 5683
     self.bot.send_variants = send_variants = M()
     self.bot.start_dialog = start_dialog = M()
     order = M()
     order.size_description = 'afks'
     order.payment_description = 'fjdrt5'
     args = dict(pizza_size=order.size_description,
                 payment_type=order.payment_description)
     mocks = dialog.send_message, send_variants, order.confirm,\
             self.bot_manager.create_order, start_dialog
     # TODO: Complete test case
     asserts = {
         self.bot.INVALID: [
             [call(self.bot.messages.get('confirm_pick').format(**args))],
             [call(dialog)],
             [],
             [],
             [],
         ],
         positive_input: [
             [call(self.bot.messages.get('pick_size'))],
             [],
             [call(positive_input)],
             [],
             [call(dialog)],
         ],
         positive_input_2: [
             [
                 call(self.bot.messages.get('success')),
                 call(self.bot.messages.get('pick_size'))
             ],
             [],
             [call(positive_input_2)],
             [call(dialog, order)],
             [call(dialog)],
         ],
     }
     for chat_input, expected in asserts.items():
         for mock in mocks:
             mock.reset_mock()
         with self.subTest(
                 'Test handle_payment_pick against {}'.format(chat_input)):
             order.is_confirmed = chat_input == positive_input_2
             self.bot.handle_payment_pick(dialog, order, chat_input)
             for mock, value in zip(mocks, expected):
                 self.assertEqual(mock.call_args_list, value)
コード例 #6
0
 def test_process_update(self):
     mocker = M()
     update = mocker.update
     chat = object()
     message = object()
     mocker.time.return_value = time_value = object()
     time_patch = patch('pizza_bot.telegram_chat.time.time',
                        new=mocker.time)
     time_patch.start()
     asserts = {
         'fails on wrong message': {
             'message': None,
             'chat': None,
             'exc': TypeError('Update with empty message')
         },
         'fails on wrong chat': {
             'message': M(text=object(), chat_id=chat),
             'chat': object(),
             'exc': TypeError('Chat integrity error')
         },
         'succeeds with chat assigned': {
             'message': M(text=message, chat_id=chat),
             'chat': None,
             'exc': None
         },
         'succeeds without chat assigned': {
             'message': M(text=message, chat_id=chat),
             'chat': chat,
             'exc': None
         },
     }
     for title, case in asserts.items():
         with self.subTest('Test process_update {}'.format(title)):
             mocker.reset_mock()
             update.message = case['message']
             self.dialog.chat = case['chat']
             self.dialog.message = None
             self.dialog.last_received = None
             if case['exc']:
                 with self.assertRaises(TypeError) as cm:
                     self.dialog.process_update(update)
                 self.assertEqual(cm.exception.args, case['exc'].args)
             else:
                 self.dialog.process_update(update)
                 self.assertEqual(chat, self.dialog.chat)
                 self.assertEqual(message, self.dialog.message)
                 self.assertEqual(time_value, self.dialog.last_received)
                 if case['chat'] is None:
                     self.assertIs(chat, self.dialog.chat)
     time_patch.stop()
コード例 #7
0
 def test_create_order(self):
     dialog = M()
     order = M()
     order.pizza_size = 'hsdfh'
     order.payment_method = 'fdgjjfg'
     order.is_confirmed = 'serhs'
     expected_output = ('Order created:\n'
                        '\tPizza size: {}\n'
                        '\tPayment type: {}\n'
                        '\tOrder confirmed: {}\n'
                        '\n').format(order.pizza_size, order.payment_method,
                                     order.is_confirmed)
     with patch('sys.stdout', new_callable=io.StringIO) as cm:
         self.manager.create_order(dialog, order)
     output = cm.getvalue()
     self.assertEqual(output, expected_output)
コード例 #8
0
    def test_send_variants(self):
        self.bot.variants = {
            's': {
                'k': 'l',
                'm': 'n'
            },
            'p': {
                'a': 'b',
                'c': 'd'
            }
        }
        order, machine = M(), M()
        order.state = 's'
        self.bot.messages = {'please_repeat': 'hhh{variants}ooo'}
        self.bot.dialogs[self.dialog] = order, machine

        self.bot.send_variants(self.dialog)

        assert self.dialog.send_message.call_args_list == [call('hhhk, mooo')]
コード例 #9
0
    def test_on_chat_start(self):
        mock = M()
        self.bot.start_dialog = mock.start_dialog
        self.bot.run_dialog = mock.run_dialog

        self.bot.on_chat_start(self.dialog)

        assert mock.method_calls == [
            call.start_dialog(self.dialog),
            call.run_dialog(self.dialog),
        ]
コード例 #10
0
    def test_on_chat_exit(self):
        self.bot.log = log = M()
        self.bot.delete_dialog = delete_dialog = M()

        with self.subTest('Test on_chat_exit fails'):
            self.bot.on_chat_exit(self.dialog)

            # Assert
            assert log.call_args_list == [
                call('Exit received from wrong dialog: {}'.format(self.dialog))
            ]
            assert delete_dialog.call_count == 0

        # Reset
        log.reset_mock(), delete_dialog.reset_mock()
        self.bot.dialogs[self.dialog] = M(), M()

        with self.subTest('Test on_chat_exit passes'):
            self.bot.on_chat_exit(self.dialog)

            # Assert
            assert log.call_count == 0
            assert delete_dialog.call_args_list == [call(self.dialog)]
コード例 #11
0
    def test_on_chat_input(self):
        self.bot.log = log = M()
        self.bot.run_dialog = run_dialog = M()

        with self.subTest('Test on_chat_input fails'):
            self.bot.on_chat_input(self.dialog)

            # Assert
            assert log.call_args_list == [
                call('Input received from wrong dialog: {}'.format(
                    self.dialog))
            ]
            assert run_dialog.call_count == 0

        # Reset
        log.reset_mock(), run_dialog.reset_mock()
        self.bot.dialogs[self.dialog] = M(), M()

        with self.subTest('Test on_chat_input passes'):
            self.bot.on_chat_input(self.dialog)

            # Assert
            assert log.call_count == 0
            assert run_dialog.call_args_list == [call(self.dialog)]
コード例 #12
0
 def test_run_chat(self):
     '''
     fails on on_chat_start with exception logged, and on_chat_exit
     passes with: run_chat_cycle called in loop and on_chat_exit called after
     '''
     type_err = TypeError()
     mocker = M()
     self.bot.on_chat_start = mocker.on_chat_start
     self.bot.on_chat_exit = mocker.on_chat_exit
     self.dialog.run_chat_cycle = mocker.run_chat_cycle
     mocker.run_chat_cycle.side_effect = [True, True, False]
     asserts = {
         'fail on on_chat_start': {
             'fails':
             True,
             'calls': [
                 call.on_chat_start(self.dialog),
                 call.logging.exception(type_err),
                 call.on_chat_exit(self.dialog),
             ]
         },
         'succeeds': {
             'fails':
             False,
             'calls': [
                 call.on_chat_start(self.dialog),
                 call.run_chat_cycle(),
                 call.run_chat_cycle(),
                 call.run_chat_cycle(),
                 call.on_chat_exit(self.dialog),
             ]
         },
     }
     with patch('pizza_bot.console_chat.logging', new=mocker.logging):
         for title, case in asserts.items():
             mocker.reset_mock()
             with self.subTest('Test run_chat {}'.format(title)):
                 mocker.on_chat_start.side_effect = type_err if case[
                     'fails'] else None
                 self.dialog.run_chat()
                 self.assertListEqual(mocker.method_calls, case['calls'])
コード例 #13
0
 def test_process_messages(self):
     mocker = M()
     self.dialog.reinit_chat = mocker.reinit_chat
     messages = 'abc def ghi'.split()
     last_message = messages[-1]
     output = '\n{}\n'.format('\n'.join(messages[:-1]))
     asserts = {
         'process_messages with reinit': {
             'no_messages':
             True,
             'calls': [
                 call.logging.error('No messages for sending!!!'),
                 call.reinit_chat(),
             ]
         },
         'regular process_messages': {
             'no_messages': False,
             'calls': []
         }
     }
     extend = lambda: self.dialog.messages.extend(messages)
     with patch('pizza_bot.console_chat.logging', new=mocker.logging):
         for title, case in asserts.items():
             mocker.reset_mock()
             self.dialog.messages = []
             if case['no_messages']:
                 mocker.reinit_chat.side_effect = extend
             else:
                 extend()
             with self.subTest('Test {} call'.format(title)),\
                     patch('sys.stdout', new_callable=io.StringIO) as cm:
                 rv = self.dialog.process_messages()
                 self.assertEqual(rv, messages[-1])
                 self.assertListEqual(mocker.method_calls, case['calls'])
                 self.assertListEqual(self.dialog.messages, [])
                 self.assertEqual(cm.getvalue(), output)
コード例 #14
0
    def test_run_chat_cycle(self):
        input_value = object()
        mocker = M()

        self.dialog.process_messages = mocker.process_messages
        self.dialog.reinit_chat = mocker.reinit_chat
        self.bot.on_chat_input = mocker.on_chat_input

        mocker.process_messages.return_value = last_message = 'sjstrjstj'
        type_err = TypeError()

        asserts = {
            'fails': {
                'return_value':
                False,
                'input':
                False,
                'on_chat_input':
                False,
                'calls': [
                    call.process_messages(),
                    call.input('{}:\n'.format(last_message)),
                ],
            },
            'succeeds with chat reinit': {
                'return_value':
                True,
                'input':
                True,
                'on_chat_input':
                True,
                'calls': [
                    call.process_messages(),
                    call.input('{}:\n'.format(last_message)),
                    call.on_chat_input(self.dialog),
                    call.logging.exception(type_err),
                    call.reinit_chat(),
                ],
            },
            'succeeds': {
                'return_value':
                True,
                'input':
                True,
                'on_chat_input':
                False,
                'calls': [
                    call.process_messages(),
                    call.input('{}:\n'.format(last_message)),
                    call.on_chat_input(self.dialog),
                ],
            },
        }
        with patch('pizza_bot.console_chat.logging', new=mocker.logging),\
                patch('builtins.input', new=mocker.input):
            for title, case in asserts.items():
                mocker.reset_mock()
                with self.subTest('Test run_chat_cycle {}'.format(title)):
                    mocker.on_chat_input.side_effect = type_err if case[
                        'on_chat_input'] else None
                    mocker.input.return_value = input_value if case[
                        'input'] else None
                    mocker.input.side_effect = None if case[
                        'input'] else KeyboardInterrupt
                    with patch('builtins.input', new=mocker.input):
                        rv = self.dialog.run_chat_cycle()
                    self.assertListEqual(mocker.method_calls, case['calls'])
                    self.assertEqual(case['return_value'], rv)
コード例 #15
0
 def setUp(self):
     self.bot = M()
     self.maxDiff = None
     self.dialog = ConsoleDialog(self.bot)
コード例 #16
0
 def test_delete_dialog(self):
     it = M()
     self.bot.dialogs[it] = it
     self.bot.delete_dialog(it)
     assert it not in self.bot.dialogs
コード例 #17
0
 def setUp(self):
     self.bot = M()
     self.dialog = TelegramDialog(self.bot)
コード例 #18
0
 def setUp(self):
     self.bot_manager = M()
     self.dialog = M()
     self.bot = PizzaBot(self.bot_manager)