import os import json import pytest from pathlib import Path from src.app_controller import AppController from src import models @pytest.fixture def controller(tmp_path): # Setup mock config and project files config_path = tmp_path / "config.toml" project_path = tmp_path / "project.toml" mcp_config_path = tmp_path / "mcp_config.json" config_data = { "ai": { "mcp_config_path": str(mcp_config_path) }, "projects": { "paths": [str(project_path)], "active": str(project_path) } } project_data = { "project": { "name": "test-project", "mcp_config_path": "project_mcp.json" # Relative path } } mcp_data = { "mcpServers": { "global-server": {"command": "echo"} } } project_mcp_data = { "mcpServers": { "project-server": {"command": "echo"} } } # We can't easily use models.save_config because it uses a hardcoded path # But AppController.init_state calls models.load_config() which uses CONFIG_PATH return AppController() def test_app_controller_mcp_loading(tmp_path, monkeypatch): # Mock CONFIG_PATH to point to our temp config config_file = tmp_path / "config.toml" monkeypatch.setattr(models, "CONFIG_PATH", str(config_file)) mcp_global_file = tmp_path / "mcp_global.json" mcp_global_file.write_text(json.dumps({"mcpServers": {"global": {"command": "echo"}}})) config_content = f""" [ai] mcp_config_path = "{mcp_global_file.as_posix()}" [projects] paths = [] active = "" """ config_file.write_text(config_content) ctrl = AppController() # Mock _load_active_project to not do anything for now monkeypatch.setattr(ctrl, "_load_active_project", lambda: None) ctrl.project = {} ctrl.init_state() assert "global" in ctrl.mcp_config.mcpServers assert ctrl.mcp_config.mcpServers["global"].command == "echo" def test_app_controller_mcp_project_override(tmp_path, monkeypatch): config_file = tmp_path / "config.toml" monkeypatch.setattr(models, "CONFIG_PATH", str(config_file)) project_file = tmp_path / "project.toml" mcp_project_file = tmp_path / "mcp_project.json" mcp_project_file.write_text(json.dumps({"mcpServers": {"project": {"command": "echo"}}})) config_content = f""" [ai] mcp_config_path = "non-existent.json" [projects] paths = ["{project_file.as_posix()}"] active = "{project_file.as_posix()}" """ config_file.write_text(config_content) ctrl = AppController() ctrl.active_project_path = str(project_file) ctrl.project = { "project": { "mcp_config_path": "mcp_project.json" } } # Mock _load_active_project to keep our manual project dict monkeypatch.setattr(ctrl, "_load_active_project", lambda: None) ctrl.init_state() assert "project" in ctrl.mcp_config.mcpServers assert "non-existent" not in ctrl.mcp_config.mcpServers