""" Tests pour le service d'authentification. Couvre: - Hachage de mots de passe - Vérification de mots de passe - Création de tokens JWT - Validation de tokens JWT """ import pytest from datetime import datetime, timedelta from unittest.mock import patch, MagicMock pytestmark = pytest.mark.unit class TestPasswordHashing: """Tests pour le hachage de mots de passe.""" def test_hash_password(self): """Hachage d'un mot de passe.""" from app.services.auth_service import AuthService service = AuthService() password = "SecurePassword123!" hashed = service.hash_password(password) assert hashed != password assert len(hashed) > 20 def test_hash_password_different_each_time(self): """Hachage différent à chaque fois (salt).""" from app.services.auth_service import AuthService service = AuthService() password = "SamePassword" hash1 = service.hash_password(password) hash2 = service.hash_password(password) assert hash1 != hash2 def test_verify_password_success(self): """Vérification réussie.""" from app.services.auth_service import AuthService service = AuthService() password = "CorrectPassword" hashed = service.hash_password(password) result = service.verify_password(password, hashed) assert result is True def test_verify_password_failure(self): """Vérification échouée.""" from app.services.auth_service import AuthService service = AuthService() password = "CorrectPassword" hashed = service.hash_password(password) result = service.verify_password("WrongPassword", hashed) assert result is False def test_verify_password_empty(self): """Mot de passe vide.""" from app.services.auth_service import AuthService service = AuthService() hashed = service.hash_password("SomePassword") result = service.verify_password("", hashed) assert result is False class TestJWTTokens: """Tests pour les tokens JWT.""" def test_create_access_token(self): """Création d'un token.""" from app.services.auth_service import AuthService service = AuthService() result = service.create_access_token( data={"sub": "testuser", "role": "admin"} ) # Returns tuple (token, expires_in) assert isinstance(result, tuple) token, expires_in = result assert isinstance(token, str) assert len(token) > 50 assert expires_in > 0 def test_create_access_token_with_expiry(self): """Token avec expiration personnalisée.""" from app.services.auth_service import AuthService service = AuthService() token, expires_in = service.create_access_token( data={"sub": "testuser"}, expires_delta=timedelta(hours=1) ) assert token is not None assert expires_in == 3600 # 1 hour in seconds def test_decode_token_success(self): """Décodage de token réussi.""" from app.services.auth_service import AuthService service = AuthService() token, _ = service.create_access_token(data={"sub": "testuser"}) token_data = service.decode_token(token) assert token_data is not None assert token_data.username == "testuser" def test_decode_token_invalid(self): """Token invalide.""" from app.services.auth_service import AuthService service = AuthService() token_data = service.decode_token("invalid.token.here") assert token_data is None def test_decode_token_expired(self): """Token expiré.""" from app.services.auth_service import AuthService service = AuthService() # Create token with negative expiry (already expired) token, _ = service.create_access_token( data={"sub": "testuser"}, expires_delta=timedelta(seconds=-10) ) token_data = service.decode_token(token) assert token_data is None def test_token_returns_expires_in(self): """Token retourne le temps d'expiration.""" from app.services.auth_service import AuthService service = AuthService() token, expires_in = service.create_access_token(data={"sub": "testuser"}) # Default is 24 hours = 86400 seconds assert expires_in == 86400 class TestAuthServiceIntegration: """Tests d'intégration pour AuthService.""" def test_full_auth_flow(self): """Flux complet: hash -> verify -> token -> validate.""" from app.services.auth_service import AuthService service = AuthService() # 1. Hash password password = "MySecurePassword123" hashed = service.hash_password(password) # 2. Verify password assert service.verify_password(password, hashed) is True # 3. Create token token, expires_in = service.create_access_token( data={"sub": "user@example.com", "role": "admin"} ) # 4. Validate token token_data = service.decode_token(token) assert token_data is not None assert token_data.username == "user@example.com"