bot tests: Adjust TestCase inheritance to avoid need to skip/filter.

Previously the test-bots script filtered out base-class tests from
BotTestCase. With this change, BotTestCase continues to inherit from
unittest.TestCase, but the default test_* methods previously in this
class are now in a new DefaultTests class, which does not. Instead, each
bot needs to inherit from BotTestCase and DefaultTests *explicitly*.

This avoids the need to filter out the base-class tests, which
simplifies the test-bots script, and may ease any migration to eg.
pytest.

The DefaultTests class does require some non-implemented methods which
BotTestCase provides.
This commit is contained in:
neiljp (Neil Pilgrim) 2018-06-08 14:30:50 -07:00 committed by showell
parent c636a5ac49
commit 6cdb83ce72
43 changed files with 105 additions and 102 deletions

View file

@ -95,19 +95,6 @@ def main():
if options.error_on_no_init: if options.error_on_no_init:
sys.exit(1) sys.exit(1)
def filter_tests(tests):
# type: (Union[TestSuite, TestCase]) -> TestSuite
filtered_tests = TestSuite()
for test in tests:
if isinstance(test, TestCase):
# Exclude test base class from being tested.
if test.__class__.__name__ != 'BotTestCase':
filtered_tests.addTest(test)
else:
filtered_tests.addTest(filter_tests(test))
return filtered_tests
test_suites = filter_tests(test_suites)
suite = unittest.TestSuite(test_suites) suite = unittest.TestSuite(test_suites)
runner = unittest.TextTestRunner(verbosity=2) runner = unittest.TextTestRunner(verbosity=2)
result = runner.run(suite) result = runner.run(suite)

View file

@ -1,9 +1,9 @@
from unittest.mock import patch from unittest.mock import patch
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
from zulip_bots.test_lib import StubBotHandler from zulip_bots.test_lib import StubBotHandler
from zulip_bots.bots.baremetrics.baremetrics import BaremetricsHandler from zulip_bots.bots.baremetrics.baremetrics import BaremetricsHandler
class TestBaremetricsBot(BotTestCase): class TestBaremetricsBot(BotTestCase, DefaultTests):
bot_name = "baremetrics" bot_name = "baremetrics"
def test_bot_responds_to_empty_message(self) -> None: def test_bot_responds_to_empty_message(self) -> None:

View file

@ -1,8 +1,8 @@
from unittest.mock import patch, Mock from unittest.mock import patch, Mock
from zulip_bots.test_lib import StubBotHandler, BotTestCase, get_bot_message_handler from zulip_bots.test_lib import StubBotHandler, BotTestCase, DefaultTests, get_bot_message_handler
from requests.exceptions import ConnectionError from requests.exceptions import ConnectionError
class TestBeeminderBot(BotTestCase): class TestBeeminderBot(BotTestCase, DefaultTests):
bot_name = "beeminder" bot_name = "beeminder"
normal_config = { normal_config = {
"auth_token": "XXXXXX", "auth_token": "XXXXXX",

View file

@ -1,6 +1,6 @@
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
class TestChessBot(BotTestCase): class TestChessBot(BotTestCase, DefaultTests):
bot_name = "chessbot" bot_name = "chessbot"
START_RESPONSE = '''New game! The board looks like this: START_RESPONSE = '''New game! The board looks like this:

View file

@ -1,4 +1,4 @@
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
from contextlib import contextmanager from contextlib import contextmanager
from unittest.mock import MagicMock from unittest.mock import MagicMock
@ -7,7 +7,7 @@ from zulip_bots.game_handler import BadMoveException
from typing import Dict, Any, List from typing import Dict, Any, List
class TestConnectFourBot(BotTestCase): class TestConnectFourBot(BotTestCase, DefaultTests):
bot_name = 'connect_four' bot_name = 'connect_four'
def make_request_message( def make_request_message(

View file

@ -1,8 +1,8 @@
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
from zulip_bots.bots.converter import utils from zulip_bots.bots.converter import utils
class TestConverterBot(BotTestCase): class TestConverterBot(BotTestCase, DefaultTests):
bot_name = "converter" bot_name = "converter"
def test_bot(self) -> None: def test_bot(self) -> None:

View file

@ -1,7 +1,7 @@
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
from unittest.mock import patch from unittest.mock import patch
class TestDefineBot(BotTestCase): class TestDefineBot(BotTestCase, DefaultTests):
bot_name = "define" bot_name = "define"
def test_bot(self) -> None: def test_bot(self) -> None:

View file

@ -1,4 +1,4 @@
from zulip_bots.test_lib import BotTestCase, read_bot_fixture_data from zulip_bots.test_lib import BotTestCase, DefaultTests, read_bot_fixture_data
from contextlib import contextmanager from contextlib import contextmanager
@ -40,7 +40,7 @@ def mock_dialogflow(test_name: str, bot_name: str) -> Any:
mock_text_request.return_value = request mock_text_request.return_value = request
yield yield
class TestDialogFlowBot(BotTestCase): class TestDialogFlowBot(BotTestCase, DefaultTests):
bot_name = 'dialogflow' bot_name = 'dialogflow'
def _test(self, test_name: str, message: str, response: str) -> None: def _test(self, test_name: str, message: str, response: str) -> None:

View file

@ -1,4 +1,4 @@
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
from typing import List from typing import List
from unittest.mock import patch from unittest.mock import patch
@ -73,7 +73,7 @@ def get_help() -> str:
``` ```
''' '''
class TestDropboxBot(BotTestCase): class TestDropboxBot(BotTestCase, DefaultTests):
bot_name = "dropbox_share" bot_name = "dropbox_share"
config_info = {"access_token": "1234567890"} config_info = {"access_token": "1234567890"}

View file

@ -1,6 +1,6 @@
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
class TestEncryptBot(BotTestCase): class TestEncryptBot(BotTestCase, DefaultTests):
bot_name = "encrypt" bot_name = "encrypt"
def test_bot(self) -> None: def test_bot(self) -> None:

View file

@ -1,8 +1,8 @@
from unittest.mock import patch from unittest.mock import patch
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
from requests.exceptions import ConnectionError from requests.exceptions import ConnectionError
class TestFlockBot(BotTestCase): class TestFlockBot(BotTestCase, DefaultTests):
bot_name = "flock" bot_name = "flock"
normal_config = {"token": "12345"} normal_config = {"token": "12345"}

View file

@ -1,13 +1,14 @@
from zulip_bots.test_lib import ( from zulip_bots.test_lib import (
StubBotHandler, StubBotHandler,
BotTestCase, BotTestCase,
DefaultTests,
get_bot_message_handler, get_bot_message_handler,
) )
from typing import Any from typing import Any
class TestFollowUpBot(BotTestCase): class TestFollowUpBot(BotTestCase, DefaultTests):
bot_name = "followup" bot_name = "followup"
def test_followup_stream(self) -> None: def test_followup_stream(self) -> None:

View file

@ -1,8 +1,8 @@
from typing import Any, Dict from typing import Any, Dict
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
class TestFrontBot(BotTestCase): class TestFrontBot(BotTestCase, DefaultTests):
bot_name = 'front' bot_name = 'front'
def make_request_message(self, content: str) -> Dict[str, Any]: def make_request_message(self, content: str) -> Dict[str, Any]:
@ -49,7 +49,7 @@ class TestFrontBot(BotTestCase):
with self.mock_http_conversation('comment'): with self.mock_http_conversation('comment'):
self.verify_reply("comment " + body, "Comment was sent.") self.verify_reply("comment " + body, "Comment was sent.")
class TestFrontBotWrongTopic(BotTestCase): class TestFrontBotWrongTopic(BotTestCase, DefaultTests):
bot_name = 'front' bot_name = 'front'
def make_request_message(self, content: str) -> Dict[str, Any]: def make_request_message(self, content: str) -> Dict[str, Any]:

View file

@ -1,4 +1,4 @@
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
from zulip_bots.game_handler import GameInstance from zulip_bots.game_handler import GameInstance
from contextlib import contextmanager from contextlib import contextmanager
@ -7,7 +7,7 @@ from mock import MagicMock, patch
from typing import Any, Dict, List from typing import Any, Dict, List
class TestGameHandlerBot(BotTestCase): class TestGameHandlerBot(BotTestCase, DefaultTests):
bot_name = 'game_handler_bot' bot_name = 'game_handler_bot'
def make_request_message( def make_request_message(

View file

@ -1,4 +1,4 @@
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
from contextlib import contextmanager from contextlib import contextmanager
from unittest.mock import MagicMock from unittest.mock import MagicMock
@ -7,7 +7,7 @@ from zulip_bots.game_handler import BadMoveException
from typing import Dict, Any, List, Tuple from typing import Dict, Any, List, Tuple
class TestGameOfFifteenBot(BotTestCase): class TestGameOfFifteenBot(BotTestCase, DefaultTests):
bot_name = 'game_of_fifteen' bot_name = 'game_of_fifteen'
def make_request_message( def make_request_message(

View file

@ -2,9 +2,9 @@ from unittest.mock import patch, MagicMock
from requests.exceptions import HTTPError, ConnectionError from requests.exceptions import HTTPError, ConnectionError
from typing import Any, Union from typing import Any, Union
from zulip_bots.test_lib import StubBotHandler, BotTestCase, get_bot_message_handler from zulip_bots.test_lib import StubBotHandler, BotTestCase, DefaultTests, get_bot_message_handler
class TestGiphyBot(BotTestCase): class TestGiphyBot(BotTestCase, DefaultTests):
bot_name = "giphy" bot_name = "giphy"
# Test for bot response to empty message # Test for bot response to empty message

View file

@ -1,12 +1,13 @@
from zulip_bots.test_lib import ( from zulip_bots.test_lib import (
StubBotHandler, StubBotHandler,
BotTestCase, BotTestCase,
DefaultTests,
get_bot_message_handler, get_bot_message_handler,
) )
from typing import Any from typing import Any
class TestGithubDetailBot(BotTestCase): class TestGithubDetailBot(BotTestCase, DefaultTests):
bot_name = "github_detail" bot_name = "github_detail"
mock_config = {'owner': 'zulip', 'repo': 'zulip'} mock_config = {'owner': 'zulip', 'repo': 'zulip'}
empty_config = {'owner': '', 'repo': ''} empty_config = {'owner': '', 'repo': ''}

View file

@ -1,8 +1,8 @@
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
from unittest.mock import patch from unittest.mock import patch
class TestGoogleSearchBot(BotTestCase): class TestGoogleSearchBot(BotTestCase, DefaultTests):
bot_name = 'google_search' bot_name = 'google_search'
# Simple query # Simple query

View file

@ -1,7 +1,7 @@
from unittest.mock import patch from unittest.mock import patch
from requests.exceptions import ConnectionError from requests.exceptions import ConnectionError
from zulip_bots.test_lib import BotTestCase, StubBotHandler from zulip_bots.test_lib import BotTestCase, DefaultTests, StubBotHandler
from zulip_bots.bots.google_translate.google_translate import TranslateError from zulip_bots.bots.google_translate.google_translate import TranslateError
help_text = ''' help_text = '''
@ -11,7 +11,7 @@ Please format your message like:
Visit [here](https://cloud.google.com/translate/docs/languages) for all languages Visit [here](https://cloud.google.com/translate/docs/languages) for all languages
''' '''
class TestGoogleTranslateBot(BotTestCase): class TestGoogleTranslateBot(BotTestCase, DefaultTests):
bot_name = "google_translate" bot_name = "google_translate"
def _test(self, message, response, http_config_fixture, http_fixture=None): def _test(self, message, response, http_config_fixture, http_fixture=None):

View file

@ -1,6 +1,6 @@
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
class TestHelpBot(BotTestCase): class TestHelpBot(BotTestCase, DefaultTests):
bot_name = "helloworld" # type: str bot_name = "helloworld" # type: str
def test_bot(self) -> None: def test_bot(self) -> None:

View file

@ -1,8 +1,8 @@
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
from typing import Any from typing import Any
class TestHelpBot(BotTestCase): class TestHelpBot(BotTestCase, DefaultTests):
bot_name = "help" bot_name = "help"
def test_bot(self) -> None: def test_bot(self) -> None:

View file

@ -1,10 +1,10 @@
from unittest.mock import patch from unittest.mock import patch
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
import requests import requests
class TestIDoneThisBot(BotTestCase): class TestIDoneThisBot(BotTestCase, DefaultTests):
bot_name = "idonethis" # type: str bot_name = "idonethis" # type: str
def test_create_entry_default_team(self) -> None: def test_create_entry_default_team(self) -> None:

View file

@ -3,10 +3,11 @@ from unittest import mock
from zulip_bots.test_lib import ( from zulip_bots.test_lib import (
get_bot_message_handler, get_bot_message_handler,
StubBotHandler, StubBotHandler,
DefaultTests,
BotTestCase, BotTestCase,
) )
class TestIncrementorBot(BotTestCase): class TestIncrementorBot(BotTestCase, DefaultTests):
bot_name = "incrementor" bot_name = "incrementor"
def test_bot(self) -> None: def test_bot(self) -> None:

View file

@ -1,7 +1,7 @@
from unittest.mock import patch from unittest.mock import patch
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
class TestJiraBot(BotTestCase): class TestJiraBot(BotTestCase, DefaultTests):
bot_name = 'jira' bot_name = 'jira'
MOCK_CONFIG_INFO = { MOCK_CONFIG_INFO = {

View file

@ -1,10 +1,10 @@
from unittest.mock import patch from unittest.mock import patch
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
from zulip_bots.test_lib import StubBotHandler from zulip_bots.test_lib import StubBotHandler
from zulip_bots.bots.link_shortener.link_shortener import LinkShortenerHandler from zulip_bots.bots.link_shortener.link_shortener import LinkShortenerHandler
class TestLinkShortenerBot(BotTestCase): class TestLinkShortenerBot(BotTestCase, DefaultTests):
bot_name = "link_shortener" bot_name = "link_shortener"
def _test(self, message: str, response: str) -> None: def _test(self, message: str, response: str) -> None:

View file

@ -1,9 +1,9 @@
from zulip_bots.bots.mention.mention import MentionHandler from zulip_bots.bots.mention.mention import MentionHandler
from unittest.mock import patch from unittest.mock import patch
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
from zulip_bots.test_lib import StubBotHandler from zulip_bots.test_lib import StubBotHandler
class TestMentionBot(BotTestCase): class TestMentionBot(BotTestCase, DefaultTests):
bot_name = "mention" bot_name = "mention"
def test_bot_responds_to_empty_message(self) -> None: def test_bot_responds_to_empty_message(self) -> None:

View file

@ -10,7 +10,7 @@ import zulip_bots.bots.merels.merels
import zulip_bots.test_lib import zulip_bots.test_lib
class TestFollowUpBot(zulip_bots.test_lib.BotTestCase): class TestFollowUpBot(zulip_bots.test_lib.BotTestCase, DefaultTests):
bot_name = "merels" bot_name = "merels"
def test_no_command(self): def test_no_command(self):

View file

@ -2,13 +2,13 @@ import unittest
from unittest import mock from unittest import mock
from importlib import import_module from importlib import import_module
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
# TODO: Figure out a way to test bots that depends # TODO: Figure out a way to test bots that depends
# on the Python version of the environment. # on the Python version of the environment.
@unittest.skip("Fails on Python3.4.") @unittest.skip("Fails on Python3.4.")
class TestMonkeyTestitBot(BotTestCase): class TestMonkeyTestitBot(BotTestCase, DefaultTests):
bot_name = "monkeytestit" bot_name = "monkeytestit"
def setUp(self): def setUp(self):

View file

@ -1,4 +1,4 @@
from zulip_bots.test_lib import BotTestCase, StubBotHandler, read_bot_fixture_data from zulip_bots.test_lib import BotTestCase, DefaultTests, StubBotHandler, read_bot_fixture_data
import simple_salesforce import simple_salesforce
from simple_salesforce.exceptions import SalesforceAuthenticationFailed from simple_salesforce.exceptions import SalesforceAuthenticationFailed
from contextlib import contextmanager from contextlib import contextmanager
@ -107,7 +107,7 @@ mock_object_types = {
} }
class TestSalesforceBot(BotTestCase): class TestSalesforceBot(BotTestCase, DefaultTests):
bot_name = "salesforce" # type: str bot_name = "salesforce" # type: str
def _test(self, test_name: str, message: str, response: str, auth_success: bool=True) -> None: def _test(self, test_name: str, message: str, response: str, auth_success: bool=True) -> None:

View file

@ -1,7 +1,7 @@
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
from zulip_bots.request_test_lib import mock_request_exception from zulip_bots.request_test_lib import mock_request_exception
class TestStackoverflowBot(BotTestCase): class TestStackoverflowBot(BotTestCase, DefaultTests):
bot_name = "stack_overflow" bot_name = "stack_overflow"
def test_bot(self) -> None: def test_bot(self) -> None:

View file

@ -1,10 +1,11 @@
from zulip_bots.test_lib import ( from zulip_bots.test_lib import (
BotTestCase, BotTestCase,
DefaultTests,
) )
from typing import Any from typing import Any
class TestSusiBot(BotTestCase): class TestSusiBot(BotTestCase, DefaultTests):
bot_name = "susi" bot_name = "susi"
def test_help(self) -> None: def test_help(self) -> None:

View file

@ -1,11 +1,11 @@
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
from zulip_bots.game_handler import GameInstance from zulip_bots.game_handler import GameInstance
from unittest.mock import patch from unittest.mock import patch
from typing import List, Tuple, Any from typing import List, Tuple, Any
class TestTicTacToeBot(BotTestCase): class TestTicTacToeBot(BotTestCase, DefaultTests):
bot_name = 'tictactoe' bot_name = 'tictactoe'
# FIXME: Add tests for computer moves # FIXME: Add tests for computer moves

View file

@ -1,7 +1,7 @@
from unittest.mock import patch from unittest.mock import patch
from zulip_bots.bots.trello.trello import TrelloHandler from zulip_bots.bots.trello.trello import TrelloHandler
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
from zulip_bots.test_lib import StubBotHandler from zulip_bots.test_lib import StubBotHandler
mock_config = { mock_config = {
@ -10,7 +10,7 @@ mock_config = {
'user_name': 'TEST' 'user_name': 'TEST'
} }
class TestTrelloBot(BotTestCase): class TestTrelloBot(BotTestCase, DefaultTests):
bot_name = "trello" # type: str bot_name = "trello" # type: str
def test_bot_responds_to_empty_message(self) -> None: def test_bot_responds_to_empty_message(self) -> None:

View file

@ -5,6 +5,7 @@ from typing import Optional
from zulip_bots.test_lib import ( from zulip_bots.test_lib import (
BotTestCase, BotTestCase,
DefaultTests,
read_bot_fixture_data, read_bot_fixture_data,
) )
@ -12,7 +13,7 @@ from zulip_bots.bots.trivia_quiz.trivia_quiz import (
get_quiz_from_payload, get_quiz_from_payload,
) )
class TestTriviaQuizBot(BotTestCase): class TestTriviaQuizBot(BotTestCase, DefaultTests):
bot_name = "trivia_quiz" # type: str bot_name = "trivia_quiz" # type: str
new_question_response = '\nQ: Which class of animals are newts members of?\n\n' + \ new_question_response = '\nQ: Which class of animals are newts members of?\n\n' + \

View file

@ -1,6 +1,7 @@
from zulip_bots.test_lib import ( from zulip_bots.test_lib import (
StubBotHandler, StubBotHandler,
BotTestCase, BotTestCase,
DefaultTests,
get_bot_message_handler, get_bot_message_handler,
) )
from zulip_bots.test_file_utils import ( from zulip_bots.test_file_utils import (
@ -12,7 +13,7 @@ import os
import json import json
class TestTwitpostBot(BotTestCase): class TestTwitpostBot(BotTestCase, DefaultTests):
bot_name = "twitpost" bot_name = "twitpost"
mock_config = {'consumer_key': 'abcdefghijklmnopqrstuvwxy', mock_config = {'consumer_key': 'abcdefghijklmnopqrstuvwxy',
'consumer_secret': 'aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyy', 'consumer_secret': 'aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyy',

View file

@ -1,8 +1,8 @@
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
from zulip_bots.bots.virtual_fs.virtual_fs import sample_conversation from zulip_bots.bots.virtual_fs.virtual_fs import sample_conversation
from unittest.mock import patch from unittest.mock import patch
class TestVirtualFsBot(BotTestCase): class TestVirtualFsBot(BotTestCase, DefaultTests):
bot_name = "virtual_fs" bot_name = "virtual_fs"
help_txt = ('foo@example.com:\n\nThis bot implements a virtual file system for a stream.\n' help_txt = ('foo@example.com:\n\nThis bot implements a virtual file system for a stream.\n'
'The locations of text are persisted for the lifetime of the bot\n' 'The locations of text are persisted for the lifetime of the bot\n'

View file

@ -1,9 +1,9 @@
from unittest.mock import patch from unittest.mock import patch
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
from typing import Optional from typing import Optional
class TestWeatherBot(BotTestCase): class TestWeatherBot(BotTestCase, DefaultTests):
bot_name = "weather" bot_name = "weather"
help_content = ''' help_content = '''

View file

@ -1,7 +1,7 @@
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
from zulip_bots.request_test_lib import mock_request_exception from zulip_bots.request_test_lib import mock_request_exception
class TestWikipediaBot(BotTestCase): class TestWikipediaBot(BotTestCase, DefaultTests):
bot_name = "wikipedia" bot_name = "wikipedia"
def test_bot(self) -> None: def test_bot(self) -> None:

View file

@ -1,9 +1,9 @@
from unittest.mock import patch from unittest.mock import patch
import sys import sys
from typing import Dict, Any, Optional from typing import Dict, Any, Optional
from zulip_bots.test_lib import BotTestCase, get_bot_message_handler, StubBotHandler from zulip_bots.test_lib import BotTestCase, DefaultTests, get_bot_message_handler, StubBotHandler
class TestWitaiBot(BotTestCase): class TestWitaiBot(BotTestCase, DefaultTests):
bot_name = 'witai' bot_name = 'witai'
MOCK_CONFIG_INFO = { MOCK_CONFIG_INFO = {

View file

@ -1,8 +1,8 @@
from unittest import mock from unittest import mock
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
class TestXkcdBot(BotTestCase): class TestXkcdBot(BotTestCase, DefaultTests):
bot_name = "xkcd" bot_name = "xkcd"
def test_latest_command(self) -> None: def test_latest_command(self) -> None:

View file

@ -1,9 +1,9 @@
from zulip_bots.bots.yoda.yoda import ServiceUnavailableError from zulip_bots.bots.yoda.yoda import ServiceUnavailableError
from zulip_bots.test_lib import BotTestCase from zulip_bots.test_lib import BotTestCase, DefaultTests
from typing import Optional from typing import Optional
class TestYodaBot(BotTestCase): class TestYodaBot(BotTestCase, DefaultTests):
bot_name = "yoda" bot_name = "yoda"
help_text = ''' help_text = '''

View file

@ -1,9 +1,9 @@
from unittest.mock import patch from unittest.mock import patch
from requests.exceptions import HTTPError, ConnectionError from requests.exceptions import HTTPError, ConnectionError
from zulip_bots.test_lib import StubBotHandler, BotTestCase, get_bot_message_handler from zulip_bots.test_lib import StubBotHandler, BotTestCase, DefaultTests, get_bot_message_handler
from typing import Any, Union, Dict from typing import Any, Union, Dict
class TestYoutubeBot(BotTestCase): class TestYoutubeBot(BotTestCase, DefaultTests):
bot_name = "youtube" bot_name = "youtube"
normal_config = {'key': '12345678', normal_config = {'key': '12345678',
'number_of_results': '5', 'number_of_results': '5',

View file

@ -88,6 +88,29 @@ class StubBotHandler:
raise Exception('The bot is giving too many responses for some reason.') raise Exception('The bot is giving too many responses for some reason.')
class DefaultTests:
bot_name = ''
def make_request_message(self, content: str) -> Dict[str, Any]:
raise NotImplementedError()
def get_response(self, message: Dict[str, Any]) -> Dict[str, Any]:
raise NotImplementedError()
def test_bot_usage(self) -> None:
bot = get_bot_message_handler(self.bot_name)
assert bot.usage() != ''
def test_bot_responds_to_empty_message(self) -> None:
message = self.make_request_message('')
# get_response will fail if we don't respond at all
response = self.get_response(message)
# we also want a non-blank response
assert len(response['content']) >= 1
class BotTestCase(unittest.TestCase): class BotTestCase(unittest.TestCase):
bot_name = '' bot_name = ''
@ -154,19 +177,6 @@ class BotTestCase(unittest.TestCase):
bot_class = type(get_bot_message_handler(self.bot_name)) bot_class = type(get_bot_message_handler(self.bot_name))
bot_class.validate_config(config_data) bot_class.validate_config(config_data)
def test_bot_usage(self) -> None:
bot = get_bot_message_handler(self.bot_name)
self.assertNotEqual(bot.usage(), '')
def test_bot_responds_to_empty_message(self) -> None:
message = self.make_request_message('')
# get_response will fail if we don't respond at all
response = self.get_response(message)
# we also want a non-blank response
self.assertTrue(len(response['content']) >= 1)
def mock_http_conversation(self, test_name: str) -> Any: def mock_http_conversation(self, test_name: str) -> Any:
assert test_name is not None assert test_name is not None
http_data = read_bot_fixture_data(self.bot_name, test_name) http_data = read_bot_fixture_data(self.bot_name, test_name)