def test_start_in_dev_mode(g_bot: GDGAjuBot, telebot: MockTeleBot): g_bot.config.debug_mode = True g_bot.start() g_bot.updater.start_polling.assert_called_once_with(clean=True) telebot.get_me.assert_called_once()
def test_list_upcoming_events(g_bot: GDGAjuBot, telebot: MockTeleBot): message = MockMessage() g_bot.list_upcoming_events(message) # Verifica se o response criado está correto r = ( "[Hackeando sua Carreira #Hangout](http://www.meetup.com/GDG-Aracaju/events/229313880/): 30/03 20h\n" "[Android Jam 2: Talks Dia 2](http://www.meetup.com/GDG-Aracaju/events/229623381/): 02/04 13h\n" "[Coding Dojo](http://www.meetup.com/GDG-Aracaju/events/mwnsrlyvgbjb/): 06/04 19h\n" "[O Caminho para uma Arquitetura Elegante #Hangout](http://www.meetup.com/GDG-Aracaju/events/229591464/): 08/04 21h\n" "[Android Jam 2: #Curso Dia 2](http://www.meetup.com/GDG-Aracaju/events/229770309/): 09/04 13h" ) telebot.send_message.assert_called_with( message.chat_id, r, parse_mode="Markdown", disable_web_page_preview=True, reply_to_message_id=message.message_id, ) # Garante que o cache mutável não gerará uma exceção n_calls = len(telebot.method_calls) g_bot.list_upcoming_events(message) assert len(telebot.method_calls) > n_calls
def test_smart_reply(self): bot, resources = MockTeleBot(), MockResources() message = MockMessage(id=0x6D6) g_bot = GDGAjuBot(self.config, bot, resources) text = "I <3 GDG Aracaju" # Mensagens privadas não fazem link message.chat.type = "private" g_bot._send_smart_reply(message, text) bot.send_message.assert_called_with( message.chat_id, text, reply_to_message_id=message.message_id) g_bot._send_smart_reply(message, text) bot.send_message.assert_called_with( message.chat_id, text, reply_to_message_id=message.message_id) # Configurando MockTeleBot.send_message() para retornar um MockMessage com um message_id bot.send_message.return_value = MockMessage(message_id=82) # Mensagens de grupo fazem link message.chat.type = "group" g_bot._send_smart_reply(message, text) bot.send_message.assert_called_with( message.chat_id, text, reply_to_message_id=message.message_id) g_bot._send_smart_reply(message, text) bot.send_message.assert_called_with(message.chat.id, mock.ANY, reply_to_message_id=82) the_answer = bot.send_message.call_args[0][1] assert the_answer[2:] in ALREADY_ANSWERED_TEXTS
def test_book_unavailable(g_bot: GDGAjuBot, telebot: MockTeleBot, resources: MockResources): message = MockMessage() resources.get_packt_free_book.return_value = None r = ( "Parece que não tem um livro grátis hoje 😡\n\n" "Se acha que é um erro meu, veja com seus próprios olhos em https://www.packtpub.com/packt/offers/free-learning" ) g_bot.packtpub_free_learning(message) telebot.send_message.assert_called_with( message.chat_id, r, parse_mode="Markdown", disable_web_page_preview=True, reply_to_message_id=message.message_id, ) g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(BOOK.expires + 1, tz=AJU_TZ)) telebot.send_message.assert_called_with( message.chat_id, r, parse_mode="Markdown", disable_web_page_preview=True, reply_to_message_id=message.message_id, )
def test_about(g_bot: GDGAjuBot, telebot: MockTeleBot): message = MockMessage(id=0xB00B) g_bot.about(message) link = "https://github.com/GDGAracaju/GDGAjuBot/" response = telebot.send_message.call_args[0][1] assert link in response
def test_help(g_bot: GDGAjuBot, telebot: MockTeleBot): message = MockMessage() g_bot.help(message) response = telebot.reply_to.call_args[0][1] assert response is not None assert all(c in response for c in ["/help", "/udemy", "/book", "/events", "/about"])
def test_list_users(g_bot: GDGAjuBot, telebot: MockTeleBot, resources: MockResources): resources.list_all_users.return_value = ["kent", "wayne"] message = MockMessage() g_bot.list_users(message) resources.list_all_users.assert_called_once() telebot.send_message.assert_called_once_with(message.chat.id, "kent\nwayne")
def g_bot(resources): bot_config = BotConfig(telegram_token=TELEGRAM_TOKEN, group_name=GROUP_NAME, dev=False) _gbot = GDGAjuBot(bot_config, resources=resources) _gbot.start() yield _gbot _gbot.updater.stop()
def test_smart_reply(self): bot, resources = MockTeleBot(), MockResources() message = MockMessage(id=0x6D6) g_bot = GDGAjuBot(self.config, bot, resources) text = "I <3 GDG Aracaju" # Mensagens privadas não fazem link message.chat.type = "private" g_bot._send_smart_reply(message, text) bot.send_message.assert_called_with(message.chat_id, text, reply_to_message_id=message.message_id) g_bot._send_smart_reply(message, text) bot.send_message.assert_called_with(message.chat_id, text, reply_to_message_id=message.message_id) # Configurando MockTeleBot.send_message() para retornar um MockMessage com um message_id bot.send_message.return_value = MockMessage(message_id=82) # Mensagens de grupo fazem link message.chat.type = "group" g_bot._send_smart_reply(message, text) bot.send_message.assert_called_with(message.chat_id, text, reply_to_message_id=message.message_id) g_bot._send_smart_reply(message, text) bot.send_message.assert_called_with(message.chat.id, mock.ANY, reply_to_message_id=82) the_answer = bot.send_message.call_args[0][1] assert the_answer[2:] in ALREADY_ANSWERED_TEXTS
def main(): log_format = os.environ.get('LOG_FORMAT', '%(asctime)s %(message)s') log_datefmt = os.environ.get('LOG_DATE_FORMAT', '%m/%d/%Y %I:%M:%S %p') # Configuring log logging.basicConfig(level=logging.INFO, format=log_format, datefmt=log_datefmt) # Configuring bot parameters logging.info("Configurando parâmetros") parser = util.ArgumentParser(description='Bot do GDG Aracaju') parser.add_argument('-c', '--config_file', help='Arquivo de configuração') parser.add_argument('-t', '--telegram_token', help='Token da API do Telegram') parser.add_argument('-m', '--meetup_key', help='Key da API do Meetup') parser.add_argument('-f', '--facebook_key', help='Key da API do Facebook') parser.add_argument( '-db', '--database_url', help='URL de configuração do banco de dados', ) parser.add_argument( '-g', '--group_name', help='Grupo(s) do Meetup/Facebook, separados por vírgulas', ) parser.add_argument('--url_shortener_key', help='Key da API do URL Shortener') parser.add_argument('--events_source', choices=['meetup', 'facebook']) parser.add_argument('-d', '--dev', help='Indicador de Debug/Dev mode', action='store_true') parser.add_argument('--no-dev', help=argparse.SUPPRESS, dest='dev', action='store_false') # Parse command line args and get the config _config = parser.parse_args() # Define the events source if needed if not _config.events_source: if _config.meetup_key: _config.events_source = 'meetup' elif _config.facebook_key: _config.events_source = 'facebook' else: parser.error('an API key is needed to get events') # Starting bot gdgbot = GDGAjuBot(_config) gdgbot.start()
def test_chat_statistics(g_bot: GDGAjuBot): message = MockMessage() g_bot.chat_statistics(message) actual = (g_bot.get_state( "chat_stats", message.chat_id)["last_activity"].astimezone().timestamp()) expected = datetime.utcnow().astimezone().timestamp() assert actual == approx(expected, rel=0.1)
def test_send_welcome(g_bot: GDGAjuBot, telebot: MockTeleBot): message = MockMessage() g_bot.send_welcome(message) response = telebot.reply_to.call_args[0][1] assert response is not None assert "/help" in response assert len(g_bot.config.group_name) > 0 for group in g_bot.config.group_name: assert group in response
def test_list_upcoming_events(self): bot, resources, message = MockTeleBot(), MockResources(), MockMessage() g_bot = GDGAjuBot(self.config, bot, resources) g_bot.list_upcoming_events(message) # Verifica se o response criado está correto self._assert_list_upcoming_events(bot, message) # Garante que o cache mutável não gerará uma exceção n_calls = len(bot.method_calls) g_bot.list_upcoming_events(message) assert len(bot.method_calls) > n_calls
def test_smart_reply(g_bot: GDGAjuBot, telebot: MockTeleBot): message = MockMessage(id=0x6D6) text = "I <3 GDG Aracaju" # Mensagens privadas não fazem link message.chat.type = "private" g_bot._send_smart_reply(message, text) telebot.send_message.assert_called_with( message.chat_id, text, reply_to_message_id=message.message_id) g_bot._send_smart_reply(message, text) telebot.send_message.assert_called_with( message.chat_id, text, reply_to_message_id=message.message_id) # Configurando telebot.send_message() para retornar um MockMessage com um message_id telebot.send_message.return_value = MockMessage(message_id=82) # Mensagens de grupo fazem link message.chat.type = "group" g_bot._send_smart_reply(message, text) telebot.send_message.assert_called_with( message.chat_id, text, reply_to_message_id=message.message_id) g_bot._send_smart_reply(message, text) telebot.send_message.assert_called_with(message.chat.id, ANY, reply_to_message_id=82) the_answer = telebot.send_message.call_args[0][1] assert the_answer[2:] in ALREADY_ANSWERED_TEXTS
def test_daily_book_management(g_bot: GDGAjuBot, resources: MockResources): message = MockMessage() resources.get_group.return_value.has_daily_book = False g_bot.daily_book_management(message, args=()) message.reply_html.assert_called_with( StartsWith("Livro diário automático <b>desativado</b>\n\n"), quote=True) g_bot.daily_book_management(message, args=("shriek", )) message.reply_html.assert_called_with( StartsWith("Argumento <code>shriek</code> inválido!!!\n\n"), quote=True) g_bot.daily_book_management(message, args=("on", )) resources.set_group.assert_called_with(message.chat_id, message.chat.username, has_daily_book=True) message.reply_html.assert_called_with( StartsWith("Livro diário automático <b>ativado</b>"), quote=True) g_bot.daily_book_management(message, args=("off", )) resources.set_group.assert_called_with(message.chat_id, message.chat.username, has_daily_book=False) message.reply_html.assert_called_with( StartsWith("Livro diário automático <b>desativado</b>"), quote=True)
def test_book_unavailable(self): bot, resources, message = MockTeleBot(), MockResources(book=False), MockMessage() g_bot = GDGAjuBot(self.config, bot, resources) r = "Parece que não tem um livro grátis hoje 😡\n\n" \ "Se acha que é um erro meu, veja com seus próprios olhos em https://www.packtpub.com/packt/offers/free-learning" g_bot.packtpub_free_learning(message) bot.send_message.assert_called_with(message.chat_id, r, parse_mode="Markdown", disable_web_page_preview=True, reply_to_message_id=message.message_id) resources.book = MockResources.BOOK g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(resources.book.expires + 1, tz=AJU_TZ)) bot.send_message.assert_called_with(message.chat_id, r, parse_mode="Markdown", disable_web_page_preview=True, reply_to_message_id=message.message_id)
def client(g_bot: GDGAjuBot): # Esse módulo só pode ser testado com uma chave API real # Obtenha a sua em https://my.telegram.org, na seção API Development api_id = TELEGRAM_CLIENT_API_ID api_hash = TELEGRAM_CLIENT_API_HASH t_client = TelegramClient("it_gdgajubot", api_id, api_hash) t_client.start() yield ClientWrapper(t_client, g_bot.get_me().name) t_client.disconnect()
def test_links(g_bot: GDGAjuBot, send_smart_reply: Mock): message = MockMessage() g_bot.links(message) send_smart_reply.assert_called_with( message, "Não existem links associados a esse grupo.", parse_mode="Markdown", disable_web_page_preview=True, ) g_bot.config.links = {"hey": "https://hey.com"} g_bot.links(message) send_smart_reply.assert_called_with( message, "*Esses são os links para o nosso grupo:*\n\n🔗 Hey: https://hey.com\n", parse_mode="Markdown", disable_web_page_preview=True, )
def test_book_unavailable(self): bot, resources, message = MockTeleBot(), MockResources( book=False), MockMessage() g_bot = GDGAjuBot(self.config, bot, resources) r = "Parece que não tem um livro grátis hoje 😡\n\n" \ "Se acha que é um erro meu, veja com seus próprios olhos em https://www.packtpub.com/packt/offers/free-learning" g_bot.packtpub_free_learning(message) bot.send_message.assert_called_with( message.chat_id, r, parse_mode="Markdown", disable_web_page_preview=True, reply_to_message_id=message.message_id) resources.book = MockResources.BOOK g_bot.packtpub_free_learning( message, now=datetime.fromtimestamp(resources.book.expires + 1, tz=AJU_TZ)) bot.send_message.assert_called_with( message.chat_id, r, parse_mode="Markdown", disable_web_page_preview=True, reply_to_message_id=message.message_id)
def test_easter_eggs(g_bot: GDGAjuBot, telebot: MockTeleBot): message = MockMessage() g_bot.love_ruby(message) telebot.send_message.assert_called_with( message.chat.id, f"{message.from_user.name} ama Ruby... ou Rails?") g_bot.memory_java(message) telebot.send_message.assert_called_with(message.chat.id, "Ihh... acabou a RAM") g_bot.easter_python(message) telebot.send_message.assert_called_with(message.chat.id, "import antigravity")
def test_about(self): bot, resources, message = MockTeleBot(), MockResources(), MockMessage(id=0xB00B) g_bot = GDGAjuBot(self.config, bot, resources) g_bot.about(message) self._assert_about(bot, message)
def test_packtpub_free_learning(self): bot, resources, message = MockTeleBot(), MockResources(), MockMessage() g_bot = GDGAjuBot(self.config, bot, resources) ts = resources.BOOK.expires # Sem warning g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(ts - 10 * 3600, tz=AJU_TZ)) self._assert_packtpub_free_learning(bot, message) # Os próximos testes verificam cada um dos warnings g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(ts - 59 * 60, tz=AJU_TZ)) self._assert_packtpub_free_learning(bot, message, warning="1 hora") g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(ts - 29 * 60, tz=AJU_TZ)) self._assert_packtpub_free_learning(bot, message, warning="meia hora") g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(ts - 9 * 60, tz=AJU_TZ)) self._assert_packtpub_free_learning(bot, message, warning="10 minutos") g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(ts - 59, tz=AJU_TZ)) self._assert_packtpub_free_learning(bot, message, warning="1 minuto") g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(ts - 29, tz=AJU_TZ)) self._assert_packtpub_free_learning(bot, message, warning="30 segundos")
def test_ensure_daily_book(g_bot: GDGAjuBot, telebot: MockTeleBot): # given chat_id = 1234 telebot.get_chat.return_value = telegram.Chat(chat_id, type="group") state = g_bot.states["daily_book"][chat_id] # when g_bot.ensure_daily_book() # then g_bot.updater.job_queue.run_once.assert_called_once_with(ANY, when=60) job_callback = g_bot.updater.job_queue.run_once.call_args[0][0] assert isinstance(job_callback, Callable) assert state["__memory__"]["first_call"] is True assert isinstance(state["__memory__"]["schedule_fn"], Callable) # given message = telegram.Message(0, g_bot.get_me(), datetime.now(), telebot.get_chat.return_value) # when g_bot.ensure_daily_book(message, as_job=False) # then assert state["messages_since"] == 1 # when g_bot.ensure_daily_book(message, as_job=True) # then last_time = state["last_time"].astimezone().timestamp() expected = datetime.utcnow().astimezone().timestamp() assert last_time == approx(expected, rel=0.1) # given g_bot.updater.job_queue.run_once.reset_mock() # when g_bot.ensure_daily_book(message, as_job=True) # then g_bot.updater.job_queue.run_once.assert_called_once_with(ANY, when=ANY) seconds = g_bot.updater.job_queue.run_once.call_args[1]["when"] assert seconds // 3600 in range(3, 12 + 1) # given state["last_time"] -= timedelta(hours=3) state["messages_since"] += 300 # when g_bot.ensure_daily_book(message, as_job=True) # then telebot.send_message.assert_any_call(chat_id, Contains(" Mensagem automática do "), parse_mode="Markdown")
def test_help(self): bot, resources, message = MockTeleBot(), MockResources(), MockMessage() g_bot = GDGAjuBot(self.config, bot, resources) g_bot.help(message) self._assert_help_message(bot, message)
def test_send_welcome(self): bot, resources, message = MockTeleBot(), MockResources(), MockMessage() g_bot = GDGAjuBot(self.config, bot, resources) g_bot.send_welcome(message) self._assert_send_welcome(bot, message)
def test_start(g_bot: GDGAjuBot): g_bot.start() g_bot.updater.start_polling.assert_called_once_with(clean=True)
def test_about(self): bot, resources, message = MockTeleBot(), MockResources(), MockMessage( id=0xB00B) g_bot = GDGAjuBot(self.config, bot, resources) g_bot.about(message) self._assert_about(bot, message)
def test_packtpub_free_learning(self): bot, resources, message = MockTeleBot(), MockResources(), MockMessage() g_bot = GDGAjuBot(self.config, bot, resources) ts = resources.BOOK.expires # Sem warning g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(ts - 10*3600, tz=AJU_TZ)) self._assert_packtpub_free_learning(bot, message) # Os próximos testes verificam cada um dos warnings g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(ts - 59*60, tz=AJU_TZ)) self._assert_packtpub_free_learning(bot, message, warning="1 hora") g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(ts - 29*60, tz=AJU_TZ)) self._assert_packtpub_free_learning(bot, message, warning="meia hora") g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(ts - 9*60, tz=AJU_TZ)) self._assert_packtpub_free_learning(bot, message, warning="10 minutos") g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(ts - 59, tz=AJU_TZ)) self._assert_packtpub_free_learning(bot, message, warning="1 minuto") g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(ts - 29, tz=AJU_TZ)) self._assert_packtpub_free_learning(bot, message, warning="30 segundos")
def g_bot_complete(updater_cls, bot_config: BotConfig, resources: MockResources): yield GDGAjuBot(bot_config, resources=resources)
def g_bot(bot_config, telebot, resources): _gbot = GDGAjuBot(bot_config, telebot, resources) _gbot.updater = NonCallableMock() yield _gbot
def test_extract_and_save_data(g_bot: GDGAjuBot, resources: MockResources): message = MockMessage() g_bot.extract_and_save_data(message) resources.log_message.assert_called_once_with(message)
def test_packtpub_free_learning(g_bot: GDGAjuBot, telebot): message = MockMessage() ts = BOOK.expires # Sem warning g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(ts - 10 * 3600, tz=AJU_TZ)) assert_packtpub_free_learning(telebot, message) # Os próximos testes verificam cada um dos warnings g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(ts - 59 * 60, tz=AJU_TZ)) assert_packtpub_free_learning(telebot, message, warning="1 hora") g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(ts - 29 * 60, tz=AJU_TZ)) assert_packtpub_free_learning(telebot, message, warning="meia hora") g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(ts - 9 * 60, tz=AJU_TZ)) assert_packtpub_free_learning(telebot, message, warning="10 minutos") g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(ts - 59, tz=AJU_TZ)) assert_packtpub_free_learning(telebot, message, warning="1 minuto") g_bot.packtpub_free_learning(message, now=datetime.fromtimestamp(ts - 29, tz=AJU_TZ)) assert_packtpub_free_learning(telebot, message, warning="30 segundos")