bots: Refactor and simplify bot_test_lib.py.
This commit integrates the mock_test function in check_expected_responses and makes this function usable for simple tests only by not allowing mock http conversations. assert_bot_response() is now used for single message-response pairs, resolving potential issues with multiple messages and a single http request-response pair. The giphy bot test file is updated accordingly.
This commit is contained in:
		
							parent
							
								
									894a816618
								
							
						
					
					
						commit
						8f2fc6069d
					
				
					 2 changed files with 46 additions and 61 deletions
				
			
		|  | @ -51,11 +51,10 @@ class TestGiphyBot(BotTestCase): | |||
|         # This message calls `send_reply` function of BotHandlerApi | ||||
|         keyword = "Hello" | ||||
|         gif_url = "https://media4.giphy.com/media/3o6ZtpxSZbQRRnwCKQ/giphy.gif" | ||||
|         expectations = { | ||||
|             keyword: get_bot_response(gif_url) | ||||
|         } | ||||
|         self.check_expected_responses( | ||||
|             expectations=expectations, | ||||
|         self.assert_bot_response( | ||||
|             message = {'content': keyword}, | ||||
|             response = {'content': get_bot_response(gif_url)}, | ||||
|             expected_method='send_reply', | ||||
|             http_request=get_http_request(keyword), | ||||
|             http_response=get_http_response_json(gif_url) | ||||
|         ) | ||||
|  |  | |||
|  | @ -29,38 +29,25 @@ class BotTestCase(TestCase): | |||
| 
 | ||||
|     def check_expected_responses(self, expectations, expected_method='send_reply', | ||||
|                                  email="foo_sender@zulip.com", recipient="foo", subject="foo", | ||||
|                                  type="all", http_request=None, http_response=None): | ||||
|         # type: (Dict[str, Any], str, str, str, str, str, Dict[str, Any], Dict[str, Any]) -> None | ||||
|                                  type="all"): | ||||
|         # type: (Dict[str, Any], str, str, str, 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'") | ||||
|         for m, r in expectations.items(): | ||||
|             # 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. | ||||
|             response = {'content': r} if expected_method == 'send_reply' else r | ||||
|             if type != "stream": | ||||
|                 self.mock_test( | ||||
|                     messages={'content': m, 'type': "private", 'display_recipient': recipient, | ||||
|                               'sender_email': email}, bot_response=r, expected_method=expected_method, | ||||
|                     http_request=http_request, http_response=http_response) | ||||
|                 message = {'content': m, 'type': "private", 'display_recipient': recipient, | ||||
|                            'sender_email': email} | ||||
|                 self.assert_bot_response(message=message, response=response, expected_method=expected_method) | ||||
|             if type != "private": | ||||
|                 self.mock_test( | ||||
|                     messages={'content': m, 'type': "stream", 'display_recipient': recipient, | ||||
|                               'subject': subject, 'sender_email': email}, bot_response=r, | ||||
|                     expected_method=expected_method, http_request=http_request, http_response=http_response) | ||||
| 
 | ||||
|     def mock_test(self, messages, bot_response, expected_method, | ||||
|                   http_request=None, http_response=None): | ||||
|         # type: (Dict[str, str], Any, str, Dict[str, Any], Dict[str, Any]) -> None | ||||
|         if expected_method == "send_message": | ||||
|             # Since send_message function uses bot_response of type Dict, no | ||||
|             # further changes required. | ||||
|             self.assert_bot_output(messages=[messages], bot_response=[bot_response], expected_method=expected_method, | ||||
|                                    http_request=http_request, http_response=http_response) | ||||
|         else: | ||||
|             # Since send_reply function uses bot_response of type str, we | ||||
|             # do convert the str type to a Dict type to have the same assert_bot_output function. | ||||
|             bot_response_type_dict = {'content': bot_response} | ||||
|             self.assert_bot_output(messages=[messages], bot_response=[bot_response_type_dict], expected_method=expected_method, | ||||
|                                    http_request=http_request, http_response=http_response) | ||||
|                 message = {'content': m, 'type': "stream", 'display_recipient': recipient, | ||||
|                            'subject': subject, 'sender_email': email} | ||||
|                 self.assert_bot_response(message=message, response=response, expected_method=expected_method) | ||||
| 
 | ||||
|     def get_bot_message_handler(self): | ||||
|         # type: () -> Any | ||||
|  | @ -75,7 +62,7 @@ class BotTestCase(TestCase): | |||
| 
 | ||||
|     def call_request(self, message_handler, message, expected_method, | ||||
|                      MockClass, response): | ||||
|         # type: (Any, Dict[str, Any], str, Any, Optional[Dict[str, Any]]) -> None | ||||
|         # type: (Any, Dict[str, Any], str, Any, Dict[str, Any]) -> None | ||||
|         # Send message to the concerned bot | ||||
|         message_handler.handle_message(message, MockClass(), StateHandler()) | ||||
| 
 | ||||
|  | @ -87,13 +74,12 @@ class BotTestCase(TestCase): | |||
|         else: | ||||
|             instance.send_reply.assert_called_with(message, response['content']) | ||||
| 
 | ||||
|     def assert_bot_output(self, messages, bot_response, expected_method, | ||||
|     def assert_bot_response(self, message, response, expected_method, | ||||
|                             http_request=None, http_response=None): | ||||
|         # type: (List[Dict[str, Any]], List[Dict[str, str]], str, Optional[Dict[str, Any]], Optional[Dict[str, Any]]) -> None | ||||
|         # type: (Dict[str, Any], Dict[str, Any], str, Optional[Dict[str, Any]], Optional[Dict[str, Any]]) -> None | ||||
|         message_handler = self.get_bot_message_handler() | ||||
|         # Mocking BotHandlerApi | ||||
|         with patch('bots_api.bot_lib.BotHandlerApi') as MockClass: | ||||
|             for (message, response) in zip(messages, bot_response): | ||||
|             # If not mock http_request/http_response are provided, | ||||
|             # just call the request normally (potentially using | ||||
|             # the Internet) | ||||
|  | @ -101,7 +87,7 @@ class BotTestCase(TestCase): | |||
|                 assert http_request is None | ||||
|                 self.call_request(message_handler, message, expected_method, | ||||
|                                   MockClass, response) | ||||
|                     continue | ||||
|                 return | ||||
| 
 | ||||
|             # Otherwise, we mock requests, and verify that the bot | ||||
|             # made the correct HTTP request to the third-party API | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 derAnfaenger
						derAnfaenger