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