File size: 3,136 Bytes
31add3b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import pytest
from unittest.mock import MagicMock, patch
from unittest.mock import AsyncMock

@pytest.fixture
def mock_chat_openai():
    """Fixture to mock langchain_openai.ChatOpenAI."""
    mock = MagicMock()
    # Simulate the behavior of the ChatOpenAI constructor if needed
    mock.return_value = MagicMock() 
    return mock

@pytest.fixture
def mock_cl():
    """Fixture to mock the chainlit library."""
    mock = MagicMock() # Removed spec=True
    mock.__name__ = "chainlit" # Act more like a module
    # mock.__file__ = "mocked_chainlit.py" # Another common module attribute

    # Mock specific chainlit attributes or methods if tests rely on them
    mock.user_session = MagicMock()
    mock.user_session.set = MagicMock()
    mock.Message = MagicMock()
    # Ensure send() is an AsyncMock if it needs to be awaited and its result checked
    mock.Message.return_value.send = AsyncMock() 

    # Mock cl.Action as it will be instantiated by the app
    mock.Action = MagicMock() # Allows app to call cl.Action(...)

    # Mock cl.Select as it will be instantiated by the app for persona choices
    mock.Select = MagicMock() # Allows app to call cl.Select(...)

    # Mock cl.Switch for UI toggles
    mock.Switch = MagicMock()

    # Mock cl.ChatSettings for UI settings panel
    mock.ChatSettings = MagicMock() # Mock the ChatSettings class
    # Ensure the instance returned by ChatSettings() has an async send method
    mock.ChatSettings.return_value.send = AsyncMock()

    # Mock decorators like on_chat_start and on_message
    # They need to be callable and return the function they decorate.
    mock.on_chat_start = MagicMock(side_effect=lambda func: func)
    mock.on_message = MagicMock(side_effect=lambda func: func)
    
    return mock

@pytest.fixture
def mock_dotenv_load():
    """Fixture to mock dotenv.load_dotenv."""
    mock = MagicMock()
    return mock

# It's good practice to also provide the mock StateGraph classes here
# if they are used across multiple test files for langgraph setup.

@pytest.fixture
def mock_state_graph_instance():
    """Returns a mock instance of StateGraph, typically the one returned by the class mock."""
    instance = MagicMock(spec=['add_node', 'set_entry_point', 'add_conditional_edges', 'add_edge', 'compile'])
    # If add_node returns self or another mock, configure here if needed for chaining
    return instance

@pytest.fixture
def mock_state_graph_class(mock_state_graph_instance):
    """Fixture to mock the StateGraph class itself."""
    mock = MagicMock(return_value=mock_state_graph_instance)
    return mock 

@pytest.fixture
def mock_chainlit_context(mock_cl): # Depends on mock_cl to use its user_session mock
    """Mocks chainlit.context.context_var.get() to return a mock context with a session."""
    mock_context_obj = MagicMock(name="MockChainlitContextObject")
    # Use the same user_session mock from the mock_cl fixture for consistency
    mock_context_obj.session = mock_cl.user_session 

    with patch('chainlit.context.context_var.get', return_value=mock_context_obj) as mock_context_var_get:
        yield mock_context_var_get