"""Gap closure integration tests — dark theme, @-mention API, LocalComputerUseSession.""" import pytest from unittest.mock import MagicMock, patch from agentkit.quality.cascade_state_store import ( InMemoryCascadeStateStore, create_cascade_state_store, ) from agentkit.llm.providers.usage_store import ( InMemoryUsageStore, create_usage_store, ) from agentkit.tools.computer_use_session import ( InMemoryComputerUseSession, LocalComputerUseSession, ComputerUseSessionManager, ) # --------------------------------------------------------------------------- # Dark theme: CSS token validation (smoke test) # --------------------------------------------------------------------------- class TestDarkThemeTokens: """Verify dark theme CSS tokens exist in tokens.css.""" def test_dark_theme_tokens_file_contains_dark_selector(self): import pathlib tokens_path = pathlib.Path(__file__).parent.parent.parent / ( "src/agentkit/server/frontend/src/styles/tokens.css" ) if not tokens_path.exists(): pytest.skip("Frontend tokens.css not found") content = tokens_path.read_text() assert '[data-theme="dark"]' in content assert '--bg-primary: #1a1a1a' in content assert '--text-primary: #fbfbfa' in content assert '--border-color: #3a3a3a' in content def test_theme_store_exists(self): import pathlib store_path = pathlib.Path(__file__).parent.parent.parent / ( "src/agentkit/server/frontend/src/stores/theme.ts" ) if not store_path.exists(): pytest.skip("Theme store not found") content = store_path.read_text() assert 'useThemeStore' in content assert 'toggle' in content assert 'resolvedMode' in content assert 'localStorage' in content # --------------------------------------------------------------------------- # @-mention API: mention-suggest endpoint # --------------------------------------------------------------------------- class TestMentionSuggestAPI: """Test the /skills/mention-suggest endpoint logic.""" def _make_skill(self, name, description): skill = MagicMock() skill.name = name skill.config.description = description return skill def test_mention_suggest_filters_by_name(self): """Verify the filtering logic used by the endpoint.""" skills = [ self._make_skill("geo_pipeline", "GEO pipeline skill"), self._make_skill("code_reviewer", "Code review skill"), self._make_skill("data_analyst", "Data analysis skill"), ] query = "geo" filtered = [ s for s in skills if query in s.name.lower() or (s.config.description and query in s.config.description.lower()) ] assert len(filtered) == 1 assert filtered[0].name == "geo_pipeline" def test_mention_suggest_filters_by_description(self): skills = [ self._make_skill("skill_a", "GEO pipeline skill"), self._make_skill("skill_b", "Code review skill"), ] query = "review" filtered = [ s for s in skills if query in s.name.lower() or (s.config.description and query in s.config.description.lower()) ] assert len(filtered) == 1 assert filtered[0].name == "skill_b" def test_mention_suggest_limits_to_8(self): skills = [self._make_skill(f"skill_{i}", "") for i in range(20)] result = skills[:8] assert len(result) == 8 def test_mention_suggest_empty_query(self): skills = [ self._make_skill("skill_a", "desc"), self._make_skill("skill_b", "desc"), ] query = "" filtered = [ s for s in skills if query in s.name.lower() or (s.config.description and query in s.config.description.lower()) ] assert len(filtered) == 2 # --------------------------------------------------------------------------- # LocalComputerUseSession # --------------------------------------------------------------------------- class TestLocalComputerUseSession: """Test LocalComputerUseSession (without actual pyautogui).""" def test_inherits_from_base(self): assert issubclass(LocalComputerUseSession, InMemoryComputerUseSession.__mro__[1]) def test_start_without_pyautogui_raises(self): """If pyautogui is not installed, start should raise RuntimeError.""" import asyncio session = LocalComputerUseSession() with patch.dict("sys.modules", {"pyautogui": None}): with pytest.raises(RuntimeError, match="pyautogui"): asyncio.run(session.start()) def test_session_manager_with_local_factory(self): manager = ComputerUseSessionManager(session_factory=LocalComputerUseSession) session = manager.get_or_create(session_id="test-local") assert isinstance(session, LocalComputerUseSession) # --------------------------------------------------------------------------- # Factory session_ttl propagation (regression test) # --------------------------------------------------------------------------- class TestFactorySessionTTL: """Ensure session_ttl is propagated through factories.""" def test_cascade_store_memory_with_custom_ttl(self): store = create_cascade_state_store(backend="memory", session_ttl=7200) assert isinstance(store, InMemoryCascadeStateStore) assert store._session_ttl == 7200 def test_usage_store_memory_backend(self): store = create_usage_store(backend="memory") assert isinstance(store, InMemoryUsageStore) def test_cascade_store_auto_backend(self): store = create_cascade_state_store(backend="auto") assert store._session_ttl == 86400 # default