#!/usr/bin/env python3 """ RTSport Auth Integration Test Tests JWT authentication flow with all role types """ import sys import os sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) import json from datetime import datetime from app.auth import create_access_token, verify_token, hash_password, verify_password from app.models import User def test_jwt_token_creation(): """Test JWT token creation and verification""" print("=" * 60) print("TEST: JWT Token Creation and Verification") print("=" * 60) # Create token for AT user token = create_access_token( user_id="usr_at001", role="at", school_id="schl_001" ) print(f"\nCreated Token (AT): {token[:50]}...") # Verify token payload = verify_token(token) print(f"Verified Payload:") print(f" user_id: {payload['user_id']}") print(f" role: {payload['role']}") print(f" school_id: {payload['school_id']}") print(f" exp: {payload['exp']}") print(f" iat: {payload['iat']}") assert payload['user_id'] == "usr_at001" assert payload['role'] == "at" assert payload['school_id'] == "schl_001" print("\n✅ PASS: Token creation and verification works") # Test tokens for each role roles = ["at", "coach", "parent", "admin"] print("\n--- Token Samples for Each Role ---") for role in roles: token = create_access_token( user_id=f"usr_{role}001", role=role, school_id="schl_001" ) payload = verify_token(token) print(f"\nRole: {role}") print(f" Token: {token}") print(f" Claims: {json.dumps(payload, indent=2)}") return True def test_password_hashing(): """Test bcrypt password hashing""" print("\n" + "=" * 60) print("TEST: Password Hashing (bcrypt)") print("=" * 60) password = "SecurePass123!" # Hash password hashed = hash_password(password) print(f"\nOriginal Password: {password}") print(f"Hashed Password: {hashed}") # Verify correct password is_valid = verify_password(password, hashed) print(f"\nVerify correct password: {is_valid}") assert is_valid, "Password verification failed for correct password" # Verify wrong password is_invalid = verify_password("WrongPassword", hashed) print(f"Verify wrong password: {is_invalid}") assert not is_invalid, "Password verification succeeded for wrong password" print("\n✅ PASS: Password hashing works correctly") return True def test_token_expiration(): """Test expired token handling""" print("\n" + "=" * 60) print("TEST: Token Expiration") print("=" * 60) from datetime import timedelta # Create expired token (negative expiration) expired_token = create_access_token( user_id="usr_test001", role="at", school_id="schl_001", expires_delta=timedelta(minutes=-1) # Already expired ) # Verify expired token payload = verify_token(expired_token) print(f"\nExpired token payload: {payload}") assert payload is None, "Expired token should return None" print("\n✅ PASS: Expired tokens are rejected") return True def test_invalid_token(): """Test invalid token handling""" print("\n" + "=" * 60) print("TEST: Invalid Token Rejection") print("=" * 60) invalid_tokens = [ "not.a.token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9", # Incomplete JWT "invalid.token.signature", ] for token in invalid_tokens: payload = verify_token(token) print(f"\nToken: {token[:30]}...") print(f"Payload: {payload}") assert payload is None, f"Invalid token should return None: {token}" print("\n✅ PASS: Invalid tokens are rejected") return True def print_token_usage_examples(): """Print examples of how to use tokens in API requests""" print("\n" + "=" * 60) print("EXAMPLES: Using JWT Tokens in API Requests") print("=" * 60) # Generate sample tokens at_token = create_access_token("usr_at001", "at", "schl_001") coach_token = create_access_token("usr_coach001", "coach", "schl_001") parent_token = create_access_token("usr_parent001", "parent", "schl_001") examples = [ ("AT User Token", at_token), ("Coach User Token", coach_token), ("Parent User Token", parent_token), ] for name, token in examples: print(f"\n--- {name} ---") print(f"Token: {token}") print(f"\n# cURL Example:") print(f"curl -H \"Authorization: Bearer {token}\" \\") print(f" http://localhost:8000/api/v1/roster?school_id=schl_001") print(f"\n# Python Example:") print(f"headers = {{'Authorization': 'Bearer {token}'}}") print(f"response = requests.get(url, headers=headers)") print("\n" + "=" * 60) print("TOKEN FORMAT SUMMARY") print("=" * 60) print(""" JWT Token Structure: Header: { "alg": "HS256", "typ": "JWT" } Payload: { "sub": "usr_001", # user_id "role": "at", # at|coach|parent|admin "school_id": "schl_001", "exp": 1719878400, # expiration "iat": 1719874800, # issued at "type": "access" } Signature: HMAC-SHA256(secret_key, base64(header) + "." + base64(payload)) Authorization Header: Authorization: Bearer """) def main(): """Run all auth tests""" print("\n" + "=" * 60) print("RTSport Auth Layer Integration Tests") print("=" * 60) all_passed = True try: test_jwt_token_creation() except AssertionError as e: print(f"\n❌ FAILED: {e}") all_passed = False try: test_password_hashing() except AssertionError as e: print(f"\n❌ FAILED: {e}") all_passed = False try: test_token_expiration() except AssertionError as e: print(f"\n❌ FAILED: {e}") all_passed = False try: test_invalid_token() except AssertionError as e: print(f"\n❌ FAILED: {e}") all_passed = False print_token_usage_examples() print("\n" + "=" * 60) if all_passed: print("✅ ALL TESTS PASSED") else: print("❌ SOME TESTS FAILED") print("=" * 60) return 0 if all_passed else 1 if __name__ == "__main__": sys.exit(main())