import os import json import pytest import tempfile import shutil from pathlib import Path from src.app_controller import AppController from src import models from src.personas import PersonaManager from src import presets, tool_presets from src import project_manager def _setup_two_projects(tmp_path): project_a_dir = tmp_path / "project_a" project_a_dir.mkdir() project_a_path = project_a_dir / "project.toml" project_a_path.write_text('[project]\nname = "project_a"\nactive_preset = "PresetA"\n') project_b_dir = tmp_path / "project_b" project_b_dir.mkdir() project_b_path = project_b_dir / "project.toml" project_b_path.write_text('[project]\nname = "project_b"\n') (project_a_dir / "project_personas.toml").write_text( '[personas."PersonaA"]\nsystem_prompt = "Project A persona"\npreferred_models = []\n' ) (project_b_dir / "project_personas.toml").write_text( '[personas."PersonaB"]\nsystem_prompt = "Project B persona"\npreferred_models = []\n' ) (project_a_dir / "project_presets.toml").write_text( '[presets."PresetA"]\nsystem_prompt = "Project A preset"\n' ) (project_b_dir / "project_presets.toml").write_text( '[presets."PresetB"]\nsystem_prompt = "Project B preset"\n' ) return project_a_path, project_b_path def test_switch_project_resets_invalid_persona(tmp_path, monkeypatch): project_a_path, project_b_path = _setup_two_projects(tmp_path) ctrl = AppController() monkeypatch.setattr(ctrl, "_rebuild_rag_index", lambda: None) monkeypatch.setattr(ctrl, "_flush_to_project", lambda: None) ctrl.active_project_path = str(project_a_path) ctrl.project = project_manager.load_project(str(project_a_path)) ctrl.preset_manager = presets.PresetManager(Path(project_a_path).parent) ctrl.tool_preset_manager = tool_presets.ToolPresetManager(Path(project_a_path).parent) ctrl.persona_manager = PersonaManager(Path(project_a_path).parent) ctrl._refresh_from_project() assert "PersonaA" in ctrl.personas assert "PersonaB" not in ctrl.personas ctrl.ui_active_persona = "PersonaA" ctrl._switch_project(str(project_b_path)) assert "PersonaA" not in ctrl.personas assert "PersonaB" in ctrl.personas assert ctrl.ui_active_persona == "" def test_switch_project_resets_invalid_preset(tmp_path, monkeypatch): project_a_path, project_b_path = _setup_two_projects(tmp_path) ctrl = AppController() monkeypatch.setattr(ctrl, "_rebuild_rag_index", lambda: None) monkeypatch.setattr(ctrl, "_flush_to_project", lambda: None) ctrl.active_project_path = str(project_a_path) ctrl.project = project_manager.load_project(str(project_a_path)) ctrl.preset_manager = presets.PresetManager(Path(project_a_path).parent) ctrl.tool_preset_manager = tool_presets.ToolPresetManager(Path(project_a_path).parent) ctrl.persona_manager = PersonaManager(Path(project_a_path).parent) ctrl._refresh_from_project() assert ctrl.ui_project_preset_name == "PresetA" ctrl._switch_project(str(project_b_path)) assert "PresetA" not in ctrl.presets assert "PresetB" in ctrl.presets assert ctrl.ui_project_preset_name is None def test_switch_project_resets_invalid_tool_preset(tmp_path, monkeypatch): project_a_path, project_b_path = _setup_two_projects(tmp_path) (Path(project_a_path).parent / "project_tool_presets.toml").write_text( '[presets."ToolA"]\ndescription = "A"\n[presets.tools."run_powershell"]\nweight = 1\n' ) (Path(project_b_path).parent / "project_tool_presets.toml").write_text( '[presets."ToolB"]\ndescription = "B"\n[presets.tools."run_powershell"]\nweight = 1\n' ) ctrl = AppController() monkeypatch.setattr(ctrl, "_rebuild_rag_index", lambda: None) monkeypatch.setattr(ctrl, "_flush_to_project", lambda: None) ctrl.active_project_path = str(project_a_path) ctrl.project = project_manager.load_project(str(project_a_path)) ctrl.preset_manager = presets.PresetManager(Path(project_a_path).parent) ctrl.tool_preset_manager = tool_presets.ToolPresetManager(Path(project_a_path).parent) ctrl.persona_manager = PersonaManager(Path(project_a_path).parent) ctrl._refresh_from_project() ctrl.ui_active_tool_preset = "ToolA" assert "ToolA" in ctrl.tool_presets ctrl._switch_project(str(project_b_path)) assert "ToolA" not in ctrl.tool_presets assert "ToolB" in ctrl.tool_presets assert ctrl.ui_active_tool_preset is None def test_switch_project_preserves_global_preset(tmp_path, monkeypatch): project_a_path, project_b_path = _setup_two_projects(tmp_path) ctrl = AppController() monkeypatch.setattr(ctrl, "_rebuild_rag_index", lambda: None) monkeypatch.setattr(ctrl, "_flush_to_project", lambda: None) ctrl.active_project_path = str(project_a_path) ctrl.project = project_manager.load_project(str(project_a_path)) ctrl.preset_manager = presets.PresetManager(Path(project_a_path).parent) ctrl.tool_preset_manager = tool_presets.ToolPresetManager(Path(project_a_path).parent) ctrl.persona_manager = PersonaManager(Path(project_a_path).parent) ctrl._refresh_from_project() ctrl.ui_global_preset_name = "GlobalPresetA" original_global = ctrl.ui_global_preset_name ctrl._switch_project(str(project_b_path)) assert ctrl.ui_global_preset_name == original_global