91 lines
3.3 KiB
Python
91 lines
3.3 KiB
Python
import os
|
|
import sys
|
|
import pytest
|
|
from unittest.mock import MagicMock, patch
|
|
from streamlit.testing.v1 import AppTest
|
|
from langchain_core.messages import AIMessage
|
|
|
|
# Ensure src is in python path
|
|
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../src')))
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def mock_history_manager():
|
|
"""Globally mock HistoryManager to avoid DB calls during AppTest."""
|
|
with patch("ea_chatbot.history.manager.HistoryManager") as mock_cls:
|
|
instance = mock_cls.return_value
|
|
instance.create_conversation.return_value = MagicMock(id="conv_123")
|
|
instance.get_conversations.return_value = []
|
|
instance.get_messages.return_value = []
|
|
instance.add_message.return_value = MagicMock()
|
|
instance.update_conversation_summary.return_value = MagicMock()
|
|
yield instance
|
|
|
|
@pytest.fixture
|
|
def mock_app_stream():
|
|
with patch("ea_chatbot.graph.workflow.app.stream") as mock_stream:
|
|
# Mock events from app.stream
|
|
mock_stream.return_value = [
|
|
{"query_analyzer": {"next_action": "research"}},
|
|
{"researcher": {"messages": [AIMessage(content="Research result")]}}
|
|
]
|
|
yield mock_stream
|
|
|
|
@pytest.fixture
|
|
def mock_user():
|
|
user = MagicMock()
|
|
user.id = "test_id"
|
|
user.username = "test@example.com"
|
|
user.display_name = "Test User"
|
|
return user
|
|
|
|
def test_app_initial_state(mock_app_stream, mock_user):
|
|
"""Test that the app initializes with the correct title and empty history."""
|
|
at = AppTest.from_file("src/ea_chatbot/app.py")
|
|
|
|
# Simulate logged-in user
|
|
at.session_state["user"] = mock_user
|
|
|
|
at.run()
|
|
|
|
assert not at.exception
|
|
assert at.title[0].value == "🗳️ Election Analytics Chatbot"
|
|
|
|
# Check session state initialization
|
|
assert "messages" in at.session_state
|
|
assert len(at.session_state["messages"]) == 0
|
|
|
|
def test_app_dev_mode_toggle(mock_app_stream, mock_user):
|
|
"""Test that the dev mode toggle exists in the sidebar."""
|
|
with patch.dict(os.environ, {"DEV_MODE": "false"}):
|
|
at = AppTest.from_file("src/ea_chatbot/app.py")
|
|
at.session_state["user"] = mock_user
|
|
at.run()
|
|
|
|
# Check for sidebar toggle (checkbox)
|
|
assert len(at.sidebar.checkbox) > 0
|
|
dev_mode_toggle = at.sidebar.checkbox[0]
|
|
assert dev_mode_toggle.label == "Dev Mode"
|
|
assert dev_mode_toggle.value is False
|
|
|
|
def test_app_graph_execution_streaming(mock_app_stream, mock_user, mock_history_manager):
|
|
"""Test that entering a prompt triggers the graph stream and displays response."""
|
|
at = AppTest.from_file("src/ea_chatbot/app.py")
|
|
at.session_state["user"] = mock_user
|
|
at.run()
|
|
|
|
# Input a question
|
|
at.chat_input[0].set_value("Test question").run()
|
|
|
|
# Verify graph stream was called
|
|
assert mock_app_stream.called
|
|
|
|
# Message should be added to history
|
|
assert len(at.session_state["messages"]) == 2
|
|
assert at.session_state["messages"][0]["role"] == "user"
|
|
assert at.session_state["messages"][1]["role"] == "assistant"
|
|
assert "Research result" in at.session_state["messages"][1]["content"]
|
|
|
|
# Verify history manager was used
|
|
assert mock_history_manager.create_conversation.called
|
|
assert mock_history_manager.add_message.called
|