import os import uuid import httpx import pytest BASE_URL = os.getenv("E2E_BASE_URL", "http://127.0.0.1:8000").rstrip("/") AGENT_ID = os.getenv("E2E_AGENT_ID", "sirus-sql-agent") JWT = os.getenv("E2E_SUPABASE_JWT") TENANT_ID = os.getenv("E2E_TENANT_ID") SOURCE_NAME = os.getenv("E2E_SOURCE_NAME") def _required_env_missing() -> list[str]: missing = [] if not JWT: missing.append("E2E_SUPABASE_JWT") if not TENANT_ID: missing.append("E2E_TENANT_ID") if not SOURCE_NAME: missing.append("E2E_SOURCE_NAME") return missing @pytest.mark.e2e def test_agent_endpoints_e2e_httpx_only(): missing = _required_env_missing() if missing: pytest.skip(f"Missing required env vars for e2e test: {', '.join(missing)}") headers = { "Authorization": f"Bearer {JWT}", "Content-Type": "application/json", } session_id = None with httpx.Client(base_url=BASE_URL, timeout=60.0) as client: run_payload = { "message": "Reply with a very short confirmation that you are connected.", "supabase_jwt": JWT, "tenant_id": TENANT_ID, "source_name": SOURCE_NAME, "available_sources": [SOURCE_NAME], "stream": False, "user_id": TENANT_ID, } run_resp = client.post(f"/tenant-run/{AGENT_ID}", headers=headers, json=run_payload) assert run_resp.status_code == 200, f"tenant-run failed: {run_resp.status_code} {run_resp.text}" run_body = run_resp.json() session_id = run_body.get("session_id") assert session_id, f"session_id missing in tenant-run response: {run_body}" list_resp = client.get(f"/chats/{TENANT_ID}", headers={"Authorization": f"Bearer {JWT}"}) assert list_resp.status_code == 200, f"list chats failed: {list_resp.status_code} {list_resp.text}" list_body = list_resp.json() sessions = list_body.get("sessions", []) assert isinstance(sessions, list), f"sessions should be list, got: {type(sessions)}" assert any((s.get("session_id") or s.get("id")) == session_id for s in sessions), ( f"created session {session_id} not found in session list" ) get_resp = client.get(f"/chats/{TENANT_ID}/{session_id}", headers={"Authorization": f"Bearer {JWT}"}) assert get_resp.status_code == 200, f"get chat failed: {get_resp.status_code} {get_resp.text}" get_body = get_resp.json() assert "messages" in get_body, f"messages missing in get chat response: {get_body}" rename_resp = client.post( f"/chats/{session_id}/rename", headers=headers, json={"name": f"e2e-{uuid.uuid4().hex[:8]}"}, ) assert rename_resp.status_code == 200, f"rename failed: {rename_resp.status_code} {rename_resp.text}" assert rename_resp.json().get("status") == "renamed" cancel_resp = client.post( f"/chats/{session_id}/cancel/{uuid.uuid4().hex}", headers={"Authorization": f"Bearer {JWT}"}, ) assert cancel_resp.status_code == 200, f"cancel failed: {cancel_resp.status_code} {cancel_resp.text}" cancel_body = cancel_resp.json() assert "cancelled" in cancel_body, f"cancelled field missing: {cancel_body}" delete_resp = client.delete(f"/chats/{session_id}", headers={"Authorization": f"Bearer {JWT}"}) assert delete_resp.status_code == 200, f"delete failed: {delete_resp.status_code} {delete_resp.text}" assert delete_resp.json().get("status") == "deleted" get_after_delete = client.get( f"/chats/{TENANT_ID}/{session_id}", headers={"Authorization": f"Bearer {JWT}"}, ) assert get_after_delete.status_code == 404, ( f"expected 404 after delete, got {get_after_delete.status_code} {get_after_delete.text}" )