
#!/usr/bin/env python3
"""
QUESTION 9: Test RateRight Error Handling System
Tests API error responses and status codes for various error scenarios
"""

from app import create_app

def test_error_handling():
    """Test error handling across all API endpoints"""
    print("🚨 Testing RateRight Error Handling System")
    print("=" * 50)
    
    app = create_app()
    client = app.test_client()
    
    print("📋 Testing Invalid Endpoints & Missing Data:")
    
    # Test invalid endpoints
    invalid_tests = [
        ('GET', '/api/nonexistent', 'Should return 404'),
        ('POST', '/api/auth/login', 'Should return 400 for missing data', {}),
        ('GET', '/api/auth/me', 'Should return 401 for no token'),
        ('POST', '/api/auth/register', 'Should return 400 for invalid data', {'email': 'invalid'}),
        ('GET', '/api/marketplace/jobs/99999', 'Should return 404 for non-existent job'),
        ('POST', '/api/marketplace/jobs', 'Should return 401 for unauthorized access', {}),
        ('GET', '/api/gamification/leaderboard', 'Should return 401 for no authentication'),
        ('POST', '/api/legal/contracts', 'Should return 401 for unauthorized contract creation', {}),
        ('GET', '/api/safety/assessments/99999', 'Should return 404 for non-existent assessment'),
    ]
    
    results = []
    for test_data in invalid_tests:
        method = test_data[0]
        url = test_data[1]
        description = test_data[2]
        data = test_data[3] if len(test_data) > 3 else {}
        
        if method == 'POST':
            response = client.post(url, json=data)
        elif method == 'PUT':
            response = client.put(url, json=data)
        elif method == 'DELETE':
            response = client.delete(url)
        else:
            response = client.get(url)
        
        results.append((description, response.status_code, url, method))
        print(f'   {description}: {response.status_code}')
    
    print(f"\n🔍 Detailed Error Analysis:")
    
    # Check for proper 404 handling
    not_found_tests = [r for r in results if '404' in r[0]]
    valid_404s = [r for r in not_found_tests if r[1] == 404]
    print(f"   404 Not Found: {len(valid_404s)}/{len(not_found_tests)} correct")
    
    # Check for proper 401 handling
    unauthorized_tests = [r for r in results if '401' in r[0]]
    valid_401s = [r for r in unauthorized_tests if r[1] == 401]
    print(f"   401 Unauthorized: {len(valid_401s)}/{len(unauthorized_tests)} correct")
    
    # Check for proper 400 handling
    bad_request_tests = [r for r in results if '400' in r[0]]
    valid_400s = [r for r in bad_request_tests if r[1] == 400]
    print(f"   400 Bad Request: {len(valid_400s)}/{len(bad_request_tests)} correct")
    
    print(f"\n🧪 Testing Specific Error Scenarios:")
    
    # Test malformed JSON
    print("   Testing malformed JSON:")
    response = client.post('/api/auth/login', 
                          data='{"email": invalid json}',
                          content_type='application/json')
    print(f"   Malformed JSON: {response.status_code} (expected 400)")
    
    # Test missing Content-Type
    print("   Testing missing Content-Type:")
    response = client.post('/api/auth/login', data='{"email": "test@test.com"}')
    print(f"   Missing Content-Type: {response.status_code}")
    
    # Test invalid HTTP methods
    print("   Testing invalid HTTP methods:")
    response = client.patch('/api/auth/login')
    print(f"   PATCH on login endpoint: {response.status_code} (expected 405)")
    
    # Test authentication edge cases
    print("   Testing authentication edge cases:")
    response = client.get('/api/auth/me', headers={'Authorization': 'Bearer invalid_token'})
    print(f"   Invalid JWT token: {response.status_code} (expected 401)")
    
    response = client.get('/api/auth/me', headers={'Authorization': 'InvalidFormat'})
    print(f"   Invalid auth format: {response.status_code} (expected 401)")
    
    print(f"\n⚡ Testing Rate Limiting & Large Payloads:")
    
    # Test large payload
    large_payload = {'data': 'x' * 10000}  # 10KB payload
    response = client.post('/api/auth/register', json=large_payload)
    print(f"   Large payload handling: {response.status_code}")
    
    # Test empty requests
    response = client.post('/api/auth/login', json=None)
    print(f"   Null JSON payload: {response.status_code}")
    
    print(f"\n🏥 Testing Health & Status Endpoints:")
    
    # Test health endpoint
    response = client.get('/')
    print(f"   Root endpoint: {response.status_code} (should be 200)")
    
    response = client.get('/api/health')
    print(f"   Health check: {response.status_code} (should be 200)")
    
    print(f"\n📊 Error Response Format Validation:")
    
    # Check error response format
    response = client.post('/api/auth/login', json={})
    if response.status_code == 400:
        try:
            error_data = response.get_json()
            if 'error' in error_data:
                print(f"   ✅ Error responses include 'error' field")
            else:
                print(f"   ❌ Error responses missing 'error' field")
        except:
            print(f"   ❌ Error responses not valid JSON")
    
    # Test various endpoints for consistent error format
    error_endpoints = [
        ('POST', '/api/auth/login', {}),
        ('POST', '/api/auth/register', {}),
        ('GET', '/api/auth/me', {}),
    ]
    
    consistent_format = True
    for method, url, data in error_endpoints:
        if method == 'POST':
            response = client.post(url, json=data)
        else:
            response = client.get(url)
        
        if response.status_code >= 400:
            try:
                error_data = response.get_json()
                if 'error' not in error_data:
                    consistent_format = False
                    break
            except:
                consistent_format = False
                break
    
    if consistent_format:
        print(f"   ✅ Error responses have consistent format")
    else:
        print(f"   ❌ Inconsistent error response format")
    
    print("=" * 50)
    
    # Summary assessment
    all_404s_correct = len(valid_404s) == len(not_found_tests)
    all_401s_correct = len(valid_401s) == len(unauthorized_tests)
    all_400s_correct = len(valid_400s) == len(bad_request_tests)
    
    if all_404s_correct and all_401s_correct and all_400s_correct and consistent_format:
        print("🎉 ERROR HANDLING SYSTEM: ✅ ALL TESTS PASSED")
        print("   ✅ Proper 404 responses for non-existent resources")
        print("   ✅ Proper 401 responses for unauthorized access")
        print("   ✅ Proper 400 responses for bad requests")
        print("   ✅ Consistent error response format")
        print("   ✅ Graceful handling of edge cases")
        print("   ✅ Error handling system working perfectly")
    else:
        print("⚠️  ERROR HANDLING SYSTEM: ❌ SOME ISSUES FOUND")
        if not all_404s_correct:
            print("   ❌ Some 404 responses incorrect")
        if not all_401s_correct:
            print("   ❌ Some 401 responses incorrect")
        if not all_400s_correct:
            print("   ❌ Some 400 responses incorrect")
        if not consistent_format:
            print("   ❌ Inconsistent error response format")
    
    print(f"\n📈 Error Handling Statistics:")
    print(f"   Total tests run: {len(results) + 6}")
    print(f"   404 errors: {len(valid_404s)}/{len(not_found_tests)}")
    print(f"   401 errors: {len(valid_401s)}/{len(unauthorized_tests)}")
    print(f"   400 errors: {len(valid_400s)}/{len(bad_request_tests)}")
    print(f"   System stability: {'✅ EXCELLENT' if consistent_format else '⚠️ NEEDS ATTENTION'}")

if __name__ == '__main__':
    test_error_handling()
