bot tests: Remove BotTestCase.
All of the functionality of BotTestCase was either directly
moved to StubBotTestCase or replaced by similar functions,
and all bots have been ported to StubBotTestCase.
MODIFY
zulip_bots/zulip_bots/test_lib.py
zulip_bots/zulip_bots/test_lib.py
@@ -24,8 +24,6 @@ from unittest import TestCase
from typing import List, Dict, Any, Optional, Callable, Tuple
from types import ModuleType
-from copy import deepcopy
-
from zulip_bots.simple_lib import (
SimpleStorage,
SimpleMessageServer,
@@ -274,115 +272,3 @@ def mock_request_exception():
mock_get.side_effect = requests.exceptions.RequestException
yield
assert_mock_called(mock_get)
-
-class BotTestCase(StubBotTestCase):
- """Test class for common Bot test helper methods"""
- bot_name = '' # type: str
-
- def setUp(self):
- # type: () -> None
- # Mocking ExternalBotHandler
- self.patcher = patch('zulip_bots.lib.ExternalBotHandler', autospec=True)
- self.MockClass = self.patcher.start()
- self.mock_bot_handler = self.MockClass(None, None, None, None)
- self.mock_client = MagicMock()
- self.mock_client.get_storage.return_value = {'result': 'success', 'storage': {}}
- self.mock_client.update_storage.return_value = {'result': 'success'}
- self.mock_bot_handler.storage = StateHandler(self.mock_client)
- self.message_handler = get_bot_message_handler(self.bot_name)
-
- def tearDown(self):
- # type: () -> None
- self.patcher.stop()
-
- def initialize_bot(self):
- # type: () -> None
- self.message_handler.initialize(self.mock_bot_handler)
-
- def check_expected_responses(self, expectations, expected_method='send_reply',
- email="foo_sender@zulip.com", recipient="foo", subject="foo",
- sender_id=0, sender_full_name="Foo Bar", type="all"):
- # type: (List[Tuple[str, Any]], str, str, str, str, int, str, str) -> None
- # To test send_message, Any would be a Dict type,
- # to test send_reply, Any would be a str type.
- if type not in ["private", "stream", "all"]:
- logging.exception("check_expected_response expects type to be 'private', 'stream' or 'all'")
-
- private_message_template = {'type': "private", 'display_recipient': recipient,
- 'sender_email': email, 'sender_id': sender_id,
- 'sender_full_name': sender_full_name}
- stream_message_template = {'type': "stream", 'display_recipient': recipient,
- 'subject': subject, 'sender_email': email, 'sender_id': sender_id,
- 'sender_full_name': sender_full_name}
-
- message_templates = []
- if type in ["private", "all"]:
- message_templates.append(private_message_template)
- if type in ["stream", "all"]:
- message_templates.append(stream_message_template)
-
- initial_storage = deepcopy(self.mock_bot_handler.storage)
- for message_template in message_templates:
- # A new copy of the StateHandler is used for every new conversation with a
- # different base template. This avoids type="all" failing if the created state
- # of a prior conversation influences the current one.
- self.mock_bot_handler.storage = deepcopy(initial_storage)
- for m, r in expectations:
- # For calls with send_reply, r is a string (the content of a message),
- # so we need to add it to a Dict as the value of 'content'.
- # For calls with send_message, r is already a Dict.
- message = dict(message_template, content = m)
- response = {'content': r} if expected_method == 'send_reply' else r
- self.assert_bot_responses(message, (response, expected_method))
-
- def call_request(self, message, *responses):
- # type: (Dict[str, Any], *Tuple[Dict[str, Any], str]) -> None
-
- # Mock BotHandler; get instance
- instance = self.MockClass.return_value
-
- # Send message to the bot
- try:
- self.message_handler.handle_message(message, self.mock_bot_handler)
- except KeyError as key_err:
- raise Exception("Message tested likely required key {}.".format(key_err))
-
- # Determine which messaging functions are expected
- send_messages = [call(r[0]) for r in responses if r[1] == 'send_message']
- send_replies = [call(message, r[0]['content']) for r in responses if r[1] == 'send_reply']
-
- # Test that call were matching in quantity, and then in details
- fail_template = "\nMESSAGE:\n{}\nACTUAL CALLS:\n{}\nEXPECTED:\n{}\n"
- functions_to_test = (('send_message', instance.send_message, send_messages),
- ('send_reply', instance.send_reply, send_replies))
- for version, actual, expected in functions_to_test:
- assert len(expected) == actual.call_count, (
- "Numbers of '{}' called do not match those expected ({} calls, {} expected)" +
- fail_template).format(version, actual.call_count, len(expected),
- message, actual.call_args_list, expected)
- if len(expected) > 0:
- try:
- actual.assert_has_calls(expected)
- except AssertionError:
- raise AssertionError(
- ("Calls to '{}' do not match those expected" +
- fail_template).format(version,
- message, actual.call_args_list, expected))
- actual.reset_mock() # Ensure the call details are reset
-
- @contextmanager
- def mock_config_info(self, config_info):
- # type: (Dict[str, str]) -> Any
- self.mock_bot_handler.get_config_info.return_value = config_info
- yield
- self.mock_bot_handler.get_config_info.return_value = None
-
- def assert_bot_response(self, message, response, expected_method):
- # type: (Dict[str, Any], Dict[str, Any], str) -> None
- # Strictly speaking, this function is not needed anymore,
- # kept for now for legacy reasons.
- self.call_request(message, (response, expected_method))
-
- def assert_bot_responses(self, message, *response_list):
- # type: (Dict[str, Any], *Tuple[Dict[str, Any], str]) -> None
- self.call_request(message, *response_list)

bot tests: Remove BotTestCase.

All of the functionality of BotTestCase was either directly
moved to StubBotTestCase or replaced by similar functions,
and all bots have been ported to StubBotTestCase.