Spaces:
Build error
Build error
Commit ·
f8e7d59
1
Parent(s): d0c8f19
Upload folder using huggingface_hub
Browse files- tests/test_risk.py +5 -1
- tests/test_routes_admin.py +11 -11
- tests/test_routes_governance_execute.py +11 -5
tests/test_risk.py
CHANGED
|
@@ -31,4 +31,8 @@ def test_get_risk_internal_error(client, monkeypatch):
|
|
| 31 |
"X-API-Key": "test-key"})
|
| 32 |
assert response.status_code == 500
|
| 33 |
data = response.json()
|
| 34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
"X-API-Key": "test-key"})
|
| 32 |
assert response.status_code == 500
|
| 33 |
data = response.json()
|
| 34 |
+
# The raw exception message must NOT reach the caller -- routes_risk.py
|
| 35 |
+
# logs the real exception server-side and returns a generic detail
|
| 36 |
+
# instead (information-disclosure fix from this session's audit).
|
| 37 |
+
assert data.get("detail") == "Internal server error"
|
| 38 |
+
assert "test error" not in data.get("detail", "")
|
tests/test_routes_admin.py
CHANGED
|
@@ -37,7 +37,7 @@ def real_tracker(monkeypatch):
|
|
| 37 |
|
| 38 |
def test_create_list_update_deactivate_key(client):
|
| 39 |
create_resp = client.post(
|
| 40 |
-
"/admin/keys",
|
| 41 |
params={"admin_key": TEST_ADMIN_KEY},
|
| 42 |
json={"tier": "free", "org_name": "Test Org"},
|
| 43 |
)
|
|
@@ -47,7 +47,7 @@ def test_create_list_update_deactivate_key(client):
|
|
| 47 |
assert body["tier"] == "free"
|
| 48 |
key_id = _key_id(api_key)
|
| 49 |
|
| 50 |
-
list_resp = client.get("/admin/keys", params={"admin_key": TEST_ADMIN_KEY})
|
| 51 |
assert list_resp.status_code == 200
|
| 52 |
keys_by_id = {row["key_id"]: row for row in list_resp.json()["keys"]}
|
| 53 |
assert key_id in keys_by_id
|
|
@@ -55,28 +55,28 @@ def test_create_list_update_deactivate_key(client):
|
|
| 55 |
assert keys_by_id[key_id]["is_active"] is True
|
| 56 |
|
| 57 |
patch_resp = client.patch(
|
| 58 |
-
f"/admin/keys/{key_id}/tier",
|
| 59 |
params={"admin_key": TEST_ADMIN_KEY},
|
| 60 |
json={"tier": "pro"},
|
| 61 |
)
|
| 62 |
assert patch_resp.status_code == 200
|
| 63 |
|
| 64 |
-
list_resp2 = client.get("/admin/keys", params={"admin_key": TEST_ADMIN_KEY})
|
| 65 |
assert list_resp2.json()["keys"][0] # non-empty, sanity check
|
| 66 |
keys_by_id2 = {row["key_id"]: row for row in list_resp2.json()["keys"]}
|
| 67 |
assert keys_by_id2[key_id]["tier"] == "pro"
|
| 68 |
|
| 69 |
-
delete_resp = client.delete(f"/admin/keys/{key_id}", params={"admin_key": TEST_ADMIN_KEY})
|
| 70 |
assert delete_resp.status_code == 200
|
| 71 |
|
| 72 |
-
list_resp3 = client.get("/admin/keys", params={"admin_key": TEST_ADMIN_KEY})
|
| 73 |
keys_by_id3 = {row["key_id"]: row for row in list_resp3.json()["keys"]}
|
| 74 |
assert keys_by_id3[key_id]["is_active"] is False
|
| 75 |
|
| 76 |
|
| 77 |
def test_update_nonexistent_key_returns_404(client):
|
| 78 |
resp = client.patch(
|
| 79 |
-
"/admin/keys/does-not-exist/tier",
|
| 80 |
params={"admin_key": TEST_ADMIN_KEY},
|
| 81 |
json={"tier": "pro"},
|
| 82 |
)
|
|
@@ -85,7 +85,7 @@ def test_update_nonexistent_key_returns_404(client):
|
|
| 85 |
|
| 86 |
def test_rotate_key_deactivates_old_and_creates_new_on_same_tenant(client):
|
| 87 |
create_resp = client.post(
|
| 88 |
-
"/admin/keys",
|
| 89 |
params={"admin_key": TEST_ADMIN_KEY},
|
| 90 |
json={"tier": "pro", "org_name": "Rotate Test Org"},
|
| 91 |
)
|
|
@@ -95,7 +95,7 @@ def test_rotate_key_deactivates_old_and_creates_new_on_same_tenant(client):
|
|
| 95 |
tenant_id = old_body["tenant_id"]
|
| 96 |
|
| 97 |
rotate_resp = client.post(
|
| 98 |
-
f"/admin/keys/{old_key_id}/rotate", params={"admin_key": TEST_ADMIN_KEY})
|
| 99 |
assert rotate_resp.status_code == 200
|
| 100 |
rotated = rotate_resp.json()
|
| 101 |
assert rotated["tenant_id"] == tenant_id
|
|
@@ -104,7 +104,7 @@ def test_rotate_key_deactivates_old_and_creates_new_on_same_tenant(client):
|
|
| 104 |
new_key_id = _key_id(rotated["api_key"])
|
| 105 |
assert new_key_id != old_key_id
|
| 106 |
|
| 107 |
-
list_resp = client.get("/admin/keys", params={"admin_key": TEST_ADMIN_KEY})
|
| 108 |
keys_by_id = {row["key_id"]: row for row in list_resp.json()["keys"]}
|
| 109 |
assert keys_by_id[old_key_id]["is_active"] is False
|
| 110 |
assert keys_by_id[new_key_id]["is_active"] is True
|
|
@@ -113,5 +113,5 @@ def test_rotate_key_deactivates_old_and_creates_new_on_same_tenant(client):
|
|
| 113 |
|
| 114 |
def test_rotate_nonexistent_key_returns_404(client):
|
| 115 |
resp = client.post(
|
| 116 |
-
"/admin/keys/does-not-exist/rotate", params={"admin_key": TEST_ADMIN_KEY})
|
| 117 |
assert resp.status_code == 404
|
|
|
|
| 37 |
|
| 38 |
def test_create_list_update_deactivate_key(client):
|
| 39 |
create_resp = client.post(
|
| 40 |
+
"/api/v1/admin/keys",
|
| 41 |
params={"admin_key": TEST_ADMIN_KEY},
|
| 42 |
json={"tier": "free", "org_name": "Test Org"},
|
| 43 |
)
|
|
|
|
| 47 |
assert body["tier"] == "free"
|
| 48 |
key_id = _key_id(api_key)
|
| 49 |
|
| 50 |
+
list_resp = client.get("/api/v1/admin/keys", params={"admin_key": TEST_ADMIN_KEY})
|
| 51 |
assert list_resp.status_code == 200
|
| 52 |
keys_by_id = {row["key_id"]: row for row in list_resp.json()["keys"]}
|
| 53 |
assert key_id in keys_by_id
|
|
|
|
| 55 |
assert keys_by_id[key_id]["is_active"] is True
|
| 56 |
|
| 57 |
patch_resp = client.patch(
|
| 58 |
+
f"/api/v1/admin/keys/{key_id}/tier",
|
| 59 |
params={"admin_key": TEST_ADMIN_KEY},
|
| 60 |
json={"tier": "pro"},
|
| 61 |
)
|
| 62 |
assert patch_resp.status_code == 200
|
| 63 |
|
| 64 |
+
list_resp2 = client.get("/api/v1/admin/keys", params={"admin_key": TEST_ADMIN_KEY})
|
| 65 |
assert list_resp2.json()["keys"][0] # non-empty, sanity check
|
| 66 |
keys_by_id2 = {row["key_id"]: row for row in list_resp2.json()["keys"]}
|
| 67 |
assert keys_by_id2[key_id]["tier"] == "pro"
|
| 68 |
|
| 69 |
+
delete_resp = client.delete(f"/api/v1/admin/keys/{key_id}", params={"admin_key": TEST_ADMIN_KEY})
|
| 70 |
assert delete_resp.status_code == 200
|
| 71 |
|
| 72 |
+
list_resp3 = client.get("/api/v1/admin/keys", params={"admin_key": TEST_ADMIN_KEY})
|
| 73 |
keys_by_id3 = {row["key_id"]: row for row in list_resp3.json()["keys"]}
|
| 74 |
assert keys_by_id3[key_id]["is_active"] is False
|
| 75 |
|
| 76 |
|
| 77 |
def test_update_nonexistent_key_returns_404(client):
|
| 78 |
resp = client.patch(
|
| 79 |
+
"/api/v1/admin/keys/does-not-exist/tier",
|
| 80 |
params={"admin_key": TEST_ADMIN_KEY},
|
| 81 |
json={"tier": "pro"},
|
| 82 |
)
|
|
|
|
| 85 |
|
| 86 |
def test_rotate_key_deactivates_old_and_creates_new_on_same_tenant(client):
|
| 87 |
create_resp = client.post(
|
| 88 |
+
"/api/v1/admin/keys",
|
| 89 |
params={"admin_key": TEST_ADMIN_KEY},
|
| 90 |
json={"tier": "pro", "org_name": "Rotate Test Org"},
|
| 91 |
)
|
|
|
|
| 95 |
tenant_id = old_body["tenant_id"]
|
| 96 |
|
| 97 |
rotate_resp = client.post(
|
| 98 |
+
f"/api/v1/admin/keys/{old_key_id}/rotate", params={"admin_key": TEST_ADMIN_KEY})
|
| 99 |
assert rotate_resp.status_code == 200
|
| 100 |
rotated = rotate_resp.json()
|
| 101 |
assert rotated["tenant_id"] == tenant_id
|
|
|
|
| 104 |
new_key_id = _key_id(rotated["api_key"])
|
| 105 |
assert new_key_id != old_key_id
|
| 106 |
|
| 107 |
+
list_resp = client.get("/api/v1/admin/keys", params={"admin_key": TEST_ADMIN_KEY})
|
| 108 |
keys_by_id = {row["key_id"]: row for row in list_resp.json()["keys"]}
|
| 109 |
assert keys_by_id[old_key_id]["is_active"] is False
|
| 110 |
assert keys_by_id[new_key_id]["is_active"] is True
|
|
|
|
| 113 |
|
| 114 |
def test_rotate_nonexistent_key_returns_404(client):
|
| 115 |
resp = client.post(
|
| 116 |
+
"/api/v1/admin/keys/does-not-exist/rotate", params={"admin_key": TEST_ADMIN_KEY})
|
| 117 |
assert resp.status_code == 404
|
tests/test_routes_governance_execute.py
CHANGED
|
@@ -46,7 +46,13 @@ def _evaluate_intent(client):
|
|
| 46 |
headers={"X-Tenant-ID": TENANT_ID})
|
| 47 |
assert resp.status_code == 200, resp.text
|
| 48 |
data = resp.json()
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
|
| 51 |
|
| 52 |
class _FakePendingApprovalError(Exception):
|
|
@@ -257,12 +263,12 @@ def admin_with_approval_store(monkeypatch, client):
|
|
| 257 |
def test_list_pending_executions_returns_501_without_store(client, monkeypatch):
|
| 258 |
monkeypatch.setattr(routes_admin, "ADMIN_API_KEY", TEST_ADMIN_KEY)
|
| 259 |
client.app.state.approval_store = None
|
| 260 |
-
resp = client.get("/admin/executions/pending", params={"admin_key": TEST_ADMIN_KEY})
|
| 261 |
assert resp.status_code == 501
|
| 262 |
|
| 263 |
|
| 264 |
def test_list_pending_executions(client, admin_with_approval_store):
|
| 265 |
-
resp = client.get("/admin/executions/pending", params={"admin_key": TEST_ADMIN_KEY})
|
| 266 |
assert resp.status_code == 200
|
| 267 |
body = resp.json()
|
| 268 |
assert body["total"] == 1
|
|
@@ -271,7 +277,7 @@ def test_list_pending_executions(client, admin_with_approval_store):
|
|
| 271 |
|
| 272 |
def test_resolve_execution_approval(client, admin_with_approval_store):
|
| 273 |
resp = client.post(
|
| 274 |
-
"/admin/executions/appr_1/resolve",
|
| 275 |
params={"admin_key": TEST_ADMIN_KEY},
|
| 276 |
json={"approved": True, "note": "looks fine"},
|
| 277 |
)
|
|
@@ -281,7 +287,7 @@ def test_resolve_execution_approval(client, admin_with_approval_store):
|
|
| 281 |
|
| 282 |
def test_resolve_unknown_approval_returns_404(client, admin_with_approval_store):
|
| 283 |
resp = client.post(
|
| 284 |
-
"/admin/executions/does-not-exist/resolve",
|
| 285 |
params={"admin_key": TEST_ADMIN_KEY},
|
| 286 |
json={"approved": True},
|
| 287 |
)
|
|
|
|
| 46 |
headers={"X-Tenant-ID": TENANT_ID})
|
| 47 |
assert resp.status_code == 200, resp.text
|
| 48 |
data = resp.json()
|
| 49 |
+
# data["intent_id"] (top level, set by evaluate_intent_endpoint right
|
| 50 |
+
# before returning: result["intent_id"] = deterministic_id) is what
|
| 51 |
+
# save_evaluated_intent actually persisted to IntentDB.deterministic_id.
|
| 52 |
+
# data["healing_intent"]["intent_id"] is a separate, independently
|
| 53 |
+
# generated id belonging to the HealingIntent object itself -- using it
|
| 54 |
+
# here instead was the exact bug that made every test in this file 404.
|
| 55 |
+
return data["intent_id"], data["healing_intent"]
|
| 56 |
|
| 57 |
|
| 58 |
class _FakePendingApprovalError(Exception):
|
|
|
|
| 263 |
def test_list_pending_executions_returns_501_without_store(client, monkeypatch):
|
| 264 |
monkeypatch.setattr(routes_admin, "ADMIN_API_KEY", TEST_ADMIN_KEY)
|
| 265 |
client.app.state.approval_store = None
|
| 266 |
+
resp = client.get("/api/v1/admin/executions/pending", params={"admin_key": TEST_ADMIN_KEY})
|
| 267 |
assert resp.status_code == 501
|
| 268 |
|
| 269 |
|
| 270 |
def test_list_pending_executions(client, admin_with_approval_store):
|
| 271 |
+
resp = client.get("/api/v1/admin/executions/pending", params={"admin_key": TEST_ADMIN_KEY})
|
| 272 |
assert resp.status_code == 200
|
| 273 |
body = resp.json()
|
| 274 |
assert body["total"] == 1
|
|
|
|
| 277 |
|
| 278 |
def test_resolve_execution_approval(client, admin_with_approval_store):
|
| 279 |
resp = client.post(
|
| 280 |
+
"/api/v1/admin/executions/appr_1/resolve",
|
| 281 |
params={"admin_key": TEST_ADMIN_KEY},
|
| 282 |
json={"approved": True, "note": "looks fine"},
|
| 283 |
)
|
|
|
|
| 287 |
|
| 288 |
def test_resolve_unknown_approval_returns_404(client, admin_with_approval_store):
|
| 289 |
resp = client.post(
|
| 290 |
+
"/api/v1/admin/executions/does-not-exist/resolve",
|
| 291 |
params={"admin_key": TEST_ADMIN_KEY},
|
| 292 |
json={"approved": True},
|
| 293 |
)
|