""" Tests for mma_agent_focus_ux_20260302 — Phase 3: Focus Agent UI + Filter Logic. """ from typing import Generator import pytest from unittest.mock import patch from gui_2 import App @pytest.fixture def app_instance() -> Generator[App, None, None]: with ( patch('gui_2.load_config', return_value={'gui': {'show_windows': {}}}), patch('gui_2.save_config'), patch('gui_2.project_manager'), patch('gui_2.session_logger'), patch('gui_2.immapp.run'), patch.object(App, '_load_active_project'), patch.object(App, '_fetch_models'), patch.object(App, '_load_fonts'), patch.object(App, '_post_init') ): yield App() def test_ui_focus_agent_state_var_exists(app_instance): """App.__init__ must expose ui_focus_agent: str | None = None.""" assert hasattr(app_instance, 'ui_focus_agent'), "ui_focus_agent missing from App" assert app_instance.ui_focus_agent is None def test_tool_log_filter_all(app_instance): """When ui_focus_agent is None, all tool log entries are visible.""" app = app_instance app._tool_log = [ {"script": "a", "result": "r1", "ts": 1.0, "source_tier": "Tier 2"}, {"script": "b", "result": "r2", "ts": 2.0, "source_tier": "Tier 3"}, {"script": "c", "result": "r3", "ts": 3.0, "source_tier": None}, ] app.ui_focus_agent = None filtered = app._tool_log if not app.ui_focus_agent else [ e for e in app._tool_log if e.get("source_tier") == app.ui_focus_agent ] assert len(filtered) == 3 def test_tool_log_filter_tier3_only(app_instance): """When ui_focus_agent='Tier 3', only Tier 3 entries are shown.""" app = app_instance app._tool_log = [ {"script": "a", "result": "r1", "ts": 1.0, "source_tier": "Tier 2"}, {"script": "b", "result": "r2", "ts": 2.0, "source_tier": "Tier 3"}, {"script": "c", "result": "r3", "ts": 3.0, "source_tier": "Tier 3"}, {"script": "d", "result": "r4", "ts": 4.0, "source_tier": None}, ] app.ui_focus_agent = "Tier 3" filtered = [e for e in app._tool_log if e.get("source_tier") == app.ui_focus_agent] assert len(filtered) == 2 assert all(e["source_tier"] == "Tier 3" for e in filtered) def test_tool_log_filter_excludes_none_tier(app_instance): """Filtering to Tier 2 excludes entries with source_tier=None.""" app = app_instance app._tool_log = [ {"script": "a", "result": "r1", "ts": 1.0, "source_tier": "Tier 2"}, {"script": "b", "result": "r2", "ts": 2.0, "source_tier": None}, ] app.ui_focus_agent = "Tier 2" filtered = [e for e in app._tool_log if e.get("source_tier") == app.ui_focus_agent] assert len(filtered) == 1 assert filtered[0]["script"] == "a" def test_comms_log_filter_tier3_only(app_instance): """When ui_focus_agent='Tier 3', comms filter excludes other tiers.""" app = app_instance import time app._comms_log = [ {"ts": "10:00", "direction": "OUT", "kind": "request", "provider": "gemini", "model": "m", "payload": {}, "source_tier": "Tier 2", "local_ts": time.time()}, {"ts": "10:01", "direction": "IN", "kind": "response", "provider": "gemini", "model": "m", "payload": {}, "source_tier": "Tier 3", "local_ts": time.time()}, {"ts": "10:02", "direction": "OUT", "kind": "request", "provider": "gemini", "model": "m", "payload": {}, "source_tier": None, "local_ts": time.time()}, ] app.ui_focus_agent = "Tier 3" app.is_viewing_prior_session = False log_to_render = list(app._comms_log) if app.ui_focus_agent and not app.is_viewing_prior_session: log_to_render = [e for e in log_to_render if e.get("source_tier") == app.ui_focus_agent] assert len(log_to_render) == 1 assert log_to_render[0]["source_tier"] == "Tier 3" def test_comms_log_filter_not_applied_for_prior_session(app_instance): """Focus filter must NOT apply when viewing prior session log.""" app = app_instance app.ui_focus_agent = "Tier 3" app.is_viewing_prior_session = True prior = [ {"ts": "10:00", "source_tier": "Tier 2"}, {"ts": "10:01", "source_tier": "Tier 3"}, ] app.prior_session_entries = prior log_to_render = app.prior_session_entries if app.is_viewing_prior_session else list(app._comms_log) if app.ui_focus_agent and not app.is_viewing_prior_session: log_to_render = [e for e in log_to_render if e.get("source_tier") == app.ui_focus_agent] assert len(log_to_render) == 2