From 1991e0128b9c933d7daca4a4bf623751434c17ac Mon Sep 17 00:00:00 2001 From: neiljp Date: Mon, 29 May 2017 14:14:11 -0700 Subject: [PATCH] contrib_bots: Add check_expected_responses() test helper and use it. This further simplifies the logic for testing a contrib_bots bot to require very little code per test in the common case. --- contrib_bots/bots/converter/test_converter.py | 32 +++++++------------ contrib_bots/bots/define/test_define.py | 20 ++++++------ contrib_bots/bots/encrypt/test_encrypt.py | 28 +++++----------- .../bots/helloworld/test_helloworld.py | 16 +++------- contrib_bots/bots/help/test_help.py | 16 +++------- contrib_bots/bots/wikipedia/test_wikipedia.py | 28 +++++++--------- contrib_bots/bots/xkcd/test_xkcd.py | 6 +--- contrib_bots/bots_test_lib.py | 14 ++++++++ 8 files changed, 63 insertions(+), 97 deletions(-) diff --git a/contrib_bots/bots/converter/test_converter.py b/contrib_bots/bots/converter/test_converter.py index 9ee1e6a..90843d9 100644 --- a/contrib_bots/bots/converter/test_converter.py +++ b/contrib_bots/bots/converter/test_converter.py @@ -16,24 +16,14 @@ class TestConverterBot(BotTestCase): bot_name = "converter" def test_bot(self): - self.assert_bot_output( - {'content': "2 m cm", 'type': "private", 'sender_email': "foo@gmail.com"}, - "2.0 m = 200.0 cm\n" - ) - self.assert_bot_output( - {'content': "12 celsius fahrenheit", 'type': "stream", 'display_recipient': "foo", 'subject': "foo"}, - "12.0 celsius = 53.600054 fahrenheit\n" - ) - self.assert_bot_output( - {'content': "0.002 kilometer millimile", 'type': "stream", 'display_recipient': "foo", 'subject': "foo"}, - "0.002 kilometer = 1.2427424 millimile\n" - ) - self.assert_bot_output( - {'content': "3 megabyte kilobit", 'type': "stream", 'display_recipient': "foo", 'subject': "foo"}, - "3.0 megabyte = 24576.0 kilobit\n" - ) - self.assert_bot_output( - {'content': "foo bar", 'type': "stream", 'display_recipient': "foo", 'subject': "foo"}, - ('Too few arguments given. Enter `@convert help` ' - 'for help on using the converter.\n') - ) + expected = { + "": ('Too few arguments given. Enter `@convert help` ' + 'for help on using the converter.\n'), + "foo bar": ('Too few arguments given. Enter `@convert help` ' + 'for help on using the converter.\n'), + "2 m cm": "2.0 m = 200.0 cm\n", + "12.0 celsius fahrenheit": "12.0 celsius = 53.600054 fahrenheit\n", + "0.002 kilometer millimile": "0.002 kilometer = 1.2427424 millimile\n", + "3 megabyte kilobit": "3.0 megabyte = 24576.0 kilobit\n", + } + self.check_expected_responses(expected) diff --git a/contrib_bots/bots/define/test_define.py b/contrib_bots/bots/define/test_define.py index 449d0a2..e365860 100644 --- a/contrib_bots/bots/define/test_define.py +++ b/contrib_bots/bots/define/test_define.py @@ -16,14 +16,12 @@ class TestDefineBot(BotTestCase): bot_name = "define" def test_bot(self): - self.assert_bot_output( - {'content': "foo", 'type': "private", 'sender_email': "foo"}, - "**foo**:\nDefinition not available." - ) - self.assert_bot_output( - {'content': "cat", 'type': "stream", 'display_recipient': "foo", 'subject': "foo"}, - ("**cat**:\n\n* (**noun**) a small domesticated carnivorous mammal " - "with soft fur, a short snout, and retractile claws. It is widely " - "kept as a pet or for catching mice, and many breeds have been " - "developed.\n  their pet cat\n\n"), - ) + expected = { + "": 'Please enter a word to define.', + "foo": "**foo**:\nDefinition not available.", + "cat": ("**cat**:\n\n* (**noun**) a small domesticated carnivorous mammal " + "with soft fur, a short snout, and retractile claws. It is widely " + "kept as a pet or for catching mice, and many breeds have been " + "developed.\n  their pet cat\n\n"), + } + self.check_expected_responses(expected) diff --git a/contrib_bots/bots/encrypt/test_encrypt.py b/contrib_bots/bots/encrypt/test_encrypt.py index 7501fbd..21613ca 100644 --- a/contrib_bots/bots/encrypt/test_encrypt.py +++ b/contrib_bots/bots/encrypt/test_encrypt.py @@ -16,23 +16,11 @@ class TestEncryptBot(BotTestCase): bot_name = "encrypt" def test_bot(self): - self.assert_bot_output( - {'content': "Please encrypt this", 'type': "private", 'sender_email': "foo@gmail.com"}, - "Encrypted/Decrypted text: Cyrnfr rapelcg guvf" - ) - self.assert_bot_output( - {'content': "Let\'s Do It", 'type': "stream", 'display_recipient': "foo", 'subject': "foo"}, - "Encrypted/Decrypted text: Yrg\'f Qb Vg" - ) - self.assert_bot_output( - {'content': "", 'type': "stream", 'display_recipient': "foo", 'subject': "foo"}, - "Encrypted/Decrypted text: " - ) - self.assert_bot_output( - {'content': "me&mom together..!!", 'type': "stream", 'display_recipient': "foo", 'subject': "foo"}, - "Encrypted/Decrypted text: zr&zbz gbtrgure..!!" - ) - self.assert_bot_output( - {'content': "foo bar", 'type': "stream", 'display_recipient': "foo", 'subject': "foo"}, - "Encrypted/Decrypted text: sbb one" - ) + expected = { + "": "Encrypted/Decrypted text: ", + "Let\'s Do It": "Encrypted/Decrypted text: Yrg\'f Qb Vg", + "me&mom together..!!": "Encrypted/Decrypted text: zr&zbz gbtrgure..!!", + "foo bar": "Encrypted/Decrypted text: sbb one", + "Please encrypt this": "Encrypted/Decrypted text: Cyrnfr rapelcg guvf", + } + self.check_expected_responses(expected) diff --git a/contrib_bots/bots/helloworld/test_helloworld.py b/contrib_bots/bots/helloworld/test_helloworld.py index 06cfef4..c115ae0 100644 --- a/contrib_bots/bots/helloworld/test_helloworld.py +++ b/contrib_bots/bots/helloworld/test_helloworld.py @@ -5,6 +5,7 @@ from __future__ import print_function import os import sys +from six.moves import zip our_dir = os.path.dirname(os.path.abspath(__file__)) # For dev setups, we can find the API in the repo itself. @@ -16,15 +17,6 @@ class TestHelloWorldBot(BotTestCase): bot_name = "helloworld" def test_bot(self): - self.assert_bot_output( - {'content': "foo", 'type': "private", 'sender_email': "foo"}, - "beep boop" - ) - self.assert_bot_output( - {'content': "Hi, my name is abc", 'type': "stream", 'display_recipient': "foo", 'subject': "foo"}, - "beep boop" - ) - self.assert_bot_output( - {'content': "", 'type': "stream", 'display_recipient': "foo", 'subject': "foo"}, - "beep boop" - ) + txt = "beep boop" + messages = ["", "foo", "Hi, my name is abc"] + self.check_expected_responses(dict(list(zip(messages, len(messages)*[txt])))) diff --git a/contrib_bots/bots/help/test_help.py b/contrib_bots/bots/help/test_help.py index fb364f8..8a2633c 100644 --- a/contrib_bots/bots/help/test_help.py +++ b/contrib_bots/bots/help/test_help.py @@ -5,6 +5,7 @@ from __future__ import print_function import os import sys +from six.moves import zip our_dir = os.path.dirname(os.path.abspath(__file__)) # For dev setups, we can find the API in the repo itself. @@ -16,15 +17,6 @@ class TestHelpBot(BotTestCase): bot_name = "help" def test_bot(self): - self.assert_bot_output( - {'content': "help", 'type': "private", 'sender_email': "foo"}, - "Info on Zulip can be found here:\nhttps://github.com/zulip/zulip" - ) - self.assert_bot_output( - {'content': "Hi, my name is abc", 'type': "stream", 'display_recipient': "foo", 'subject': "foo"}, - "Info on Zulip can be found here:\nhttps://github.com/zulip/zulip" - ) - self.assert_bot_output( - {'content': "", 'type': "stream", 'display_recipient': "foo", 'subject': "foo"}, - "Info on Zulip can be found here:\nhttps://github.com/zulip/zulip" - ) + txt = "Info on Zulip can be found here:\nhttps://github.com/zulip/zulip" + messages = ["", "help", "Hi, my name is abc"] + self.check_expected_responses(dict(list(zip(messages, len(messages)*[txt])))) diff --git a/contrib_bots/bots/wikipedia/test_wikipedia.py b/contrib_bots/bots/wikipedia/test_wikipedia.py index 8482e95..45dcbd5 100644 --- a/contrib_bots/bots/wikipedia/test_wikipedia.py +++ b/contrib_bots/bots/wikipedia/test_wikipedia.py @@ -16,19 +16,15 @@ class TestWikipediaBot(BotTestCase): bot_name = "wikipedia" def test_bot(self): - self.assert_bot_output( - {'content': "foo", 'type': "private", 'sender_email': "foo"}, - 'For search term "foo", https://en.wikipedia.org/wiki/Foobar' - ) - self.assert_bot_output( - {'content': "", 'type': "stream", 'display_recipient': "foo", 'subject': "foo"}, - 'Please enter your message after @mention-bot' - ) - self.assert_bot_output( - {'content': "sssssss kkkkk", 'type': "stream", 'display_recipient': "foo", 'subject': "foo"}, - 'I am sorry. The search term you provided is not found :slightly_frowning_face:' - ) - self.assert_bot_output( - {'content': "123", 'type': "stream", 'display_recipient': "foo", 'subject': "foo"}, - 'For search term "123", https://en.wikipedia.org/wiki/123' - ) + expected = { + "": 'Please enter your message after @mention-bot', + "sssssss kkkkk": ('I am sorry. The search term you provided ' + 'is not found :slightly_frowning_face:'), + "foo": ('For search term "foo", ' + 'https://en.wikipedia.org/wiki/Foobar'), + "123": ('For search term "123", ' + 'https://en.wikipedia.org/wiki/123'), + "laugh": ('For search term "laugh", ' + 'https://en.wikipedia.org/wiki/Laughter'), + } + self.check_expected_responses(expected) diff --git a/contrib_bots/bots/xkcd/test_xkcd.py b/contrib_bots/bots/xkcd/test_xkcd.py index 24b774e..fa43894 100644 --- a/contrib_bots/bots/xkcd/test_xkcd.py +++ b/contrib_bots/bots/xkcd/test_xkcd.py @@ -39,8 +39,4 @@ class TestXkcdBot(BotTestCase): "(https://imgs.xkcd.com/comics/chess_notation.png)"), "999999999": invalid_id_txt + "999999999", } - for m, r in expected.items(): - self.assert_bot_output( - {'content': m, 'type': "private", 'sender_email': "foo"}, r) - self.assert_bot_output( - {'content': m, 'type': "stream", 'sender_email': "foo"}, r) + self.check_expected_responses(expected) diff --git a/contrib_bots/bots_test_lib.py b/contrib_bots/bots_test_lib.py index e5a551b..04f82fc 100644 --- a/contrib_bots/bots_test_lib.py +++ b/contrib_bots/bots_test_lib.py @@ -6,6 +6,7 @@ from __future__ import print_function import os import sys import unittest +import logging from mock import MagicMock, patch @@ -31,6 +32,19 @@ class BotTestCase(TestCase): self.bot_test(messages=[request], bot_module=bot_module, bot_response=[response]) + def check_expected_responses(self, expectations, email="foo", recipient="foo", subject="foo", type="all"): + # type: (Dict[str, str], str, str, str, str) -> None + if type not in ["private", "stream", "all"]: + logging.exception("check_expected_response expects type to be 'private', 'stream' or 'all'") + for m, r in expectations.items(): + if type != "stream": + self.assert_bot_output( + {'content': m, 'type': "private", 'sender_email': email}, r) + if type != "private": + self.assert_bot_output( + {'content': m, 'type': "stream", 'display_recipient': recipient, + 'subject': subject}, r) + def mock_test(self, messages, message_handler, bot_response): # message_handler is of type Any, since it can contain any bot's # handler class. Eventually, we want bot's handler classes to