File size: 11,790 Bytes
aef804e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
"""
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"""
        # First, list available agents
        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")

        # Select first agent
        agent_id = agents[0].get("id") or agents[0].get("agent_id")
        if not agent_id:
            pytest.skip("Agent ID not found in response")

        # Execute agent
        response = mobile_api_client.post(
            f"/api/v1/agents/{agent_id}/execute",
            headers=mobile_auth_headers,
            json={"query": "test query"}
        )

        # Verify response (may be 200 or 202 for async execution)
        assert response.status_code in [200, 202]
        data = response.json()

        # Verify execution_id or response present
        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"""
        # First, list available agents
        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")

        # Execute agent with parameters
        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}
            }
        )

        # Verify response
        assert response.status_code in [200, 202]
        data = response.json()

        # Verify execution initiated
        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"}
        )

        # Verify error response
        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"}
        )

        # Verify unauthorized response
        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"""
        # First, list available agents
        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")

        # Execute agent with streaming enabled
        response = mobile_api_client.post(
            "/api/atom-agent/chat/stream",
            headers=mobile_auth_headers,
            json={
                "message": "test streaming query",
                "stream": True
            }
        )

        # Verify response (streaming returns 200 with message_id)
        if response.status_code == 200:
            data = response.json()
            # Verify streaming response structure
            assert "message_id" in data or "success" in data
        else:
            # Some endpoints may not support streaming in TestClient
            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"""
        # Try to execute an agent action that requires governance
        # This test verifies governance enforcement is in place

        # List agents first
        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")

        # Try to execute agent
        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"}
        )

        # Verify governance is checked (should not fail silently)
        # Response may be success or governance error
        assert response.status_code in [200, 202, 403, 400]

        # If governance blocked, verify error message
        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"""
        # This test verifies that agent maturity levels (STUDENT, INTERN, SUPERVISED, AUTONOMOUS)
        # are properly enforced

        # Try to access agent info
        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", [])

        # Verify agents have maturity level info (if available)
        if agents:
            # Check first agent for maturity info
            agent = agents[0]
            # Maturity level may be in different fields
            maturity_fields = ["maturity_level", "maturity", "level", "confidence"]
            has_maturity = any(field in agent for field in maturity_fields)

            # If maturity info present, verify it's valid
            if has_maturity:
                # Just verify field exists - actual governance tested elsewhere
                assert True  # Maturity info present
            else:
                # Maturity info not required in response
                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"""
        # Try to get execution history
        response = mobile_api_client.get(
            "/api/v1/agents/executions",
            headers=mobile_auth_headers
        )

        # Verify response (may be 200 or endpoint may not exist)
        if response.status_code == 200:
            data = response.json()

            # Verify history structure
            assert "executions" in data or "items" in data or isinstance(data, list)

            # Verify pagination fields if present
            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:
            # Unexpected status code
            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"""
        # Try with limit and offset
        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()

            # Verify pagination parameters respected
            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  # New session
            }
        )

        # Verify response
        if response.status_code == 200:
            data = response.json()

            # Verify chat response structure
            assert "success" in data or "response" in data

            # If success, verify response structure
            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?"}
                ]
            }
        )

        # Verify response
        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")