#!/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())