Spaces:
Runtime error
Runtime error
File size: 6,254 Bytes
37a6ee1 | 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 | import os
import sys
import io
import time
from fastapi.testclient import TestClient
# Ensure parent directory is in python path
current_dir = os.path.dirname(os.path.abspath(__file__))
if current_dir not in sys.path:
sys.path.insert(0, current_dir)
from backend.main import app
from backend import config
client = TestClient(app)
def test_health():
print("\n--- Test Health Endpoint ---")
response = client.get("/health")
assert response.status_code == 200
data = response.json()
assert data["status"] == "healthy"
assert data["groq_configured"] is True
assert "sales" in data["sample_datasets"]
print("[OK] Health endpoint returned healthy state.")
def test_get_datasets():
print("\n--- Test Get Datasets ---")
response = client.get("/datasets")
assert response.status_code == 200
data = response.json()
assert "datasets" in data
assert data["total"] >= 3
# Verify sample datasets exist
sample_names = {ds["db_name"] for ds in data["datasets"] if ds["is_sample"]}
assert "sales" in sample_names
assert "employees" in sample_names
assert "ecommerce" in sample_names
print(f"[OK] Retrieved {data['total']} datasets successfully.")
def test_get_schema():
print("\n--- Test Get Schema ---")
# Valid dataset
response = client.get("/datasets/employees/schema")
assert response.status_code == 200
data = response.json()
assert data["db_name"] == "employees"
assert data["table_name"] == "data"
assert len(data["columns"]) > 0
assert data["row_count"] == 25
print("[OK] Schema for employees retrieved successfully.")
# Invalid dataset (404)
response = client.get("/datasets/nonexistent_db/schema")
assert response.status_code == 404
print("[OK] Non-existent schema query correctly returned 404.")
# Path traversal validation (400)
response = client.get("/datasets/invalid-name-with-dash/schema")
assert response.status_code == 400
print("[OK] Invalid db_name with dash correctly returned 400.")
def test_upload_and_delete_flow():
print("\n--- Test CSV Upload, Preview, and Delete Flow ---")
# 1. Create a dummy CSV file
csv_content = (
"id,name,role,level\n"
"1,Alice,Engineer,L1\n"
"2,Bob,Product Manager,L2\n"
"3,Charlie,Designer,L1\n"
)
file_payload = {"file": ("test_upload_dataset.csv", io.BytesIO(csv_content.encode("utf-8")), "text/csv")}
# 2. Upload the CSV file
response = client.post("/upload", files=file_payload)
assert response.status_code == 200
data = response.json()
assert data["success"] is True
assert data["db_name"] == "test_upload_dataset"
assert data["row_count"] == 3
assert "name" in data["columns"]
print("[OK] Uploaded CSV dataset successfully.")
# 3. Upload duplicate CSV file (expected 409)
file_payload_dup = {"file": ("test_upload_dataset.csv", io.BytesIO(csv_content.encode("utf-8")), "text/csv")}
response_dup = client.post("/upload", files=file_payload_dup)
assert response_dup.status_code == 409
assert "already uploaded" in response_dup.json()["detail"]
print("[OK] Duplicate upload correctly rejected with 409 Conflict.")
# 4. Preview the uploaded dataset
response_preview = client.get("/datasets/test_upload_dataset/preview")
assert response_preview.status_code == 200
preview_data = response_preview.json()
assert preview_data["row_count"] == 3
assert len(preview_data["rows"]) == 3
assert preview_data["columns"] == ["id", "name", "role", "level"]
print("[OK] Previewed uploaded dataset successfully.")
# 5. Delete the uploaded dataset
response_delete = client.delete("/datasets/test_upload_dataset")
assert response_delete.status_code == 200
assert response_delete.json()["success"] is True
print("[OK] Deleted uploaded dataset successfully.")
# 6. Try deleting a sample dataset (expected 403)
response_del_sample = client.delete("/datasets/employees")
assert response_del_sample.status_code == 403
print("[OK] Deleting sample dataset correctly rejected with 403 Forbidden.")
def test_query_pipeline():
print("\n--- Test Query Pipeline ---")
# Standard query
payload = {
"question": "What is the average revenue for products in the Clothing category?",
"db_name": "sales"
}
response = client.post("/query", json=payload)
assert response.status_code == 200
data = response.json()
assert data["question"] == payload["question"]
assert data["db_name"] == "sales"
assert "results" in data
assert len(data["results"]["columns"]) > 0
assert "insight" in data
assert "X-Process-Time" in response.headers
print(f"[OK] Standard query returned successfully in {response.headers['X-Process-Time']}.")
print(f" SQL: {data['sql']}")
print(f" Insight: {data['insight']}")
# Validation: min length constraint on question (expected 422)
payload_short = {
"question": "a",
"db_name": "sales"
}
response_short = client.post("/query", json=payload_short)
assert response_short.status_code == 422
print("[OK] Question less than 3 characters correctly rejected with 422.")
# Validation: max length constraint on question (expected 422)
payload_long = {
"question": "a" * 301,
"db_name": "sales"
}
response_long = client.post("/query", json=payload_long)
assert response_long.status_code == 422
print("[OK] Question greater than 300 characters correctly rejected with 422.")
# Validation: db_name pattern constraint (expected 422)
payload_bad_db = {
"question": "What is the average revenue?",
"db_name": "sales-invalid-dash"
}
response_bad_db = client.post("/query", json=payload_bad_db)
assert response_bad_db.status_code == 422
print("[OK] Database name with invalid format correctly rejected with 422.")
if __name__ == "__main__":
print("Starting integration tests for API routes...")
test_health()
test_get_datasets()
test_get_schema()
test_upload_and_delete_flow()
test_query_pipeline()
print("\nAll API integration tests passed successfully!")
|