""" Integration tests for authentication with database """ import pytest from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from src.database.models import Base, User from src.database.repositories import UserRepository from src.auth.service import AuthService @pytest.fixture def db_session(): """Create an in-memory SQLite database for testing""" engine = create_engine("sqlite:///:memory:") Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) session = Session() yield session session.close() @pytest.fixture def user_repository(db_session): """Create a user repository with test database session""" return UserRepository(db_session) @pytest.fixture def auth_service(user_repository): """Create an auth service with test repository""" return AuthService(user_repository) class TestAuthenticationIntegration: """Integration tests for authentication system""" def test_full_user_creation_and_authentication_flow( self, auth_service, user_repository ): """Test complete flow: create user, authenticate, verify role""" # Create a new user username = "test_user" password = "secure_password_123" role = "User" user = auth_service.create_user_with_hashed_password( username, password, role ) # Verify user was created assert user.id is not None assert user.username == username assert user.role == role assert user.hashed_password != password # Password is hashed # Authenticate with correct credentials authenticated_user = auth_service.authenticate_user(username, password) assert authenticated_user is not None assert authenticated_user.id == user.id assert authenticated_user.username == username assert authenticated_user.role == role assert authenticated_user.is_admin() is False # Verify authentication fails with wrong password failed_auth = auth_service.authenticate_user(username, "wrong_password") assert failed_auth is None def test_admin_user_authentication_and_role_check( self, auth_service, user_repository ): """Test admin user authentication and role identification""" # Create admin user username = "admin_user" password = "admin_password" role = "Admin" user = auth_service.create_user_with_hashed_password( username, password, role ) # Authenticate authenticated_user = auth_service.authenticate_user(username, password) assert authenticated_user is not None assert authenticated_user.role == "Admin" assert authenticated_user.is_admin() is True def test_authentication_fails_for_nonexistent_user(self, auth_service): """Test that authentication fails for user that doesn't exist""" result = auth_service.authenticate_user("nonexistent_user", "password") assert result is None def test_multiple_users_with_different_roles( self, auth_service, user_repository ): """Test authentication with multiple users of different roles""" # Create multiple users admin_user = auth_service.create_user_with_hashed_password( "admin1", "admin_pass", "Admin" ) regular_user1 = auth_service.create_user_with_hashed_password( "user1", "user_pass1", "User" ) regular_user2 = auth_service.create_user_with_hashed_password( "user2", "user_pass2", "User" ) # Authenticate each user auth_admin = auth_service.authenticate_user("admin1", "admin_pass") auth_user1 = auth_service.authenticate_user("user1", "user_pass1") auth_user2 = auth_service.authenticate_user("user2", "user_pass2") # Verify each authentication and role assert auth_admin is not None assert auth_admin.is_admin() is True assert auth_user1 is not None assert auth_user1.is_admin() is False assert auth_user2 is not None assert auth_user2.is_admin() is False # Verify wrong passwords fail assert auth_service.authenticate_user("admin1", "wrong") is None assert auth_service.authenticate_user("user1", "wrong") is None assert auth_service.authenticate_user("user2", "wrong") is None def test_password_hash_is_stored_not_plain_text( self, auth_service, user_repository ): """Test that passwords are hashed before storage""" username = "security_test" password = "my_password" user = auth_service.create_user_with_hashed_password( username, password, "User" ) # Get user from database db_user = user_repository.get_by_username(username) # Verify password is hashed assert db_user.hashed_password != password assert len(db_user.hashed_password) > 50 # bcrypt hashes are long assert db_user.hashed_password.startswith("$2b$") # bcrypt prefix