test_execution_engine, test_mcp_server_code_execution test_mcp_server_files_search test_mcp_server_web_search müssen noch gemacht werden
143 lines
4.7 KiB
Python
143 lines
4.7 KiB
Python
"""Tests for frontend/state.py — init_state() session initialisation."""
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
import pytest
|
|
from unittest.mock import patch
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
|
|
from backend.managers.chat_manager import ChatManager
|
|
|
|
|
|
# ── Fake session_state ────────────────────────────────────────────────────────
|
|
|
|
class FakeSessionState:
|
|
"""Minimal stand-in for st.session_state that supports attribute and 'in' access."""
|
|
|
|
def __init__(self):
|
|
self._data = {}
|
|
|
|
def __contains__(self, key):
|
|
return key in self._data
|
|
|
|
def __setattr__(self, name, value):
|
|
if name == "_data":
|
|
super().__setattr__(name, value)
|
|
else:
|
|
self._data[name] = value
|
|
|
|
def __getattr__(self, name):
|
|
try:
|
|
return self._data[name]
|
|
except KeyError:
|
|
raise AttributeError(name)
|
|
|
|
def get(self, key, default=None):
|
|
return self._data.get(key, default)
|
|
|
|
|
|
@pytest.fixture
|
|
def fake_state():
|
|
state = FakeSessionState()
|
|
with patch("frontend.state.st.session_state", state):
|
|
yield state
|
|
|
|
|
|
# ── Key initialisation ────────────────────────────────────────────────────────
|
|
|
|
class TestInitStateKeys:
|
|
EXPECTED_KEYS = [
|
|
"last_selected",
|
|
"selected_folder",
|
|
"selected_folder_rel",
|
|
"chat_manager",
|
|
"open_files",
|
|
"files_content",
|
|
"active_file",
|
|
"active_tab",
|
|
"is_editing",
|
|
"code_suggestions",
|
|
"code_execution_output",
|
|
"chat_history",
|
|
"agent_mode",
|
|
"coding_agent",
|
|
"agent_status",
|
|
"agent_log",
|
|
"agent_pending_action",
|
|
]
|
|
|
|
def test_all_expected_keys_are_set(self, fake_state):
|
|
from frontend.state import init_state
|
|
init_state()
|
|
for key in self.EXPECTED_KEYS:
|
|
assert key in fake_state, f"Missing key: {key}"
|
|
|
|
def test_open_files_initialised_as_empty_list(self, fake_state):
|
|
from frontend.state import init_state
|
|
init_state()
|
|
assert fake_state.open_files == []
|
|
|
|
def test_files_content_initialised_as_empty_dict(self, fake_state):
|
|
from frontend.state import init_state
|
|
init_state()
|
|
assert fake_state.files_content == {}
|
|
|
|
def test_active_file_initialised_as_none(self, fake_state):
|
|
from frontend.state import init_state
|
|
init_state()
|
|
assert fake_state.active_file is None
|
|
|
|
def test_chat_history_initialised_as_empty_list(self, fake_state):
|
|
from frontend.state import init_state
|
|
init_state()
|
|
assert fake_state.chat_history == []
|
|
|
|
def test_agent_mode_initialised_as_false(self, fake_state):
|
|
from frontend.state import init_state
|
|
init_state()
|
|
assert fake_state.agent_mode is False
|
|
|
|
def test_agent_status_initialised_as_idle(self, fake_state):
|
|
from frontend.state import init_state
|
|
init_state()
|
|
assert fake_state.agent_status == "idle"
|
|
|
|
def test_chat_manager_is_chat_manager_instance(self, fake_state):
|
|
from frontend.state import init_state
|
|
init_state()
|
|
assert isinstance(fake_state.chat_manager, ChatManager)
|
|
|
|
|
|
# ── Idempotency ───────────────────────────────────────────────────────────────
|
|
|
|
class TestInitStateIdempotency:
|
|
def test_second_call_does_not_overwrite_open_files(self, fake_state):
|
|
"""init_state() must not reset state that was set by the user."""
|
|
from frontend.state import init_state
|
|
init_state()
|
|
fake_state.open_files = ["/workspace/file.py"]
|
|
init_state()
|
|
assert fake_state.open_files == ["/workspace/file.py"]
|
|
|
|
def test_second_call_does_not_overwrite_chat_history(self, fake_state):
|
|
from frontend.state import init_state
|
|
init_state()
|
|
fake_state.chat_history = [{"role": "user", "content": "Hi"}]
|
|
init_state()
|
|
assert len(fake_state.chat_history) == 1
|
|
|
|
def test_second_call_does_not_replace_chat_manager(self, fake_state):
|
|
from frontend.state import init_state
|
|
init_state()
|
|
original = fake_state.chat_manager
|
|
init_state()
|
|
assert fake_state.chat_manager is original
|
|
|
|
def test_second_call_does_not_overwrite_active_file(self, fake_state):
|
|
from frontend.state import init_state
|
|
init_state()
|
|
fake_state.active_file = "/workspace/main.py"
|
|
init_state()
|
|
assert fake_state.active_file == "/workspace/main.py"
|