From 205f7c16c7f1ee7b3ddd0e51bb18b323006ba6ce Mon Sep 17 00:00:00 2001
From: Steve Howell <showell@zulipchat.com>
Date: Thu, 30 Nov 2017 14:09:28 -0800
Subject: [PATCH] Add StubBotTestCase and StubBotHandler.

We will start to use these for some of our bot test code.
---
 tools/test-bots                   |  2 +-
 zulip_bots/zulip_bots/test_lib.py | 59 +++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/tools/test-bots b/tools/test-bots
index c298bdb8..de28bbbb 100755
--- a/tools/test-bots
+++ b/tools/test-bots
@@ -98,7 +98,7 @@ def main():
         for test in tests:
             if isinstance(test, TestCase):
                 # Exclude test base class from being tested.
-                if test.__class__.__name__ not in ['BotTestCase', 'BotTestCaseBase']:
+                if test.__class__.__name__ not in ['StubBotTestCase', 'BotTestCase', 'BotTestCaseBase']:
                     filtered_tests.addTest(test)
             else:
                 filtered_tests.addTest(filter_tests(test))
diff --git a/zulip_bots/zulip_bots/test_lib.py b/zulip_bots/zulip_bots/test_lib.py
index 1d7691e3..f499a661 100755
--- a/zulip_bots/zulip_bots/test_lib.py
+++ b/zulip_bots/zulip_bots/test_lib.py
@@ -26,6 +26,65 @@ from types import ModuleType
 
 from copy import deepcopy
 
+from zulip_bots.simple_lib import (
+    SimpleStorage,
+    SimpleMessageServer,
+)
+
+class StubBotHandler:
+    def __init__(self):
+        # type: () -> None
+        self.storage = SimpleStorage()
+        self.message_server = SimpleMessageServer()
+        self.sent_messages = []  # type: List[Dict[str, Any]]
+
+    def send_message(self, message):
+        # type: (Dict[str, Any]) -> Dict[str, Any]
+        self.sent_messages.append(message)
+        self.sent_messages.append(message)
+        return self.message_server.send(message)
+
+    def send_reply(self, message, response):
+        # type: (Dict[str, Any], str) -> Dict[str, Any]
+        response_message = dict(
+            content=response
+        )
+        self.sent_messages.append(response_message)
+        return self.message_server.send(response_message)
+
+    def update_message(self, message):
+        # type: (Dict[str, Any]) -> None
+        self.message_server.update(message)
+
+    def last_test_response(self):
+        # type: () -> Dict[str, Any]
+        return self.sent_messages[-1]
+
+class StubBotTestCase(TestCase):
+    '''
+    The goal for this class is to eventually replace
+    BotTestCaseBase for places where we may want more
+    fine-grained control and less heavy setup.
+    '''
+
+    bot_name = ''
+
+    def verify_dialog(self, conversation):
+        # type: (List[Tuple[str, str]]) -> None
+
+        # Start a new message handler for the full conversation.
+        bot = get_bot_message_handler(self.bot_name)
+        bot_handler = StubBotHandler()
+
+        for (request, expected_response) in conversation:
+            message = dict(
+                sender_email='foo@example.com',
+                content=request,
+            )
+            bot.handle_message(message, bot_handler)
+            response = bot_handler.last_test_response()
+            self.assertEqual(expected_response, response['content'])
+
 def get_bot_message_handler(bot_name):
     # type: (str) -> Any
     # message_handler is of type 'Any', since it can contain any bot's