def test_error_handler(self): class CallbackContext(object): error = "error msg" self.assertIsNone(error_callback(Update("0"), CallbackContext()))
def callback_query(bot): return Update(0, callback_query=CallbackQuery(2, User(1, '', False), None, data='test data'))
def false_update(request): return Update(update_id=2, **request.param)
class TestDispatcher(object): message_update = Update(1, message=Message(1, User(1, '', False), None, Chat(1, ''), text='Text')) received = None count = 0 @pytest.fixture(autouse=True, name='reset') def reset_fixture(self): self.reset() def reset(self): self.received = None self.count = 0 def error_handler(self, bot, update, error): self.received = error.message def error_handler_raise_error(self, bot, update, error): raise Exception('Failing bigly') def callback_increase_count(self, bot, update): self.count += 1 def callback_set_count(self, count): def callback(bot, update): self.count = count return callback def callback_raise_error(self, bot, update): raise TelegramError(update.message.text) def callback_if_not_update_queue(self, bot, update, update_queue=None): if update_queue is not None: self.received = update.message def callback_context(self, update, context): if (isinstance(context, CallbackContext) and isinstance(context.bot, Bot) and isinstance(context.update_queue, Queue) and isinstance(context.job_queue, JobQueue) and isinstance(context.error, TelegramError)): self.received = context.error.message def test_one_context_per_update(self, cdp): def one(update, context): if update.message.text == 'test': context.my_flag = True def two(update, context): if update.message.text == 'test': if not hasattr(context, 'my_flag'): pytest.fail() else: if hasattr(context, 'my_flag'): pytest.fail() cdp.add_handler(MessageHandler(Filters.regex('test'), one), group=1) cdp.add_handler(MessageHandler(None, two), group=2) u = Update(1, Message(1, None, None, None, text='test')) cdp.process_update(u) u.message.text = 'something' cdp.process_update(u) def test_error_handler(self, dp): dp.add_error_handler(self.error_handler) error = TelegramError('Unauthorized.') dp.update_queue.put(error) sleep(.1) assert self.received == 'Unauthorized.' # Remove handler dp.remove_error_handler(self.error_handler) self.reset() dp.update_queue.put(error) sleep(.1) assert self.received is None def test_construction_with_bad_persistence(self, caplog, bot): class my_per: def __init__(self): self.store_user_data = False self.store_chat_data = False self.store_bot_data = False with pytest.raises( TypeError, match= 'persistence should be based on telegram.ext.BasePersistence'): Dispatcher(bot, None, persistence=my_per()) def test_error_handler_that_raises_errors(self, dp): """ Make sure that errors raised in error handlers don't break the main loop of the dispatcher """ handler_raise_error = MessageHandler(Filters.all, self.callback_raise_error) handler_increase_count = MessageHandler(Filters.all, self.callback_increase_count) error = TelegramError('Unauthorized.') dp.add_error_handler(self.error_handler_raise_error) # From errors caused by handlers dp.add_handler(handler_raise_error) dp.update_queue.put(self.message_update) sleep(.1) # From errors in the update_queue dp.remove_handler(handler_raise_error) dp.add_handler(handler_increase_count) dp.update_queue.put(error) dp.update_queue.put(self.message_update) sleep(.1) assert self.count == 1 def test_run_async_multiple(self, bot, dp, dp2): def get_dispatcher_name(q): q.put(current_thread().name) q1 = Queue() q2 = Queue() dp.run_async(get_dispatcher_name, q1) dp2.run_async(get_dispatcher_name, q2) sleep(.1) name1 = q1.get() name2 = q2.get() assert name1 != name2 def test_multiple_run_async_decorator(self, dp, dp2): # Make sure we got two dispatchers and that they are not the same assert isinstance(dp, Dispatcher) assert isinstance(dp2, Dispatcher) assert dp is not dp2 @run_async def must_raise_runtime_error(): pass with pytest.raises(RuntimeError): must_raise_runtime_error() def test_run_async_with_args(self, dp): dp.add_handler( MessageHandler(Filters.all, run_async(self.callback_if_not_update_queue), pass_update_queue=True)) dp.update_queue.put(self.message_update) sleep(.1) assert self.received == self.message_update.message def test_error_in_handler(self, dp): dp.add_handler(MessageHandler(Filters.all, self.callback_raise_error)) dp.add_error_handler(self.error_handler) dp.update_queue.put(self.message_update) sleep(.1) assert self.received == self.message_update.message.text def test_add_remove_handler(self, dp): handler = MessageHandler(Filters.all, self.callback_increase_count) dp.add_handler(handler) dp.update_queue.put(self.message_update) sleep(.1) assert self.count == 1 dp.remove_handler(handler) dp.update_queue.put(self.message_update) assert self.count == 1 def test_add_remove_handler_non_default_group(self, dp): handler = MessageHandler(Filters.all, self.callback_increase_count) dp.add_handler(handler, group=2) with pytest.raises(KeyError): dp.remove_handler(handler) dp.remove_handler(handler, group=2) def test_error_start_twice(self, dp): assert dp.running dp.start() def test_handler_order_in_group(self, dp): dp.add_handler( MessageHandler(Filters.photo, self.callback_set_count(1))) dp.add_handler(MessageHandler(Filters.all, self.callback_set_count(2))) dp.add_handler(MessageHandler(Filters.text, self.callback_set_count(3))) dp.update_queue.put(self.message_update) sleep(.1) assert self.count == 2 def test_groups(self, dp): dp.add_handler( MessageHandler(Filters.all, self.callback_increase_count)) dp.add_handler(MessageHandler(Filters.all, self.callback_increase_count), group=2) dp.add_handler(MessageHandler(Filters.all, self.callback_increase_count), group=-1) dp.update_queue.put(self.message_update) sleep(.1) assert self.count == 3 def test_add_handler_errors(self, dp): handler = 'not a handler' with pytest.raises(TypeError, match='handler is not an instance of'): dp.add_handler(handler) handler = MessageHandler(Filters.photo, self.callback_set_count(1)) with pytest.raises(TypeError, match='group is not int'): dp.add_handler(handler, 'one') def test_flow_stop(self, dp, bot): passed = [] def start1(b, u): passed.append('start1') raise DispatcherHandlerStop def start2(b, u): passed.append('start2') def start3(b, u): passed.append('start3') def error(b, u, e): passed.append('error') passed.append(e) update = Update(1, message=Message(1, None, None, None, text='/start', entities=[ MessageEntity( type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) ], bot=bot)) # If Stop raised handlers in other groups should not be called. passed = [] dp.add_handler(CommandHandler('start', start1), 1) dp.add_handler(CommandHandler('start', start3), 1) dp.add_handler(CommandHandler('start', start2), 2) dp.process_update(update) assert passed == ['start1'] def test_exception_in_handler(self, dp, bot): passed = [] err = Exception('General exception') def start1(b, u): passed.append('start1') raise err def start2(b, u): passed.append('start2') def start3(b, u): passed.append('start3') def error(b, u, e): passed.append('error') passed.append(e) update = Update(1, message=Message(1, None, None, None, text='/start', entities=[ MessageEntity( type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) ], bot=bot)) # If an unhandled exception was caught, no further handlers from the same group should be # called. Also, the error handler should be called and receive the exception passed = [] dp.add_handler(CommandHandler('start', start1), 1) dp.add_handler(CommandHandler('start', start2), 1) dp.add_handler(CommandHandler('start', start3), 2) dp.add_error_handler(error) dp.process_update(update) assert passed == ['start1', 'error', err, 'start3'] def test_telegram_error_in_handler(self, dp, bot): passed = [] err = TelegramError('Telegram error') def start1(b, u): passed.append('start1') raise err def start2(b, u): passed.append('start2') def start3(b, u): passed.append('start3') def error(b, u, e): passed.append('error') passed.append(e) update = Update(1, message=Message(1, None, None, None, text='/start', entities=[ MessageEntity( type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) ], bot=bot)) # If a TelegramException was caught, an error handler should be called and no further # handlers from the same group should be called. dp.add_handler(CommandHandler('start', start1), 1) dp.add_handler(CommandHandler('start', start2), 1) dp.add_handler(CommandHandler('start', start3), 2) dp.add_error_handler(error) dp.process_update(update) assert passed == ['start1', 'error', err, 'start3'] assert passed[2] is err def test_error_while_saving_chat_data(self, dp, bot): increment = [] class OwnPersistence(BasePersistence): def __init__(self): super(BasePersistence, self).__init__() self.store_user_data = True self.store_chat_data = True self.store_bot_data = True def get_bot_data(self): return dict() def update_bot_data(self, data): raise Exception def get_chat_data(self): return defaultdict(dict) def update_chat_data(self, chat_id, data): raise Exception def get_user_data(self): return defaultdict(dict) def update_user_data(self, user_id, data): raise Exception def start1(b, u): pass def error(b, u, e): increment.append("error") # If updating a user_data or chat_data from a persistence object throws an error, # the error handler should catch it update = Update(1, message=Message(1, User(1, "Test", False), None, Chat(1, "lala"), text='/start', entities=[ MessageEntity( type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) ], bot=bot)) my_persistence = OwnPersistence() dp = Dispatcher(bot, None, persistence=my_persistence) dp.add_handler(CommandHandler('start', start1)) dp.add_error_handler(error) dp.process_update(update) assert increment == ["error", "error", "error"] def test_flow_stop_in_error_handler(self, dp, bot): passed = [] err = TelegramError('Telegram error') def start1(b, u): passed.append('start1') raise err def start2(b, u): passed.append('start2') def start3(b, u): passed.append('start3') def error(b, u, e): passed.append('error') passed.append(e) raise DispatcherHandlerStop update = Update(1, message=Message(1, None, None, None, text='/start', entities=[ MessageEntity( type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) ], bot=bot)) # If a TelegramException was caught, an error handler should be called and no further # handlers from the same group should be called. dp.add_handler(CommandHandler('start', start1), 1) dp.add_handler(CommandHandler('start', start2), 1) dp.add_handler(CommandHandler('start', start3), 2) dp.add_error_handler(error) dp.process_update(update) assert passed == ['start1', 'error', err] assert passed[2] is err def test_error_handler_context(self, cdp): cdp.add_error_handler(self.callback_context) error = TelegramError('Unauthorized.') cdp.update_queue.put(error) sleep(.1) assert self.received == 'Unauthorized.' def test_sensible_worker_thread_names(self, dp2): thread_names = [ thread.name for thread in getattr(dp2, '_Dispatcher__async_threads') ] print(thread_names) for thread_name in thread_names: assert thread_name.startswith("Bot:{}:worker:".format(dp2.bot.id)) @pytest.mark.skipif(sys.version_info < (3, 0), reason='pytest fails this for no reason') def test_non_context_deprecation(self, dp): with pytest.warns(TelegramDeprecationWarning): Dispatcher(dp.bot, dp.update_queue, job_queue=dp.job_queue, workers=0, use_context=False)
def update(): return Update( 0, Message(0, User(0, 'Testuser', False), datetime.datetime.utcnow(), Chat(0, 'private')))
def check_rise_fall_day(context: CallbackContext) -> NoReturn: chat_data = context.job.context.dispatcher.chat_data datetime_now = datetime.now() date_now = datetime_now.date() datetime_zero = datetime.fromtimestamp(0) for c_id, cd in chat_data.items(): stonks = cd.get(conf.INTERNALS['stock'], {}) chat_custom = Chat(c_id, 'group') message_custom = Message(0, datetime_now, chat=chat_custom) update_custom = Update(0, message=message_custom) msg_daily = get_daily_dict(cd) daily_rise = msg_daily[conf.JOBS['check_rise_fall_day']['dict'] ['rise']] daily_fall = msg_daily[conf.JOBS['check_rise_fall_day']['dict'] ['fall']] for symbol, stonk in stonks.items(): msg_last_rise_at = daily_rise.get(symbol, datetime_zero).date() msg_last_fall_at = daily_fall.get(symbol, datetime_zero).date() context.args = [symbol] if msg_last_rise_at == date_now and msg_last_fall_at == date_now: continue res_calc = stonk.calculate_perf_rise_fall_daily() to_send_message = [] if res_calc: if stonk.daily_rise.calculated_at.date( ) == date_now and msg_last_rise_at < date_now: if stonk.daily_rise.percent >= conf.JOBS[ 'check_rise_fall_day']['threshold_perc_rise']: text = f"🚀🚀🚀 {stonk.name} ({stonk.symbol}) is rocketing to " \ f"{round_currency_scalar(stonk.daily_rise.price)} " \ f"{conf.LOCAL['currency']} (+{stonk.daily_rise.percent.round(2)}%)" to_send_message.append(text) daily_rise[symbol] = datetime_now if stonk.daily_fall.calculated_at.date( ) == date_now and msg_last_fall_at < date_now: if stonk.daily_fall.percent <= conf.JOBS[ 'check_rise_fall_day']['threshold_perc_fall']: text = f"📉📉📉 {stonk.name} ({stonk.symbol}) is drow" \ f"ning to {round_currency_scalar(stonk.daily_fall.price)} " \ f"{conf.LOCAL['currency']} ({stonk.daily_fall.percent.round(2)}%)" to_send_message.append(text) daily_fall[symbol] = datetime_now for message in to_send_message: try: send_message(context, c_id, message) chart(update_custom, context, reply=False, symbols=[stonk.symbol]) except error.Unauthorized: error_message = f'Rise/Fall check: User ID {c_id} blocked our bot. Thus, this user was will ' \ f'be removed from chat_data.' error_handler(update_custom, context, error_message) del context.job.context.dispatcher.chat_data[c_id] break
def update(): _update = Update(0) _update.message = Message(0, 0, datetime.utcnow(), Chat(0, 0)) return _update
class TestDispatcher(object): message_update = Update(1, message=Message(1, User(1, '', False), None, Chat(1, ''), text='Text')) received = None count = 0 @pytest.fixture(autouse=True) def reset(self): self.received = None self.count = 0 def error_handler(self, bot, update, error): self.received = error.message def error_handler_raise_error(self, bot, update, error): raise Exception('Failing bigly') def callback_increase_count(self, bot, update): self.count += 1 def callback_set_count(self, count): def callback(bot, update): self.count = count return callback def callback_raise_error(self, bot, update): raise TelegramError(update.message.text) def callback_if_not_update_queue(self, bot, update, update_queue=None): if update_queue is not None: self.received = update.message def callback_context(self, update, context): if (isinstance(context, CallbackContext) and isinstance(context.bot, Bot) and isinstance(context.update_queue, Queue) and isinstance(context.job_queue, JobQueue) and isinstance(context.error, TelegramError)): self.received = context.error.message def test_error_handler(self, dp): dp.add_error_handler(self.error_handler) error = TelegramError('Unauthorized.') dp.update_queue.put(error) sleep(.1) assert self.received == 'Unauthorized.' # Remove handler dp.remove_error_handler(self.error_handler) self.reset() dp.update_queue.put(error) sleep(.1) assert self.received is None def test_error_handler_that_raises_errors(self, dp): """ Make sure that errors raised in error handlers don't break the main loop of the dispatcher """ handler_raise_error = MessageHandler(Filters.all, self.callback_raise_error) handler_increase_count = MessageHandler(Filters.all, self.callback_increase_count) error = TelegramError('Unauthorized.') dp.add_error_handler(self.error_handler_raise_error) # From errors caused by handlers dp.add_handler(handler_raise_error) dp.update_queue.put(self.message_update) sleep(.1) # From errors in the update_queue dp.remove_handler(handler_raise_error) dp.add_handler(handler_increase_count) dp.update_queue.put(error) dp.update_queue.put(self.message_update) sleep(.1) assert self.count == 1 def test_run_async_multiple(self, bot, dp, dp2): def get_dispatcher_name(q): q.put(current_thread().name) q1 = Queue() q2 = Queue() dp.run_async(get_dispatcher_name, q1) dp2.run_async(get_dispatcher_name, q2) sleep(.1) name1 = q1.get() name2 = q2.get() assert name1 != name2 def test_multiple_run_async_decorator(self, dp, dp2): # Make sure we got two dispatchers and that they are not the same assert isinstance(dp, Dispatcher) assert isinstance(dp2, Dispatcher) assert dp is not dp2 @run_async def must_raise_runtime_error(): pass with pytest.raises(RuntimeError): must_raise_runtime_error() def test_run_async_with_args(self, dp): dp.add_handler(MessageHandler(Filters.all, run_async(self.callback_if_not_update_queue), pass_update_queue=True)) dp.update_queue.put(self.message_update) sleep(.1) assert self.received == self.message_update.message def test_error_in_handler(self, dp): dp.add_handler(MessageHandler(Filters.all, self.callback_raise_error)) dp.add_error_handler(self.error_handler) dp.update_queue.put(self.message_update) sleep(.1) assert self.received == self.message_update.message.text def test_add_remove_handler(self, dp): handler = MessageHandler(Filters.all, self.callback_increase_count) dp.add_handler(handler) dp.update_queue.put(self.message_update) sleep(.1) assert self.count == 1 dp.remove_handler(handler) dp.update_queue.put(self.message_update) assert self.count == 1 def test_add_remove_handler_non_default_group(self, dp): handler = MessageHandler(Filters.all, self.callback_increase_count) dp.add_handler(handler, group=2) with pytest.raises(KeyError): dp.remove_handler(handler) dp.remove_handler(handler, group=2) def test_error_start_twice(self, dp): assert dp.running dp.start() def test_handler_order_in_group(self, dp): dp.add_handler(MessageHandler(Filters.photo, self.callback_set_count(1))) dp.add_handler(MessageHandler(Filters.all, self.callback_set_count(2))) dp.add_handler(MessageHandler(Filters.text, self.callback_set_count(3))) dp.update_queue.put(self.message_update) sleep(.1) assert self.count == 2 def test_groups(self, dp): dp.add_handler(MessageHandler(Filters.all, self.callback_increase_count)) dp.add_handler(MessageHandler(Filters.all, self.callback_increase_count), group=2) dp.add_handler(MessageHandler(Filters.all, self.callback_increase_count), group=-1) dp.update_queue.put(self.message_update) sleep(.1) assert self.count == 3 def test_add_handler_errors(self, dp): handler = 'not a handler' with pytest.raises(TypeError, match='handler is not an instance of'): dp.add_handler(handler) handler = MessageHandler(Filters.photo, self.callback_set_count(1)) with pytest.raises(TypeError, match='group is not int'): dp.add_handler(handler, 'one') def test_flow_stop(self, dp, bot): passed = [] def start1(b, u): passed.append('start1') raise DispatcherHandlerStop def start2(b, u): passed.append('start2') def start3(b, u): passed.append('start3') def error(b, u, e): passed.append('error') passed.append(e) update = Update(1, message=Message(1, None, None, None, text='/start', bot=bot)) # If Stop raised handlers in other groups should not be called. passed = [] dp.add_handler(CommandHandler('start', start1), 1) dp.add_handler(CommandHandler('start', start3), 1) dp.add_handler(CommandHandler('start', start2), 2) dp.process_update(update) assert passed == ['start1'] def test_exception_in_handler(self, dp, bot): passed = [] def start1(b, u): passed.append('start1') raise Exception('General exception') def start2(b, u): passed.append('start2') def start3(b, u): passed.append('start3') def error(b, u, e): passed.append('error') passed.append(e) update = Update(1, message=Message(1, None, None, None, text='/start', bot=bot)) # If an unhandled exception was caught, no further handlers from the same group should be # called. passed = [] dp.add_handler(CommandHandler('start', start1), 1) dp.add_handler(CommandHandler('start', start2), 1) dp.add_handler(CommandHandler('start', start3), 2) dp.add_error_handler(error) dp.process_update(update) assert passed == ['start1', 'start3'] def test_telegram_error_in_handler(self, dp, bot): passed = [] err = TelegramError('Telegram error') def start1(b, u): passed.append('start1') raise err def start2(b, u): passed.append('start2') def start3(b, u): passed.append('start3') def error(b, u, e): passed.append('error') passed.append(e) update = Update(1, message=Message(1, None, None, None, text='/start', bot=bot)) # If a TelegramException was caught, an error handler should be called and no further # handlers from the same group should be called. dp.add_handler(CommandHandler('start', start1), 1) dp.add_handler(CommandHandler('start', start2), 1) dp.add_handler(CommandHandler('start', start3), 2) dp.add_error_handler(error) dp.process_update(update) assert passed == ['start1', 'error', err, 'start3'] assert passed[2] is err def test_flow_stop_in_error_handler(self, dp, bot): passed = [] err = TelegramError('Telegram error') def start1(b, u): passed.append('start1') raise err def start2(b, u): passed.append('start2') def start3(b, u): passed.append('start3') def error(b, u, e): passed.append('error') passed.append(e) raise DispatcherHandlerStop update = Update(1, message=Message(1, None, None, None, text='/start', bot=bot)) # If a TelegramException was caught, an error handler should be called and no further # handlers from the same group should be called. dp.add_handler(CommandHandler('start', start1), 1) dp.add_handler(CommandHandler('start', start2), 1) dp.add_handler(CommandHandler('start', start3), 2) dp.add_error_handler(error) dp.process_update(update) assert passed == ['start1', 'error', err] assert passed[2] is err def test_error_handler_context(self, cdp): cdp.add_error_handler(self.callback_context) error = TelegramError('Unauthorized.') cdp.update_queue.put(error) sleep(.1) assert self.received == 'Unauthorized.' @pytest.mark.skipif(sys.version_info < (3, 0), reason='pytest fails this for no reason') def test_non_context_deprecation(self, dp): with pytest.warns(TelegramDeprecationWarning): Dispatcher(dp.bot, dp.update_queue, job_queue=dp.job_queue, workers=0, use_context=False)
def callback_query(bot): return Update(0, callback_query=CallbackQuery(2, None, None, data='test data'))
def shiping_query(): return Update(1, shipping_query=ShippingQuery(42, User(1, 'test user', False), 'invoice_payload', ShippingAddress('EN', 'my_state', 'my_city', 'steer_1', '', 'post_code')))
def test_context(self, cdp, prefixmessage): handler = PrefixHandler(['!', '#', 'mytrig-'], ['help', 'test'], self.callback_context) cdp.add_handler(handler) cdp.process_update(Update(0, prefixmessage)) assert self.test_flag
def update(bot): user = User(id=321, first_name='test_user', is_bot=False) chat = Chat(id=123, type='group') message = Message(1, user, None, chat, text="Hi there", bot=bot) return Update(0, message=message)
def test_dispatcher_integration_handlers(self, caplog, bot, base_persistence, chat_data, user_data): def get_user_data(): return user_data def get_chat_data(): return chat_data base_persistence.get_user_data = get_user_data base_persistence.get_chat_data = get_chat_data # base_persistence.update_chat_data = lambda x: x # base_persistence.update_user_data = lambda x: x updater = Updater(bot=bot, persistence=base_persistence, use_context=True) dp = updater.dispatcher def callback_known_user(update, context): if not context.user_data['test1'] == 'test2': pytest.fail('user_data corrupt') def callback_known_chat(update, context): if not context.chat_data['test3'] == 'test4': pytest.fail('chat_data corrupt') def callback_unknown_user_or_chat(update, context): if not context.user_data == {}: pytest.fail('user_data corrupt') if not context.chat_data == {}: pytest.fail('chat_data corrupt') context.user_data[1] = 'test7' context.chat_data[2] = 'test8' known_user = MessageHandler(Filters.user(user_id=12345), callback_known_user, pass_chat_data=True, pass_user_data=True) known_chat = MessageHandler(Filters.chat(chat_id=-67890), callback_known_chat, pass_chat_data=True, pass_user_data=True) unknown = MessageHandler(Filters.all, callback_unknown_user_or_chat, pass_chat_data=True, pass_user_data=True) dp.add_handler(known_user) dp.add_handler(known_chat) dp.add_handler(unknown) user1 = User(id=12345, first_name='test user', is_bot=False) user2 = User(id=54321, first_name='test user', is_bot=False) chat1 = Chat(id=-67890, type='group') chat2 = Chat(id=-987654, type='group') m = Message(1, user1, None, chat2) u = Update(0, m) with caplog.at_level(logging.ERROR): dp.process_update(u) rec = caplog.records[-1] assert rec.msg == 'No error handlers are registered, logging exception.' assert rec.levelname == 'ERROR' rec = caplog.records[-2] assert rec.msg == 'No error handlers are registered, logging exception.' assert rec.levelname == 'ERROR' m.from_user = user2 m.chat = chat1 u = Update(1, m) dp.process_update(u) m.chat = chat2 u = Update(2, m) def save_chat_data(data): if -987654 not in data: pytest.fail() def save_user_data(data): if 54321 not in data: pytest.fail() base_persistence.update_chat_data = save_chat_data base_persistence.update_user_data = save_user_data dp.process_update(u) assert dp.user_data[54321][1] == 'test7' assert dp.chat_data[-987654][2] == 'test8'
def chat_join_request_update(bot, chat_join_request): return Update(0, chat_join_request=chat_join_request)
def chat_update(chat_message): return Update(update_id=2, message=chat_message)
def setUp(self): self.update = Update(0) self.update.message = Message(0, 0, datetime.utcnow(), Chat(0, 0))
def pre_checkout_query(): return Update( 1, pre_checkout_query=PreCheckoutQuery('id', User(1, 'test user', False), 'EUR', 223, 'invoice_payload'), )
class TestDispatcher: message_update = Update(1, message=Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text')) received = None count = 0 @pytest.fixture(autouse=True, name='reset') def reset_fixture(self): self.reset() def reset(self): self.received = None self.count = 0 def error_handler(self, bot, update, error): self.received = error.message def error_handler_context(self, update, context): self.received = context.error.message def error_handler_raise_error(self, bot, update, error): raise Exception('Failing bigly') def callback_increase_count(self, bot, update): self.count += 1 def callback_set_count(self, count): def callback(bot, update): self.count = count return callback def callback_raise_error(self, bot, update): if isinstance(bot, Bot): raise TelegramError(update.message.text) raise TelegramError(bot.message.text) def callback_if_not_update_queue(self, bot, update, update_queue=None): if update_queue is not None: self.received = update.message def callback_context(self, update, context): if (isinstance(context, CallbackContext) and isinstance(context.bot, Bot) and isinstance(context.update_queue, Queue) and isinstance(context.job_queue, JobQueue) and isinstance(context.error, TelegramError)): self.received = context.error.message def test_one_context_per_update(self, cdp): def one(update, context): if update.message.text == 'test': context.my_flag = True def two(update, context): if update.message.text == 'test': if not hasattr(context, 'my_flag'): pytest.fail() else: if hasattr(context, 'my_flag'): pytest.fail() cdp.add_handler(MessageHandler(Filters.regex('test'), one), group=1) cdp.add_handler(MessageHandler(None, two), group=2) u = Update(1, Message(1, None, None, None, text='test')) cdp.process_update(u) u.message.text = 'something' cdp.process_update(u) def test_error_handler(self, dp): dp.add_error_handler(self.error_handler) error = TelegramError('Unauthorized.') dp.update_queue.put(error) sleep(0.1) assert self.received == 'Unauthorized.' # Remove handler dp.remove_error_handler(self.error_handler) self.reset() dp.update_queue.put(error) sleep(0.1) assert self.received is None def test_double_add_error_handler(self, dp, caplog): dp.add_error_handler(self.error_handler) with caplog.at_level(logging.DEBUG): dp.add_error_handler(self.error_handler) assert len(caplog.records) == 1 assert caplog.records[-1].getMessage().startswith( 'The callback is already registered') def test_construction_with_bad_persistence(self, caplog, bot): class my_per: def __init__(self): self.store_user_data = False self.store_chat_data = False self.store_bot_data = False with pytest.raises( TypeError, match= 'persistence must be based on telegram.ext.BasePersistence'): Dispatcher(bot, None, persistence=my_per()) def test_error_handler_that_raises_errors(self, dp): """ Make sure that errors raised in error handlers don't break the main loop of the dispatcher """ handler_raise_error = MessageHandler(Filters.all, self.callback_raise_error) handler_increase_count = MessageHandler(Filters.all, self.callback_increase_count) error = TelegramError('Unauthorized.') dp.add_error_handler(self.error_handler_raise_error) # From errors caused by handlers dp.add_handler(handler_raise_error) dp.update_queue.put(self.message_update) sleep(0.1) # From errors in the update_queue dp.remove_handler(handler_raise_error) dp.add_handler(handler_increase_count) dp.update_queue.put(error) dp.update_queue.put(self.message_update) sleep(0.1) assert self.count == 1 @pytest.mark.parametrize(['run_async', 'expected_output'], [(True, 5), (False, 0)]) def test_default_run_async_error_handler(self, dp, monkeypatch, run_async, expected_output): def mock_async_err_handler(*args, **kwargs): self.count = 5 # set defaults value to dp.bot dp.bot.defaults = Defaults(run_async=run_async) try: dp.add_handler( MessageHandler(Filters.all, self.callback_raise_error)) dp.add_error_handler(self.error_handler) monkeypatch.setattr(dp, 'run_async', mock_async_err_handler) dp.process_update(self.message_update) assert self.count == expected_output finally: # reset dp.bot.defaults values dp.bot.defaults = None @pytest.mark.parametrize(['run_async', 'expected_output'], [(True, 'running async'), (False, None)]) def test_default_run_async(self, monkeypatch, dp, run_async, expected_output): def mock_run_async(*args, **kwargs): self.received = 'running async' # set defaults value to dp.bot dp.bot.defaults = Defaults(run_async=run_async) try: dp.add_handler(MessageHandler(Filters.all, lambda u, c: None)) monkeypatch.setattr(dp, 'run_async', mock_run_async) dp.process_update(self.message_update) assert self.received == expected_output finally: # reset defaults value dp.bot.defaults = None def test_run_async_multiple(self, bot, dp, dp2): def get_dispatcher_name(q): q.put(current_thread().name) q1 = Queue() q2 = Queue() dp.run_async(get_dispatcher_name, q1) dp2.run_async(get_dispatcher_name, q2) sleep(0.1) name1 = q1.get() name2 = q2.get() assert name1 != name2 def test_multiple_run_async_decorator(self, dp, dp2): # Make sure we got two dispatchers and that they are not the same assert isinstance(dp, Dispatcher) assert isinstance(dp2, Dispatcher) assert dp is not dp2 @run_async def must_raise_runtime_error(): pass with pytest.raises(RuntimeError): must_raise_runtime_error() def test_run_async_with_args(self, dp): dp.add_handler( MessageHandler(Filters.all, run_async(self.callback_if_not_update_queue), pass_update_queue=True)) dp.update_queue.put(self.message_update) sleep(0.1) assert self.received == self.message_update.message def test_multiple_run_async_deprecation(self, dp): assert isinstance(dp, Dispatcher) @run_async def callback(update, context): pass dp.add_handler(MessageHandler(Filters.all, callback)) with pytest.warns(TelegramDeprecationWarning, match='@run_async decorator'): dp.process_update(self.message_update) def test_async_raises_dispatcher_handler_stop(self, dp, caplog): @run_async def callback(update, context): raise DispatcherHandlerStop() dp.add_handler(MessageHandler(Filters.all, callback)) with caplog.at_level(logging.WARNING): dp.update_queue.put(self.message_update) sleep(0.1) assert len(caplog.records) == 1 assert (caplog.records[-1].getMessage().startswith( 'DispatcherHandlerStop is not supported ' 'with async functions')) def test_async_raises_exception(self, dp, caplog): @run_async def callback(update, context): raise RuntimeError('async raising exception') dp.add_handler(MessageHandler(Filters.all, callback)) with caplog.at_level(logging.WARNING): dp.update_queue.put(self.message_update) sleep(0.1) assert len(caplog.records) == 1 assert (caplog.records[-1].getMessage().startswith( 'A promise with deactivated error handling')) def test_add_async_handler(self, dp): dp.add_handler( MessageHandler( Filters.all, self.callback_if_not_update_queue, pass_update_queue=True, run_async=True, )) dp.update_queue.put(self.message_update) sleep(0.1) assert self.received == self.message_update.message def test_run_async_no_error_handler(self, dp, caplog): def func(): raise RuntimeError('Async Error') with caplog.at_level(logging.ERROR): dp.run_async(func) sleep(0.1) assert len(caplog.records) == 1 assert caplog.records[-1].getMessage().startswith( 'No error handlers are registered') def test_async_handler_error_handler(self, dp): dp.add_handler( MessageHandler(Filters.all, self.callback_raise_error, run_async=True)) dp.add_error_handler(self.error_handler) dp.update_queue.put(self.message_update) sleep(0.1) assert self.received == self.message_update.message.text def test_async_handler_async_error_handler_context(self, cdp): cdp.add_handler( MessageHandler(Filters.all, self.callback_raise_error, run_async=True)) cdp.add_error_handler(self.error_handler_context, run_async=True) cdp.update_queue.put(self.message_update) sleep(2) assert self.received == self.message_update.message.text def test_async_handler_error_handler_that_raises_error(self, dp, caplog): handler = MessageHandler(Filters.all, self.callback_raise_error, run_async=True) dp.add_handler(handler) dp.add_error_handler(self.error_handler_raise_error, run_async=False) with caplog.at_level(logging.ERROR): dp.update_queue.put(self.message_update) sleep(0.1) assert len(caplog.records) == 1 assert caplog.records[-1].getMessage().startswith( 'An uncaught error was raised') # Make sure that the main loop still runs dp.remove_handler(handler) dp.add_handler( MessageHandler(Filters.all, self.callback_increase_count, run_async=True)) dp.update_queue.put(self.message_update) sleep(0.1) assert self.count == 1 def test_async_handler_async_error_handler_that_raises_error( self, dp, caplog): handler = MessageHandler(Filters.all, self.callback_raise_error, run_async=True) dp.add_handler(handler) dp.add_error_handler(self.error_handler_raise_error, run_async=True) with caplog.at_level(logging.ERROR): dp.update_queue.put(self.message_update) sleep(0.1) assert len(caplog.records) == 1 assert caplog.records[-1].getMessage().startswith( 'An uncaught error was raised') # Make sure that the main loop still runs dp.remove_handler(handler) dp.add_handler( MessageHandler(Filters.all, self.callback_increase_count, run_async=True)) dp.update_queue.put(self.message_update) sleep(0.1) assert self.count == 1 def test_error_in_handler(self, dp): dp.add_handler(MessageHandler(Filters.all, self.callback_raise_error)) dp.add_error_handler(self.error_handler) dp.update_queue.put(self.message_update) sleep(0.1) assert self.received == self.message_update.message.text def test_add_remove_handler(self, dp): handler = MessageHandler(Filters.all, self.callback_increase_count) dp.add_handler(handler) dp.update_queue.put(self.message_update) sleep(0.1) assert self.count == 1 dp.remove_handler(handler) dp.update_queue.put(self.message_update) assert self.count == 1 def test_add_remove_handler_non_default_group(self, dp): handler = MessageHandler(Filters.all, self.callback_increase_count) dp.add_handler(handler, group=2) with pytest.raises(KeyError): dp.remove_handler(handler) dp.remove_handler(handler, group=2) def test_error_start_twice(self, dp): assert dp.running dp.start() def test_handler_order_in_group(self, dp): dp.add_handler( MessageHandler(Filters.photo, self.callback_set_count(1))) dp.add_handler(MessageHandler(Filters.all, self.callback_set_count(2))) dp.add_handler(MessageHandler(Filters.text, self.callback_set_count(3))) dp.update_queue.put(self.message_update) sleep(0.1) assert self.count == 2 def test_groups(self, dp): dp.add_handler( MessageHandler(Filters.all, self.callback_increase_count)) dp.add_handler(MessageHandler(Filters.all, self.callback_increase_count), group=2) dp.add_handler(MessageHandler(Filters.all, self.callback_increase_count), group=-1) dp.update_queue.put(self.message_update) sleep(0.1) assert self.count == 3 def test_add_handler_errors(self, dp): handler = 'not a handler' with pytest.raises(TypeError, match='handler is not an instance of'): dp.add_handler(handler) handler = MessageHandler(Filters.photo, self.callback_set_count(1)) with pytest.raises(TypeError, match='group is not int'): dp.add_handler(handler, 'one') def test_flow_stop(self, dp, bot): passed = [] def start1(b, u): passed.append('start1') raise DispatcherHandlerStop def start2(b, u): passed.append('start2') def start3(b, u): passed.append('start3') def error(b, u, e): passed.append('error') passed.append(e) update = Update( 1, message=Message( 1, None, None, None, text='/start', entities=[ MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) ], bot=bot, ), ) # If Stop raised handlers in other groups should not be called. passed = [] dp.add_handler(CommandHandler('start', start1), 1) dp.add_handler(CommandHandler('start', start3), 1) dp.add_handler(CommandHandler('start', start2), 2) dp.process_update(update) assert passed == ['start1'] def test_exception_in_handler(self, dp, bot): passed = [] err = Exception('General exception') def start1(b, u): passed.append('start1') raise err def start2(b, u): passed.append('start2') def start3(b, u): passed.append('start3') def error(b, u, e): passed.append('error') passed.append(e) update = Update( 1, message=Message( 1, None, None, None, text='/start', entities=[ MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) ], bot=bot, ), ) # If an unhandled exception was caught, no further handlers from the same group should be # called. Also, the error handler should be called and receive the exception passed = [] dp.add_handler(CommandHandler('start', start1), 1) dp.add_handler(CommandHandler('start', start2), 1) dp.add_handler(CommandHandler('start', start3), 2) dp.add_error_handler(error) dp.process_update(update) assert passed == ['start1', 'error', err, 'start3'] def test_telegram_error_in_handler(self, dp, bot): passed = [] err = TelegramError('Telegram error') def start1(b, u): passed.append('start1') raise err def start2(b, u): passed.append('start2') def start3(b, u): passed.append('start3') def error(b, u, e): passed.append('error') passed.append(e) update = Update( 1, message=Message( 1, None, None, None, text='/start', entities=[ MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) ], bot=bot, ), ) # If a TelegramException was caught, an error handler should be called and no further # handlers from the same group should be called. dp.add_handler(CommandHandler('start', start1), 1) dp.add_handler(CommandHandler('start', start2), 1) dp.add_handler(CommandHandler('start', start3), 2) dp.add_error_handler(error) dp.process_update(update) assert passed == ['start1', 'error', err, 'start3'] assert passed[2] is err def test_error_while_saving_chat_data(self, bot): increment = [] class OwnPersistence(BasePersistence): def __init__(self): super().__init__() self.store_user_data = True self.store_chat_data = True self.store_bot_data = True def get_bot_data(self): return {} def update_bot_data(self, data): raise Exception def get_chat_data(self): return defaultdict(dict) def update_chat_data(self, chat_id, data): raise Exception def get_user_data(self): return defaultdict(dict) def update_user_data(self, user_id, data): raise Exception def get_conversations(self, name): pass def update_conversation(self, name, key, new_state): pass def start1(b, u): pass def error(b, u, e): increment.append("error") # If updating a user_data or chat_data from a persistence object throws an error, # the error handler should catch it update = Update( 1, message=Message( 1, None, Chat(1, "lala"), from_user=User(1, "Test", False), text='/start', entities=[ MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) ], bot=bot, ), ) my_persistence = OwnPersistence() dp = Dispatcher(bot, None, persistence=my_persistence, use_context=False) dp.add_handler(CommandHandler('start', start1)) dp.add_error_handler(error) dp.process_update(update) assert increment == ["error", "error", "error"] def test_flow_stop_in_error_handler(self, dp, bot): passed = [] err = TelegramError('Telegram error') def start1(b, u): passed.append('start1') raise err def start2(b, u): passed.append('start2') def start3(b, u): passed.append('start3') def error(b, u, e): passed.append('error') passed.append(e) raise DispatcherHandlerStop update = Update( 1, message=Message( 1, None, None, None, text='/start', entities=[ MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) ], bot=bot, ), ) # If a TelegramException was caught, an error handler should be called and no further # handlers from the same group should be called. dp.add_handler(CommandHandler('start', start1), 1) dp.add_handler(CommandHandler('start', start2), 1) dp.add_handler(CommandHandler('start', start3), 2) dp.add_error_handler(error) dp.process_update(update) assert passed == ['start1', 'error', err] assert passed[2] is err def test_error_handler_context(self, cdp): cdp.add_error_handler(self.callback_context) error = TelegramError('Unauthorized.') cdp.update_queue.put(error) sleep(0.1) assert self.received == 'Unauthorized.' def test_sensible_worker_thread_names(self, dp2): thread_names = [ thread.name for thread in getattr(dp2, '_Dispatcher__async_threads') ] print(thread_names) for thread_name in thread_names: assert thread_name.startswith(f"Bot:{dp2.bot.id}:worker:") def test_non_context_deprecation(self, dp): with pytest.warns(TelegramDeprecationWarning): Dispatcher(dp.bot, dp.update_queue, job_queue=dp.job_queue, workers=0, use_context=False) def test_error_while_persisting(self, cdp, monkeypatch): class OwnPersistence(BasePersistence): def __init__(self): super().__init__() self.store_user_data = True self.store_chat_data = True self.store_bot_data = True def update(self, data): raise Exception('PersistenceError') def update_bot_data(self, data): self.update(data) def update_chat_data(self, chat_id, data): self.update(data) def update_user_data(self, user_id, data): self.update(data) def get_chat_data(self): pass def get_bot_data(self): pass def get_user_data(self): pass def get_conversations(self, name): pass def update_conversation(self, name, key, new_state): pass def callback(update, context): pass test_flag = False def error(update, context): nonlocal test_flag test_flag = str(context.error) == 'PersistenceError' raise Exception('ErrorHandlingError') def logger(message): assert 'uncaught error was raised while handling' in message update = Update(1, message=Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text')) handler = MessageHandler(Filters.all, callback) cdp.add_handler(handler) cdp.add_error_handler(error) monkeypatch.setattr(cdp.logger, 'exception', logger) cdp.persistence = OwnPersistence() cdp.process_update(update) assert test_flag def test_persisting_no_user_no_chat(self, cdp): class OwnPersistence(BasePersistence): def __init__(self): super().__init__() self.store_user_data = True self.store_chat_data = True self.store_bot_data = True self.test_flag_bot_data = False self.test_flag_chat_data = False self.test_flag_user_data = False def update_bot_data(self, data): self.test_flag_bot_data = True def update_chat_data(self, chat_id, data): self.test_flag_chat_data = True def update_user_data(self, user_id, data): self.test_flag_user_data = True def update_conversation(self, name, key, new_state): pass def get_conversations(self, name): pass def get_user_data(self): pass def get_bot_data(self): pass def get_chat_data(self): pass def callback(update, context): pass handler = MessageHandler(Filters.all, callback) cdp.add_handler(handler) cdp.persistence = OwnPersistence() update = Update(1, message=Message(1, None, None, from_user=User(1, '', False), text='Text')) cdp.process_update(update) assert cdp.persistence.test_flag_bot_data assert cdp.persistence.test_flag_user_data assert not cdp.persistence.test_flag_chat_data cdp.persistence.test_flag_bot_data = False cdp.persistence.test_flag_user_data = False cdp.persistence.test_flag_chat_data = False update = Update(1, message=Message(1, None, Chat(1, ''), from_user=None, text='Text')) cdp.process_update(update) assert cdp.persistence.test_flag_bot_data assert not cdp.persistence.test_flag_user_data assert cdp.persistence.test_flag_chat_data def test_update_persistence_once_per_update(self, monkeypatch, dp): def update_persistence(*args, **kwargs): self.count += 1 def dummy_callback(*args): pass monkeypatch.setattr(dp, 'update_persistence', update_persistence) for group in range(5): dp.add_handler(MessageHandler(Filters.text, dummy_callback), group=group) update = Update(1, message=Message(1, None, Chat(1, ''), from_user=None, text=None)) dp.process_update(update) assert self.count == 0 update = Update(1, message=Message(1, None, Chat(1, ''), from_user=None, text='text')) dp.process_update(update) assert self.count == 1 def test_update_persistence_all_async(self, monkeypatch, dp): def update_persistence(*args, **kwargs): self.count += 1 def dummy_callback(*args, **kwargs): pass monkeypatch.setattr(dp, 'update_persistence', update_persistence) monkeypatch.setattr(dp, 'run_async', dummy_callback) for group in range(5): dp.add_handler(MessageHandler(Filters.text, dummy_callback, run_async=True), group=group) update = Update(1, message=Message(1, None, Chat(1, ''), from_user=None, text='Text')) dp.process_update(update) assert self.count == 0 dp.bot.defaults = Defaults(run_async=True) try: for group in range(5): dp.add_handler(MessageHandler(Filters.text, dummy_callback), group=group) update = Update(1, message=Message(1, None, Chat(1, ''), from_user=None, text='Text')) dp.process_update(update) assert self.count == 0 finally: dp.bot.defaults = None @pytest.mark.parametrize('run_async', [DEFAULT_FALSE, False]) def test_update_persistence_one_sync(self, monkeypatch, dp, run_async): def update_persistence(*args, **kwargs): self.count += 1 def dummy_callback(*args, **kwargs): pass monkeypatch.setattr(dp, 'update_persistence', update_persistence) monkeypatch.setattr(dp, 'run_async', dummy_callback) for group in range(5): dp.add_handler(MessageHandler(Filters.text, dummy_callback, run_async=True), group=group) dp.add_handler(MessageHandler(Filters.text, dummy_callback, run_async=run_async), group=5) update = Update(1, message=Message(1, None, Chat(1, ''), from_user=None, text='Text')) dp.process_update(update) assert self.count == 1 @pytest.mark.parametrize('run_async,expected', [(DEFAULT_FALSE, 1), (False, 1), (True, 0)]) def test_update_persistence_defaults_async(self, monkeypatch, dp, run_async, expected): def update_persistence(*args, **kwargs): self.count += 1 def dummy_callback(*args, **kwargs): pass monkeypatch.setattr(dp, 'update_persistence', update_persistence) monkeypatch.setattr(dp, 'run_async', dummy_callback) dp.bot.defaults = Defaults(run_async=run_async) try: for group in range(5): dp.add_handler(MessageHandler(Filters.text, dummy_callback), group=group) update = Update(1, message=Message(1, None, Chat(1, ''), from_user=None, text='Text')) dp.process_update(update) assert self.count == expected finally: dp.bot.defaults = None
def mockUpdate(text): message = Message(0, None, None, None) message.text = text update = Update(0) update.message = message return update
def test_error_while_saving_chat_data(self, bot): increment = [] class OwnPersistence(BasePersistence): def __init__(self): super().__init__() self.store_user_data = True self.store_chat_data = True self.store_bot_data = True def get_bot_data(self): return {} def update_bot_data(self, data): raise Exception def get_chat_data(self): return defaultdict(dict) def update_chat_data(self, chat_id, data): raise Exception def get_user_data(self): return defaultdict(dict) def update_user_data(self, user_id, data): raise Exception def get_conversations(self, name): pass def update_conversation(self, name, key, new_state): pass def start1(b, u): pass def error(b, u, e): increment.append("error") # If updating a user_data or chat_data from a persistence object throws an error, # the error handler should catch it update = Update( 1, message=Message( 1, None, Chat(1, "lala"), from_user=User(1, "Test", False), text='/start', entities=[ MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) ], bot=bot, ), ) my_persistence = OwnPersistence() dp = Dispatcher(bot, None, persistence=my_persistence, use_context=False) dp.add_handler(CommandHandler('start', start1)) dp.add_error_handler(error) dp.process_update(update) assert increment == ["error", "error", "error"]
def test_context(self, cdp, message): handler = RegexHandler(r'(t)est(.*)', self.callback_context) cdp.add_handler(handler) cdp.process_update(Update(0, message=message)) assert self.test_flag
def test_error_while_persisting(self, cdp, monkeypatch): class OwnPersistence(BasePersistence): def __init__(self): super().__init__() self.store_user_data = True self.store_chat_data = True self.store_bot_data = True def update(self, data): raise Exception('PersistenceError') def update_bot_data(self, data): self.update(data) def update_chat_data(self, chat_id, data): self.update(data) def update_user_data(self, user_id, data): self.update(data) def get_chat_data(self): pass def get_bot_data(self): pass def get_user_data(self): pass def get_conversations(self, name): pass def update_conversation(self, name, key, new_state): pass def callback(update, context): pass test_flag = False def error(update, context): nonlocal test_flag test_flag = str(context.error) == 'PersistenceError' raise Exception('ErrorHandlingError') def logger(message): assert 'uncaught error was raised while handling' in message update = Update(1, message=Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text')) handler = MessageHandler(Filters.all, callback) cdp.add_handler(handler) cdp.add_error_handler(error) monkeypatch.setattr(cdp.logger, 'exception', logger) cdp.persistence = OwnPersistence() cdp.process_update(update) assert test_flag
def chat_member(bot, chat_member_updated): return Update(0, my_chat_member=chat_member_updated)
def test_persisting_no_user_no_chat(self, cdp): class OwnPersistence(BasePersistence): def __init__(self): super().__init__() self.store_user_data = True self.store_chat_data = True self.store_bot_data = True self.test_flag_bot_data = False self.test_flag_chat_data = False self.test_flag_user_data = False def update_bot_data(self, data): self.test_flag_bot_data = True def update_chat_data(self, chat_id, data): self.test_flag_chat_data = True def update_user_data(self, user_id, data): self.test_flag_user_data = True def update_conversation(self, name, key, new_state): pass def get_conversations(self, name): pass def get_user_data(self): pass def get_bot_data(self): pass def get_chat_data(self): pass def callback(update, context): pass handler = MessageHandler(Filters.all, callback) cdp.add_handler(handler) cdp.persistence = OwnPersistence() update = Update(1, message=Message(1, None, None, from_user=User(1, '', False), text='Text')) cdp.process_update(update) assert cdp.persistence.test_flag_bot_data assert cdp.persistence.test_flag_user_data assert not cdp.persistence.test_flag_chat_data cdp.persistence.test_flag_bot_data = False cdp.persistence.test_flag_user_data = False cdp.persistence.test_flag_chat_data = False update = Update(1, message=Message(1, None, Chat(1, ''), from_user=None, text='Text')) cdp.process_update(update) assert cdp.persistence.test_flag_bot_data assert not cdp.persistence.test_flag_user_data assert cdp.persistence.test_flag_chat_data
def chosen_inline_result(): return Update(1, chosen_inline_result=ChosenInlineResult( 'result_id', User(1, 'test_user'), 'query'))
def call_handler(updater, handler, message): update = Update(update_id=1, message=message) context = CallbackContext.from_update(update, updater.dispatcher) return handler(update, context)
def update(request): return Update(update_id=TestUpdate.update_id, **request.param)
def update(message): return Update(update_id=1, message=message)
def poll_answer(bot): return Update(0, poll_answer=PollAnswer(1, User(2, 'test user', False), [0, 1]))
def test_nested_conversation_handler(self, dp, bot, user1, user2): self.nested_states[self.DRINKING] = [ ConversationHandler(entry_points=self.drinking_entry_points, states=self.drinking_states, fallbacks=self.drinking_fallbacks, map_to_parent=self.drinking_map_to_parent) ] handler = ConversationHandler(entry_points=self.entry_points, states=self.nested_states, fallbacks=self.fallbacks) dp.add_handler(handler) # User one, starts the state machine. message = Message(0, user1, None, self.group, text='/start', bot=bot, entities=[ MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0, length=len('/start')) ]) dp.process_update(Update(update_id=0, message=message)) assert self.current_state[user1.id] == self.THIRSTY # The user is thirsty and wants to brew coffee. message.text = '/brew' message.entities[0].length = len('/brew') dp.process_update(Update(update_id=0, message=message)) assert self.current_state[user1.id] == self.BREWING # Lets pour some coffee. message.text = '/pourCoffee' message.entities[0].length = len('/pourCoffee') dp.process_update(Update(update_id=0, message=message)) assert self.current_state[user1.id] == self.DRINKING # The user is holding the cup message.text = '/hold' message.entities[0].length = len('/hold') dp.process_update(Update(update_id=0, message=message)) assert self.current_state[user1.id] == self.HOLDING # The user is sipping coffee message.text = '/sip' message.entities[0].length = len('/sip') dp.process_update(Update(update_id=0, message=message)) assert self.current_state[user1.id] == self.SIPPING # The user is swallowing message.text = '/swallow' message.entities[0].length = len('/swallow') dp.process_update(Update(update_id=0, message=message)) assert self.current_state[user1.id] == self.SWALLOWING # The user is holding the cup again message.text = '/hold' message.entities[0].length = len('/hold') dp.process_update(Update(update_id=0, message=message)) assert self.current_state[user1.id] == self.HOLDING # The user wants to replenish the coffee supply message.text = '/replenish' message.entities[0].length = len('/replenish') dp.process_update(Update(update_id=0, message=message)) assert self.current_state[user1.id] == self.REPLENISHING assert handler.conversations[(0, user1.id)] == self.BREWING # The user wants to drink their coffee again message.text = '/pourCoffee' message.entities[0].length = len('/pourCoffee') dp.process_update(Update(update_id=0, message=message)) assert self.current_state[user1.id] == self.DRINKING # The user is now ready to start coding message.text = '/startCoding' message.entities[0].length = len('/startCoding') dp.process_update(Update(update_id=0, message=message)) assert self.current_state[user1.id] == self.CODING # The user decides it's time to drink again message.text = '/drinkMore' message.entities[0].length = len('/drinkMore') dp.process_update(Update(update_id=0, message=message)) assert self.current_state[user1.id] == self.DRINKING # The user is holding their cup message.text = '/hold' message.entities[0].length = len('/hold') dp.process_update(Update(update_id=0, message=message)) assert self.current_state[user1.id] == self.HOLDING # The user wants to end with the drinking and go back to coding message.text = '/end' message.entities[0].length = len('/end') dp.process_update(Update(update_id=0, message=message)) assert self.current_state[user1.id] == self.END assert handler.conversations[(0, user1.id)] == self.CODING # The user wants to drink once more message.text = '/drinkMore' message.entities[0].length = len('/drinkMore') dp.process_update(Update(update_id=0, message=message)) assert self.current_state[user1.id] == self.DRINKING # The user wants to stop altogether message.text = '/stop' message.entities[0].length = len('/stop') dp.process_update(Update(update_id=0, message=message)) assert self.current_state[user1.id] == self.STOPPING assert handler.conversations.get((0, user1.id)) is None