from unittest.mock import AsyncMock, MagicMock, patch # ── Index ───────────────────────────────────────────────────────────────────── def test_index_returns_200(client): response = client.get("/") assert response.status_code == 200 def test_index_contains_title(client): response = client.get("/") assert "MISSION CONTROL" in response.text def test_index_contains_chat_interface(client): response = client.get("/") # Agent panel loads dynamically via HTMX; verify the trigger attribute is present assert 'hx-get="/agents/default/panel"' in response.text # ── Health ──────────────────────────────────────────────────────────────────── def test_health_endpoint_ok(client): with patch( "dashboard.routes.health.check_ollama", new_callable=AsyncMock, return_value=True, ): response = client.get("/health") assert response.status_code == 200 data = response.json() assert data["status"] == "ok" assert data["services"]["ollama"] == "up" assert "agents" in data def test_health_endpoint_ollama_down(client): with patch( "dashboard.routes.health.check_ollama", new_callable=AsyncMock, return_value=False, ): response = client.get("/health") assert response.status_code == 200 assert response.json()["services"]["ollama"] == "down" def test_health_status_panel_ollama_up(client): with patch( "dashboard.routes.health.check_ollama", new_callable=AsyncMock, return_value=True, ): response = client.get("/health/status") assert response.status_code == 200 assert "UP" in response.text def test_health_status_panel_ollama_down(client): with patch( "dashboard.routes.health.check_ollama", new_callable=AsyncMock, return_value=False, ): response = client.get("/health/status") assert response.status_code == 200 assert "DOWN" in response.text # ── Agents ──────────────────────────────────────────────────────────────────── def test_agents_list(client): response = client.get("/agents") assert response.status_code == 200 data = response.json() assert "agents" in data ids = [a["id"] for a in data["agents"]] assert "default" in ids def test_agents_list_metadata(client): from config import settings response = client.get("/agents") agent = next(a for a in response.json()["agents"] if a["id"] == "default") assert agent["name"] == "Agent" assert agent["model"] == settings.ollama_model assert agent["type"] == "local" # ── Chat ────────────────────────────────────────────────────────────────────── def _mock_run(content="Operational and ready."): """Create a mock RunOutput for a completed run.""" run = MagicMock() run.content = content run.status = "COMPLETED" run.active_requirements = [] return run def test_chat_agent_success(client): with patch("dashboard.routes.agents.chat_with_tools", return_value=_mock_run()): response = client.post("/agents/default/chat", data={"message": "status?"}) assert response.status_code == 200 assert "status?" in response.text assert "Operational" in response.text def test_chat_agent_shows_user_message(client): with patch("dashboard.routes.agents.chat_with_tools", return_value=_mock_run("Acknowledged.")): response = client.post("/agents/default/chat", data={"message": "hello there"}) assert "hello there" in response.text def test_chat_agent_ollama_offline(client): # When Ollama is unreachable, chat shows the user message + error. with patch( "dashboard.routes.agents.chat_with_tools", side_effect=Exception("Ollama unreachable"), ): response = client.post("/agents/default/chat", data={"message": "ping"}) assert response.status_code == 200 assert "ping" in response.text def test_chat_agent_requires_message(client): response = client.post("/agents/default/chat", data={}) assert response.status_code == 422 # ── History ──────────────────────────────────────────────────────────────────── def test_history_empty_shows_init_message(client): response = client.get("/agents/default/history") assert response.status_code == 200 assert "Mission Control initialized" in response.text def test_history_records_user_and_agent_messages(client): with patch( "dashboard.routes.agents.chat_with_tools", return_value=_mock_run("I am operational.") ): client.post("/agents/default/chat", data={"message": "status check"}) response = client.get("/agents/default/history") assert "status check" in response.text def test_history_records_error_when_offline(client): with patch( "dashboard.routes.agents.chat_with_tools", side_effect=Exception("Ollama unreachable"), ): client.post("/agents/default/chat", data={"message": "ping"}) response = client.get("/agents/default/history") assert "ping" in response.text def test_history_clear_resets_to_init_message(client): with patch("dashboard.routes.agents.chat_with_tools", return_value=_mock_run("Acknowledged.")): client.post("/agents/default/chat", data={"message": "hello"}) response = client.delete("/agents/default/history") assert response.status_code == 200 assert "Mission Control initialized" in response.text def test_history_empty_after_clear(client): with patch("dashboard.routes.agents.chat_with_tools", return_value=_mock_run("OK.")): client.post("/agents/default/chat", data={"message": "test"}) client.delete("/agents/default/history") response = client.get("/agents/default/history") assert "test" not in response.text assert "Mission Control initialized" in response.text