375 lines
11 KiB
Python
375 lines
11 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test variant approval endpoints with proper session handling.
|
|
"""
|
|
|
|
import re
|
|
import sys
|
|
|
|
import httpx
|
|
|
|
BASE_URL = "http://localhost:8000"
|
|
|
|
|
|
def get_csrf_token(client: httpx.Client, page_url: str) -> str:
|
|
"""Extract CSRF token from a page."""
|
|
try:
|
|
response = client.get(page_url)
|
|
if response.status_code == 200:
|
|
match = re.search(r'name="csrf_token" value="([^"]+)"', response.text)
|
|
if match:
|
|
return match.group(1)
|
|
except Exception as e:
|
|
print(f" Error getting CSRF token from {page_url}: {e}")
|
|
return ""
|
|
|
|
|
|
def login(client: httpx.Client) -> bool:
|
|
"""Login and maintain session."""
|
|
# Get login page
|
|
response = client.get("/admin/login")
|
|
if response.status_code != 200:
|
|
print(f" Failed to get login page: {response.status_code}")
|
|
return False
|
|
|
|
match = re.search(r'name="csrf_token" value="([^"]+)"', response.text)
|
|
csrf_token = match.group(1) if match else ""
|
|
|
|
if not csrf_token:
|
|
print(" Failed to get CSRF token")
|
|
return False
|
|
|
|
# Submit login - follow redirects to complete login
|
|
response = client.post(
|
|
"/admin/login",
|
|
data={
|
|
"username": "admin",
|
|
"password": "admin123",
|
|
"csrf_token": csrf_token,
|
|
},
|
|
follow_redirects=True,
|
|
)
|
|
|
|
if response.status_code == 200 and "/admin/dashboard" in str(response.url):
|
|
print(" ✅ Successfully logged in!")
|
|
return True
|
|
|
|
print(f" Login failed: {response.status_code}, URL: {response.url}")
|
|
return False
|
|
|
|
|
|
def test_variant_approval(client: httpx.Client) -> dict:
|
|
"""Test the variant approval endpoint."""
|
|
|
|
# Get CSRF token from the review page
|
|
csrf_token = get_csrf_token(client, "/admin/questions/1/generate?tab=review")
|
|
|
|
if not csrf_token:
|
|
return {
|
|
"status_code": None,
|
|
"has_ise": False,
|
|
"has_traceback": False,
|
|
"error": "Could not get CSRF token - likely not authenticated",
|
|
"response_preview": "",
|
|
}
|
|
|
|
# Submit variant approval
|
|
response = client.post(
|
|
"/admin/questions/1/generate/review-bulk",
|
|
data={
|
|
"item_ids": "1",
|
|
"action": "approved",
|
|
"tab": "review",
|
|
"csrf_token": csrf_token,
|
|
},
|
|
follow_redirects=True,
|
|
)
|
|
|
|
print(f" Response status: {response.status_code}")
|
|
print(f" Final URL: {response.url}")
|
|
|
|
# Check for errors
|
|
has_ise = response.status_code == 500 or "Internal Server Error" in response.text
|
|
has_traceback = "Traceback" in response.text
|
|
|
|
if has_traceback:
|
|
print("\n === TRACEBACK DETECTED ===")
|
|
# Extract just the traceback part
|
|
if "Traceback" in response.text:
|
|
idx = response.text.find("Traceback")
|
|
print(response.text[idx : idx + 3000])
|
|
print(" ==========================\n")
|
|
|
|
return {
|
|
"status_code": response.status_code,
|
|
"has_ise": has_ise,
|
|
"has_traceback": has_traceback,
|
|
"response_preview": response.text[:1000],
|
|
}
|
|
|
|
|
|
def test_basis_item_review(client: httpx.Client) -> dict:
|
|
"""Test the basis item review bulk endpoint."""
|
|
|
|
# Get CSRF token from the basis item page
|
|
csrf_token = get_csrf_token(client, "/admin/basis-items/1")
|
|
|
|
if not csrf_token:
|
|
return {
|
|
"status_code": None,
|
|
"has_ise": False,
|
|
"has_traceback": False,
|
|
"error": "Could not get CSRF token - likely not authenticated",
|
|
"response_preview": "",
|
|
}
|
|
|
|
# Submit basis item review
|
|
response = client.post(
|
|
"/admin/basis-items/1/review-bulk",
|
|
data={
|
|
"item_ids": "1",
|
|
"action": "approved",
|
|
"csrf_token": csrf_token,
|
|
},
|
|
follow_redirects=True,
|
|
)
|
|
|
|
print(f" Response status: {response.status_code}")
|
|
print(f" Final URL: {response.url}")
|
|
|
|
# Check for errors
|
|
has_ise = response.status_code == 500 or "Internal Server Error" in response.text
|
|
has_traceback = "Traceback" in response.text
|
|
|
|
if has_traceback:
|
|
print("\n === TRACEBACK DETECTED ===")
|
|
if "Traceback" in response.text:
|
|
idx = response.text.find("Traceback")
|
|
print(response.text[idx : idx + 3000])
|
|
print(" ==========================\n")
|
|
|
|
return {
|
|
"status_code": response.status_code,
|
|
"has_ise": has_ise,
|
|
"has_traceback": has_traceback,
|
|
"response_preview": response.text[:1000],
|
|
}
|
|
|
|
|
|
def test_snapshot_promote(client: httpx.Client) -> dict:
|
|
"""Test the snapshot questions promote bulk endpoint."""
|
|
|
|
# Get CSRF token from the hierarchy page
|
|
csrf_token = get_csrf_token(client, "/admin/hierarchy")
|
|
|
|
if not csrf_token:
|
|
return {
|
|
"status_code": None,
|
|
"has_ise": False,
|
|
"has_traceback": False,
|
|
"error": "Could not get CSRF token - likely not authenticated",
|
|
"response_preview": "",
|
|
}
|
|
|
|
# Submit snapshot promote (with empty list)
|
|
response = client.post(
|
|
"/admin/snapshot-questions/promote-bulk",
|
|
data={
|
|
"snapshot_id": "1",
|
|
"snapshot_question_ids": "",
|
|
"csrf_token": csrf_token,
|
|
},
|
|
follow_redirects=True,
|
|
)
|
|
|
|
print(f" Response status: {response.status_code}")
|
|
|
|
# Check for errors
|
|
has_ise = response.status_code == 500 or "Internal Server Error" in response.text
|
|
has_traceback = "Traceback" in response.text
|
|
|
|
if has_traceback:
|
|
print("\n === TRACEBACK DETECTED ===")
|
|
if "Traceback" in response.text:
|
|
idx = response.text.find("Traceback")
|
|
print(response.text[idx : idx + 3000])
|
|
print(" ==========================\n")
|
|
|
|
return {
|
|
"status_code": response.status_code,
|
|
"has_ise": has_ise,
|
|
"has_traceback": has_traceback,
|
|
"response_preview": response.text[:1000],
|
|
}
|
|
|
|
|
|
def test_tryout_import_preview(client: httpx.Client) -> dict:
|
|
"""Test the tryout import preview endpoint."""
|
|
|
|
csrf_token = get_csrf_token(client, "/admin/tryout-import")
|
|
|
|
if not csrf_token:
|
|
return {
|
|
"status_code": None,
|
|
"has_ise": False,
|
|
"has_traceback": False,
|
|
"error": "Could not get CSRF token",
|
|
"response_preview": "",
|
|
}
|
|
|
|
# Submit tryout import preview (without file)
|
|
response = client.post(
|
|
"/admin/tryout-import/preview",
|
|
data={
|
|
"website_id": "1",
|
|
"csrf_token": csrf_token,
|
|
},
|
|
follow_redirects=True,
|
|
)
|
|
|
|
print(f" Response status: {response.status_code}")
|
|
|
|
has_ise = response.status_code == 500 or "Internal Server Error" in response.text
|
|
has_traceback = "Traceback" in response.text
|
|
|
|
if has_traceback:
|
|
print("\n === TRACEBACK DETECTED ===")
|
|
if "Traceback" in response.text:
|
|
idx = response.text.find("Traceback")
|
|
print(response.text[idx : idx + 3000])
|
|
print(" ==========================\n")
|
|
|
|
return {
|
|
"status_code": response.status_code,
|
|
"has_ise": has_ise,
|
|
"has_traceback": has_traceback,
|
|
"response_preview": response.text[:1000],
|
|
}
|
|
|
|
|
|
def test_website_crud(client: httpx.Client) -> dict:
|
|
"""Test website creation endpoint."""
|
|
|
|
csrf_token = get_csrf_token(client, "/admin/websites")
|
|
|
|
if not csrf_token:
|
|
return {
|
|
"status_code": None,
|
|
"has_ise": False,
|
|
"has_traceback": False,
|
|
"error": "Could not get CSRF token",
|
|
"response_preview": "",
|
|
}
|
|
|
|
# Submit website creation
|
|
response = client.post(
|
|
"/admin/websites",
|
|
data={
|
|
"site_name": "Test Site",
|
|
"site_url": "https://test.example.com",
|
|
"csrf_token": csrf_token,
|
|
},
|
|
follow_redirects=True,
|
|
)
|
|
|
|
print(f" Response status: {response.status_code}")
|
|
|
|
has_ise = response.status_code == 500 or "Internal Server Error" in response.text
|
|
has_traceback = "Traceback" in response.text
|
|
|
|
if has_traceback:
|
|
print("\n === TRACEBACK DETECTED ===")
|
|
if "Traceback" in response.text:
|
|
idx = response.text.find("Traceback")
|
|
print(response.text[idx : idx + 3000])
|
|
print(" ==========================\n")
|
|
|
|
return {
|
|
"status_code": response.status_code,
|
|
"has_ise": has_ise,
|
|
"has_traceback": has_traceback,
|
|
"response_preview": response.text[:1000],
|
|
}
|
|
|
|
|
|
def main():
|
|
print("=" * 80)
|
|
print("Testing Form POST Endpoints for Internal Server Errors")
|
|
print("=" * 80)
|
|
print()
|
|
|
|
results = []
|
|
|
|
with httpx.Client(base_url=BASE_URL, timeout=30.0) as client:
|
|
# Login
|
|
print("Step 1: Logging in...")
|
|
if not login(client):
|
|
print("❌ Login failed")
|
|
return 1
|
|
print()
|
|
|
|
# Test 1: Variant approval
|
|
print(
|
|
"Step 2: Testing variant approval (/admin/questions/1/generate/review-bulk)..."
|
|
)
|
|
result1 = test_variant_approval(client)
|
|
results.append(("Variant approval", result1))
|
|
print()
|
|
|
|
# Test 2: Basis item review
|
|
print("Step 3: Testing basis item review (/admin/basis-items/1/review-bulk)...")
|
|
result2 = test_basis_item_review(client)
|
|
results.append(("Basis item review", result2))
|
|
print()
|
|
|
|
# Test 3: Snapshot promote
|
|
print(
|
|
"Step 4: Testing snapshot promote (/admin/snapshot-questions/promote-bulk)..."
|
|
)
|
|
result3 = test_snapshot_promote(client)
|
|
results.append(("Snapshot promote", result3))
|
|
print()
|
|
|
|
# Test 4: Tryout import preview
|
|
print("Step 5: Testing tryout import preview (/admin/tryout-import/preview)...")
|
|
result4 = test_tryout_import_preview(client)
|
|
results.append(("Tryout import preview", result4))
|
|
print()
|
|
|
|
# Test 5: Website creation
|
|
print("Step 6: Testing website creation (/admin/websites)...")
|
|
result5 = test_website_crud(client)
|
|
results.append(("Website creation", result5))
|
|
print()
|
|
|
|
# Summary
|
|
print("=" * 80)
|
|
print("RESULTS SUMMARY")
|
|
print("=" * 80)
|
|
|
|
all_good = True
|
|
for name, result in results:
|
|
if result.get("has_ise") or result.get("has_traceback"):
|
|
print(f"❌ {name}: INTERNAL SERVER ERROR!")
|
|
print(f" Status: {result['status_code']}")
|
|
print(f" Preview: {result['response_preview'][:200]}...")
|
|
all_good = False
|
|
elif result.get("error"):
|
|
print(f"⚠️ {name}: {result['error']}")
|
|
elif result["status_code"] in [200, 303]:
|
|
print(f"✅ {name}: OK ({result['status_code']})")
|
|
else:
|
|
print(f"⚠️ {name}: Unexpected status {result['status_code']}")
|
|
|
|
print()
|
|
if all_good:
|
|
print("✅ All form POST endpoints passed! No Internal Server Errors detected.")
|
|
return 0
|
|
else:
|
|
print("❌ Some endpoints have issues. Please review the output above.")
|
|
return 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|