""" TradeSense AI — Standardized API Error Contract Tests (Milestone 17) Validates that all API error responses strictly conform to: {"error": {"code": "...", "message": "...", "request_id": "..."}} """ import pytest from fastapi.testclient import TestClient from backend.app.main import app client = TestClient(app) class TestAPIErrorContracts: def test_404_error_contract_format(self): res = client.get("/api/v1/research/runs/non_existent_run_id_9999") assert res.status_code == 404 data = res.json() assert "error" in data assert data["error"]["code"] == "HTTP_404" assert "request_id" in data["error"] assert len(data["error"]["message"]) > 0 def test_401_error_contract_format(self): res = client.get("/api/v1/audit/events", headers={"X-API-Key": "invalid_fake_key"}) assert res.status_code == 401 data = res.json() assert "error" in data assert data["error"]["code"] == "HTTP_401" assert "request_id" in data["error"] def test_rate_limit_429_or_403_format(self): # Viewer attempting to create organization triggers 403 with standard envelope res = client.post("/api/v1/organizations?name=UnauthorizedOrg", headers={"X-API-Key": "ts_viewer_public_key_safe"}) assert res.status_code == 403 data = res.json() assert "error" in data assert data["error"]["code"] == "HTTP_403" assert "request_id" in data["error"]