import unittest
from unittest.mock import MagicMock, patch
from slack_bot.dispatcher import MessageDispatcher

class TestDispatcher(unittest.TestCase):
    @patch("slack_bot.dispatcher.WebClient")
    @patch("slack_bot.dispatcher.GeminiLLM")
    @patch("slack_bot.dispatcher.ContextStorage")
    def test_dispatch_flow(self, mock_storage_cls, mock_llm_cls, mock_client_cls):
        # Setup mocks
        mock_client = MagicMock()
        mock_client_cls.return_value = mock_client
        
        mock_llm = MagicMock()
        mock_llm_cls.return_value = mock_llm
        # Return text and no tool calls
        mock_llm.generate_response.return_value = ("Hello World", None)
        
        mock_storage = MagicMock()
        mock_storage_cls.return_value = mock_storage
        # Mock get_context to return empty list
        mock_storage.get_context.return_value = []

        # Initialize
        dispatcher = MessageDispatcher()
        
        # Test Dispatch
        dispatcher.dispatch("Hi", "C123", "U456")
        
        # Verify Context Added (User message)
        mock_storage.add_message.assert_any_call("user", "Hi")
        
        # Verify LLM Called
        mock_llm.generate_response.assert_called_once()
        
        # Verify Reply Posted
        mock_client.chat_postMessage.assert_called_with(
            channel="C123",
            text="Hello World"
        )
        
        # Verify Reply Saved to Context (Assistant message)
        mock_storage.add_message.assert_any_call("assistant", "Hello World", model="gemini")

if __name__ == '__main__':
    unittest.main()
