| """ |
| Mobile API Agent Execution Tests |
| |
| Tests for mobile API agent execution endpoints: |
| - Agent execution (sync and streaming) |
| - Agent execution with parameters |
| - Agent execution governance checks |
| - Agent execution history |
| |
| All tests use API-first approach with TestClient (no browser). |
| Response structure matches web API for consistency. |
| """ |
|
|
| import pytest |
| from fastapi.testclient import TestClient |
|
|
|
|
| class TestMobileAgentExecute: |
| """Test mobile agent execution endpoint""" |
|
|
| def test_mobile_agent_execute_success(self, mobile_api_client: TestClient, mobile_auth_headers: dict): |
| """Test successful agent execution""" |
| |
| list_response = mobile_api_client.get("/api/v1/agents", headers=mobile_auth_headers) |
|
|
| if list_response.status_code != 200: |
| pytest.skip("Agents endpoint not available") |
|
|
| agents = list_response.json().get("agents", []) |
| if not agents: |
| pytest.skip("No agents available for testing") |
|
|
| |
| agent_id = agents[0].get("id") or agents[0].get("agent_id") |
| if not agent_id: |
| pytest.skip("Agent ID not found in response") |
|
|
| |
| response = mobile_api_client.post( |
| f"/api/v1/agents/{agent_id}/execute", |
| headers=mobile_auth_headers, |
| json={"query": "test query"} |
| ) |
|
|
| |
| assert response.status_code in [200, 202] |
| data = response.json() |
|
|
| |
| assert "execution_id" in data or "response" in data or "success" in data |
|
|
| def test_mobile_agent_execute_with_params(self, mobile_api_client: TestClient, mobile_auth_headers: dict): |
| """Test agent execution with custom parameters""" |
| |
| list_response = mobile_api_client.get("/api/v1/agents", headers=mobile_auth_headers) |
|
|
| if list_response.status_code != 200: |
| pytest.skip("Agents endpoint not available") |
|
|
| agents = list_response.json().get("agents", []) |
| if not agents: |
| pytest.skip("No agents available for testing") |
|
|
| agent_id = agents[0].get("id") or agents[0].get("agent_id") |
| if not agent_id: |
| pytest.skip("Agent ID not found in response") |
|
|
| |
| response = mobile_api_client.post( |
| f"/api/v1/agents/{agent_id}/execute", |
| headers=mobile_auth_headers, |
| json={ |
| "query": "test query with params", |
| "params": {"key": "value", "number": 123} |
| } |
| ) |
|
|
| |
| assert response.status_code in [200, 202] |
| data = response.json() |
|
|
| |
| assert "execution_id" in data or "success" in data |
|
|
| def test_mobile_agent_execute_not_found(self, mobile_api_client: TestClient, mobile_auth_headers: dict): |
| """Test agent execution with non-existent agent ID""" |
| response = mobile_api_client.post( |
| "/api/v1/agents/nonexistent_agent_id/execute", |
| headers=mobile_auth_headers, |
| json={"query": "test query"} |
| ) |
|
|
| |
| assert response.status_code in [404, 400] |
|
|
| def test_mobile_agent_execute_unauthorized(self, mobile_api_client: TestClient): |
| """Test agent execution without authentication""" |
| response = mobile_api_client.post( |
| "/api/v1/agents/some_agent_id/execute", |
| json={"query": "test query"} |
| ) |
|
|
| |
| assert response.status_code == 401 |
|
|
|
|
| class TestMobileAgentStream: |
| """Test mobile agent streaming execution""" |
|
|
| def test_mobile_agent_stream_execution(self, mobile_api_client: TestClient, mobile_auth_headers: dict): |
| """Test agent streaming execution""" |
| |
| list_response = mobile_api_client.get("/api/v1/agents", headers=mobile_auth_headers) |
|
|
| if list_response.status_code != 200: |
| pytest.skip("Agents endpoint not available") |
|
|
| agents = list_response.json().get("agents", []) |
| if not agents: |
| pytest.skip("No agents available for testing") |
|
|
| agent_id = agents[0].get("id") or agents[0].get("agent_id") |
| if not agent_id: |
| pytest.skip("Agent ID not found in response") |
|
|
| |
| response = mobile_api_client.post( |
| "/api/atom-agent/chat/stream", |
| headers=mobile_auth_headers, |
| json={ |
| "message": "test streaming query", |
| "stream": True |
| } |
| ) |
|
|
| |
| if response.status_code == 200: |
| data = response.json() |
| |
| assert "message_id" in data or "success" in data |
| else: |
| |
| pytest.skip("Streaming endpoint not available in TestClient") |
|
|
|
|
| class TestMobileAgentGovernance: |
| """Test mobile agent governance enforcement""" |
|
|
| def test_mobile_agent_execution_governance(self, mobile_api_client: TestClient, mobile_auth_headers: dict): |
| """Test agent execution respects governance checks""" |
| |
| |
|
|
| |
| list_response = mobile_api_client.get("/api/v1/agents", headers=mobile_auth_headers) |
|
|
| if list_response.status_code != 200: |
| pytest.skip("Agents endpoint not available") |
|
|
| agents = list_response.json().get("agents", []) |
| if not agents: |
| pytest.skip("No agents available for testing") |
|
|
| |
| agent_id = agents[0].get("id") or agents[0].get("agent_id") |
| if not agent_id: |
| pytest.skip("Agent ID not found in response") |
|
|
| response = mobile_api_client.post( |
| f"/api/v1/agents/{agent_id}/execute", |
| headers=mobile_auth_headers, |
| json={"query": "test governance check"} |
| ) |
|
|
| |
| |
| assert response.status_code in [200, 202, 403, 400] |
|
|
| |
| if response.status_code == 403: |
| data = response.json() |
| assert "detail" in data or "error" in data |
|
|
| def test_mobile_agent_maturity_level(self, mobile_api_client: TestClient, mobile_auth_headers: dict): |
| """Test agent maturity level is respected""" |
| |
| |
|
|
| |
| response = mobile_api_client.get("/api/v1/agents", headers=mobile_auth_headers) |
|
|
| if response.status_code != 200: |
| pytest.skip("Agents endpoint not available") |
|
|
| data = response.json() |
| agents = data.get("agents", []) |
|
|
| |
| if agents: |
| |
| agent = agents[0] |
| |
| maturity_fields = ["maturity_level", "maturity", "level", "confidence"] |
| has_maturity = any(field in agent for field in maturity_fields) |
|
|
| |
| if has_maturity: |
| |
| assert True |
| else: |
| |
| pass |
|
|
|
|
| class TestMobileAgentExecutionHistory: |
| """Test mobile agent execution history""" |
|
|
| def test_mobile_agent_execution_history(self, mobile_api_client: TestClient, mobile_auth_headers: dict): |
| """Test listing agent execution history""" |
| |
| response = mobile_api_client.get( |
| "/api/v1/agents/executions", |
| headers=mobile_auth_headers |
| ) |
|
|
| |
| if response.status_code == 200: |
| data = response.json() |
|
|
| |
| assert "executions" in data or "items" in data or isinstance(data, list) |
|
|
| |
| if "limit" in data or "offset" in data: |
| assert isinstance(data.get("limit", 0), int) |
| assert isinstance(data.get("offset", 0), int) |
| elif response.status_code == 404: |
| pytest.skip("Executions history endpoint not implemented") |
| else: |
| |
| assert response.status_code in [200, 404] |
|
|
| def test_mobile_agent_execution_history_pagination(self, mobile_api_client: TestClient, mobile_auth_headers: dict): |
| """Test execution history pagination works""" |
| |
| response = mobile_api_client.get( |
| "/api/v1/agents/executions?limit=10&offset=0", |
| headers=mobile_auth_headers |
| ) |
|
|
| if response.status_code == 200: |
| data = response.json() |
|
|
| |
| executions = data.get("executions", data.get("items", [])) |
| if isinstance(executions, list): |
| assert len(executions) <= 10 |
| elif response.status_code == 404: |
| pytest.skip("Executions history endpoint not implemented") |
|
|
|
|
| class TestMobileAgentChatEndpoint: |
| """Test mobile agent chat endpoint (alternative to execute)""" |
|
|
| def test_mobile_agent_chat(self, mobile_api_client: TestClient, mobile_auth_headers: dict): |
| """Test agent chat endpoint""" |
| response = mobile_api_client.post( |
| "/api/atom-agent/chat", |
| headers=mobile_auth_headers, |
| json={ |
| "message": "Hello, can you help me?", |
| "session_id": None |
| } |
| ) |
|
|
| |
| if response.status_code == 200: |
| data = response.json() |
|
|
| |
| assert "success" in data or "response" in data |
|
|
| |
| if data.get("success"): |
| assert "response" in data |
| response_data = data["response"] |
| assert "message" in response_data or isinstance(response_data, str) |
| elif response.status_code == 404: |
| pytest.skip("Chat endpoint not available") |
|
|
| def test_mobile_agent_chat_with_history(self, mobile_api_client: TestClient, mobile_auth_headers: dict): |
| """Test agent chat with conversation history""" |
| response = mobile_api_client.post( |
| "/api/atom-agent/chat", |
| headers=mobile_auth_headers, |
| json={ |
| "message": "What was my previous question?", |
| "conversation_history": [ |
| {"role": "user", "content": "Hello"}, |
| {"role": "assistant", "content": "Hi! How can I help?"} |
| ] |
| } |
| ) |
|
|
| |
| if response.status_code == 200: |
| data = response.json() |
| assert "success" in data or "response" in data |
| elif response.status_code == 404: |
| pytest.skip("Chat endpoint not available") |
|
|