Ejemplo n.º 1
0
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()
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
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,
    )
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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"])
Ejemplo n.º 7
0
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")
Ejemplo n.º 8
0
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()
Ejemplo n.º 9
0
    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
Ejemplo n.º 10
0
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()
Ejemplo n.º 11
0
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)
Ejemplo n.º 12
0
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
Ejemplo n.º 13
0
    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
Ejemplo n.º 14
0
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
Ejemplo n.º 15
0
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)
Ejemplo n.º 16
0
    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)
Ejemplo n.º 17
0
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()
Ejemplo n.º 18
0
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,
    )
Ejemplo n.º 19
0
    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)
Ejemplo n.º 20
0
    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
Ejemplo n.º 21
0
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")
Ejemplo n.º 22
0
 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)
Ejemplo n.º 23
0
    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")
Ejemplo n.º 24
0
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")
Ejemplo n.º 25
0
 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)
Ejemplo n.º 26
0
 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)
Ejemplo n.º 27
0
def test_start(g_bot: GDGAjuBot):
    g_bot.start()
    g_bot.updater.start_polling.assert_called_once_with(clean=True)
Ejemplo n.º 28
0
 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)
Ejemplo n.º 29
0
 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)
Ejemplo n.º 30
0
    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")
Ejemplo n.º 31
0
def g_bot_complete(updater_cls, bot_config: BotConfig,
                   resources: MockResources):
    yield GDGAjuBot(bot_config, resources=resources)
Ejemplo n.º 32
0
def g_bot(bot_config, telebot, resources):
    _gbot = GDGAjuBot(bot_config, telebot, resources)
    _gbot.updater = NonCallableMock()
    yield _gbot
Ejemplo n.º 33
0
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)
Ejemplo n.º 34
0
 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)
Ejemplo n.º 35
0
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")