diff --git a/bot.py b/bot.py index 8dc5110..994e9d0 100644 --- a/bot.py +++ b/bot.py @@ -66,6 +66,20 @@ RANDOMFOX_API_URL: str = "https://randomfox.ca/floof/" +# src: https://gist.github.com/bcnzer/2e1e392e355dc95b7f3da98a0b2ade9d +WOLF_PICTURES: List[str] = [ + "https://wolftracker9eee.blob.core.windows.net/wolfpictures-mock/wolf1.png", + "https://wolftracker9eee.blob.core.windows.net/wolfpictures-mock/wolf2.png", + "https://wolftracker9eee.blob.core.windows.net/wolfpictures-mock/wolf3.png", + "https://wolftracker9eee.blob.core.windows.net/wolfpictures-mock/wolf4.png", + "https://wolftracker9eee.blob.core.windows.net/wolfpictures-mock/wolf5.png", + "https://wolftracker9eee.blob.core.windows.net/wolfpictures-mock/wolf6.png", + "https://wolftracker9eee.blob.core.windows.net/wolfpictures-mock/wolf7.png", + "https://wolftracker9eee.blob.core.windows.net/wolfpictures-mock/wolf8.png", + "https://wolftracker9eee.blob.core.windows.net/wolfpictures-mock/wolf9.png", +] + + class DogPicsBot: """ A class to encapsulate all relevant methods of the Dog Pics @@ -126,6 +140,16 @@ def __init__(self): "triste", ] + # And again, for wolves. I promise this is the last animal to be + # introduced to the bot. + self.wolf_triggers = [ + "🐺", + "lobo", + "wolf", + "wolves", + "howl", + ] + # This environment variable should be set before using the bot self.token = os.environ.get("DPB_TG_TOKEN", "") @@ -196,6 +220,13 @@ def get_random_fox_sound(self): return random.choice(FOX_SOUNDS) + def get_random_wolf_picture(self): + """ + Randomly return a link to a wolf's picture. + """ + + return random.choice(WOLF_PICTURES) + def show_help(self, update, context): """ Sends the user a brief message explaining how to use the bot. @@ -232,6 +263,15 @@ def handle_text_messages(self, update, context): for fox_trigger in self.fox_triggers ) + # Easter Egg Possibility: has a wolf emoji or word + has_wolf_reference = any( + any( + word.startswith(wolf_trigger) + for word in words + ) + for wolf_trigger in self.wolf_triggers + ) + # Possibility: received a sad message is_sad_message = any( sad_trigger in words for sad_trigger in self.sad_triggers @@ -252,6 +292,8 @@ def handle_text_messages(self, update, context): if has_fox_reference: self.send_fox_picture(update, context) + elif has_wolf_reference: + self.send_wolf_picture(update, context) elif is_sad_message: sad_caption = "Don't be sad, have a cute dog!" self.send_dog_picture( @@ -312,7 +354,21 @@ def send_fox_picture(self, update, context): response_body = response.json() image_url = response_body['image'] - self.send_picture(update, context, image_url, self.get_random_fox_sound()) + self.send_picture( + update, context, image_url, self.get_random_fox_sound() + ) + + def send_wolf_picture(self, update, context): + """ + Retrieves a random wolf pic URL from the static list and sends the + given wolf picture as a photo message on Telegram. + """ + + image_url = self.get_random_wolf_picture() + + self.send_picture( + update, context, image_url, "Howl!" + ) def send_picture(self, update, context, image_url, caption): """ diff --git a/tests.py b/tests.py index d2eea93..637b309 100644 --- a/tests.py +++ b/tests.py @@ -16,6 +16,7 @@ TELEGRAM_CHAT_TYPE_GROUP, DOG_SOUNDS, FOX_SOUNDS, + WOLF_PICTURES, DogPicsBot, ) @@ -257,6 +258,21 @@ def test_get_random_fox_sound(monkeypatch: pytest.MonkeyPatch): assert bot.get_random_fox_sound() in FOX_SOUNDS +def test_get_random_wolf_picture(monkeypatch: pytest.MonkeyPatch): + """ + Unit test to verify that the bot is able to generate a random + wolf picture if needed. + """ + + # instantiating mock bot + bot = get_mock_bot(monkeypatch) + + # repeating the test several times + test_iterations = max(len(WOLF_PICTURES) * 5, 25) + for _ in range(test_iterations): + assert bot.get_random_wolf_picture() in WOLF_PICTURES + + def test_show_help(monkeypatch: pytest.MonkeyPatch): """ Unit test to verify that the bot is sending the proper help information @@ -531,6 +547,47 @@ def test_handle_text_messages_for_fox_reference( assert caption in FOX_SOUNDS +@pytest.mark.parametrize( + "wolf_message", + [ + "🐺", + "me gusta mucho este animal 🐺", + "wolves are the best", + "is that a wolf?", + "¡mira un lobo!", + "howl howl howl!", + ] +) +def test_handle_text_messages_for_wolf_reference( + monkeypatch: pytest.MonkeyPatch, wolf_message: str +): + """ + Unit test to verify that, in the presence of a message with a wolf + reference, the bot replies with a random wolf picture and a specific + caption. + """ + + # instantiating mock bot + bot = get_mock_bot(monkeypatch) + update = get_mock_update(message=wolf_message) + context = get_mock_context() + + # context is empty of sent photos + assert len(context.bot.photos) == 0 + + bot.handle_text_messages(update, context) + + # one picture sent through context + assert len(context.bot.photos) == 1 + + # contains the chat_id, original message id, photo url and caption + chat_id, reply_to_message_id, photo_url, caption = context.bot.photos[0] + assert chat_id == update.message.chat_id + assert reply_to_message_id == update.message.message_id + assert photo_url in WOLF_PICTURES + assert caption == "Howl!" + + def test_bot_fails_without_telegram_bot_token_in_environment( monkeypatch: pytest.MonkeyPatch ):