hamzabhatti/Todo-fullstack-web
0
1"""2Test Authentication System3 4This script tests the complete authentication flow:5- User registration6- User login7- JWT token generation8- JWT token verification9- Protected endpoint access10"""11 12from sqlmodel import SQLModel, create_engine, Session, select13from app.models.user import User14from app.schemas.user import UserCreate, UserLogin15from app.auth import get_password_hash, verify_password, create_access_token, decode_token16from jose import JWTError17import uuid18 19# Create SQLite in-memory engine for testing20test_engine = create_engine("sqlite:///:memory:", echo=False)21 22 23def test_authentication():24 """Test complete authentication flow"""25 print("\n" + "="*60)26 print("Testing Authentication System")27 print("="*60)28 29 # Create tables30 print("\n1. Setting up test database...")31 SQLModel.metadata.create_all(test_engine)32 print("✓ Database tables created")33 34 # Test password hashing35 print("\n2. Testing password hashing...")36 plain_password = "password123" # Simple password for testing37 hashed = get_password_hash(plain_password)38 assert len(hashed) > 039 assert hashed != plain_password40 print(f"✓ Password hashed successfully")41 print(f" Plain: {plain_password}")42 print(f" Hash: {hashed[:50]}...")43 44 # Test password verification45 print("\n3. Testing password verification...")46 assert verify_password(plain_password, hashed) == True47 assert verify_password("WrongPassword", hashed) == False48 print("✓ Password verification works correctly")49 50 # Test user registration51 print("\n4. Testing user registration...")52 with Session(test_engine) as session:53 # Create user54 user_email = "test@example.com"55 user_password = "SecurePass123!"56 57 # Check user doesn't exist58 statement = select(User).where(User.email == user_email)59 existing_user = session.exec(statement).first()60 assert existing_user is None61 print(f"✓ Verified user doesn't exist yet")62 63 # Register user64 hashed_password = get_password_hash(user_password)65 new_user = User(66 email=user_email,67 hashed_password=hashed_password68 )69 session.add(new_user)70 session.commit()71 session.refresh(new_user)72 73 user_id = new_user.id74 print(f"✓ User registered: {user_email}")75 print(f" User ID: {user_id}")76 77 # Test user login78 print("\n5. Testing user login...")79 with Session(test_engine) as session:80 # Get user81 statement = select(User).where(User.email == user_email)82 user = session.exec(statement).first()83 assert user is not None84 print(f"✓ User found: {user.email}")85 86 # Verify password87 assert verify_password(user_password, user.hashed_password)88 print("✓ Password verified successfully")89 90 # Wrong password should fail91 assert not verify_password("WrongPassword", user.hashed_password)92 print("✓ Wrong password correctly rejected")93 94 # Test JWT token creation95 print("\n6. Testing JWT token creation...")96 token = create_access_token(data={"sub": str(user_id)})97 assert len(token) > 098 print(f"✓ JWT token created")99 print(f" Token: {token[:50]}...")100 101 # Test JWT token decoding102 print("\n7. Testing JWT token verification...")103 try:104 payload = decode_token(token)105 assert payload["sub"] == str(user_id)106 print(f"✓ Token decoded successfully")107 print(f" User ID from token: {payload['sub']}")108 except JWTError as e:109 print(f"✗ Token verification failed: {e}")110 raise111 112 # Test invalid token113 print("\n8. Testing invalid token rejection...")114 try:115 decode_token("invalid.token.here")116 print("✗ Invalid token was accepted (should have failed!)")117 raise AssertionError("Invalid token should be rejected")118 except JWTError:119 print("✓ Invalid token correctly rejected")120 121 # Test expired token handling122 print("\n9. Testing token expiration...")123 from datetime import timedelta124 expired_token = create_access_token(125 data={"sub": str(user_id)},126 expires_delta=timedelta(seconds=-1) # Already expired127 )128 try:129 decode_token(expired_token)130 print("✗ Expired token was accepted (should have failed!)")131 raise AssertionError("Expired token should be rejected")132 except JWTError:133 print("✓ Expired token correctly rejected")134 135 # Test duplicate email registration136 print("\n10. Testing duplicate email prevention...")137 with Session(test_engine) as session:138 statement = select(User).where(User.email == user_email)139 existing = session.exec(statement).first()140 assert existing is not None141 print(f"✓ Duplicate email check works (user exists)")142 143 # Test complete auth flow144 print("\n11. Testing complete authentication flow...")145 test_email = "newuser@example.com"146 test_password = "NewUserPass123!"147 148 with Session(test_engine) as session:149 # Register150 new_user = User(151 email=test_email,152 hashed_password=get_password_hash(test_password)153 )154 session.add(new_user)155 session.commit()156 session.refresh(new_user)157 print(f"✓ Step 1: User registered")158 159 # Login (verify credentials)160 statement = select(User).where(User.email == test_email)161 user = session.exec(statement).first()162 assert user is not None163 assert verify_password(test_password, user.hashed_password)164 print(f"✓ Step 2: Credentials verified")165 166 # Generate token167 auth_token = create_access_token(data={"sub": str(user.id)})168 print(f"✓ Step 3: Token generated")169 170 # Verify token171 payload = decode_token(auth_token)172 assert payload["sub"] == str(user.id)173 print(f"✓ Step 4: Token verified")174 175 # Access protected resource (simulate)176 token_user_id = uuid.UUID(payload["sub"])177 statement = select(User).where(User.id == token_user_id)178 authenticated_user = session.exec(statement).first()179 assert authenticated_user.email == test_email180 print(f"✓ Step 5: Protected resource accessed")181 182 # Test security features183 print("\n12. Testing security features...")184 185 # Password requirements186 weak_passwords = ["123", "password", "abc"]187 for weak in weak_passwords:188 if len(weak) < 8:189 print(f"✓ Weak password would be rejected: '{weak}' (too short)")190 191 # Token payload inspection192 payload = decode_token(token)193 assert "exp" in payload # Expiration time194 assert "sub" in payload # Subject (user ID)195 print("✓ Token contains required claims (sub, exp)")196 197 print("\n" + "="*60)198 print("All authentication tests passed successfully! ✓")199 print("="*60)200 201 return True202 203 204if __name__ == "__main__":205 try:206 test_authentication()207 except Exception as e:208 print(f"\n✗ Authentication test failed: {e}")209 import traceback210 traceback.print_exc()211 exit(1)212 