Remove legacy test files for auth, rate limiting, and users

- Deleted outdated backend test cases (`test_auth.py`, `test_rate_limiting.py`, `test_users.py`) to clean up deprecated test structure.
- These tests are now redundant with newer async test implementations and improved coverage.
This commit is contained in:
Felipe Cardoso
2025-11-01 00:02:17 +01:00
parent 31e2109278
commit f4be8b56f0
10 changed files with 285 additions and 1712 deletions

View File

@@ -1,7 +1,9 @@
# tests/services/test_auth_service.py
import uuid
import pytest
import pytest_asyncio
from unittest.mock import patch
from sqlalchemy import select
from app.core.auth import get_password_hash, verify_password, TokenExpiredError, TokenInvalidError
from app.models.user import User
@@ -12,72 +14,100 @@ from app.services.auth_service import AuthService, AuthenticationError
class TestAuthServiceAuthentication:
"""Tests for AuthService.authenticate_user method"""
def test_authenticate_valid_user(self, db_session, mock_user):
@pytest.mark.asyncio
async def test_authenticate_valid_user(self, async_test_db, async_test_user):
"""Test authenticating a user with valid credentials"""
test_engine, AsyncTestingSessionLocal = async_test_db
# Set a known password for the mock user
password = "TestPassword123"
mock_user.password_hash = get_password_hash(password)
db_session.commit()
async with AsyncTestingSessionLocal() as session:
result = await session.execute(select(User).where(User.id == async_test_user.id))
user = result.scalar_one_or_none()
user.password_hash = get_password_hash(password)
await session.commit()
# Authenticate with correct credentials
user = AuthService.authenticate_user(
db=db_session,
email=mock_user.email,
password=password
)
assert user is not None
assert user.id == mock_user.id
assert user.email == mock_user.email
def test_authenticate_nonexistent_user(self, db_session):
"""Test authenticating with an email that doesn't exist"""
user = AuthService.authenticate_user(
db=db_session,
email="nonexistent@example.com",
password="password"
)
assert user is None
def test_authenticate_with_wrong_password(self, db_session, mock_user):
"""Test authenticating with the wrong password"""
# Set a known password for the mock user
password = "TestPassword123"
mock_user.password_hash = get_password_hash(password)
db_session.commit()
# Authenticate with wrong password
user = AuthService.authenticate_user(
db=db_session,
email=mock_user.email,
password="WrongPassword123"
)
assert user is None
def test_authenticate_inactive_user(self, db_session, mock_user):
"""Test authenticating an inactive user"""
# Set a known password and make user inactive
password = "TestPassword123"
mock_user.password_hash = get_password_hash(password)
mock_user.is_active = False
db_session.commit()
# Should raise AuthenticationError
with pytest.raises(AuthenticationError):
AuthService.authenticate_user(
db=db_session,
email=mock_user.email,
async with AsyncTestingSessionLocal() as session:
auth_user = await AuthService.authenticate_user(
db=session,
email=async_test_user.email,
password=password
)
assert auth_user is not None
assert auth_user.id == async_test_user.id
assert auth_user.email == async_test_user.email
@pytest.mark.asyncio
async def test_authenticate_nonexistent_user(self, async_test_db):
"""Test authenticating with an email that doesn't exist"""
test_engine, AsyncTestingSessionLocal = async_test_db
async with AsyncTestingSessionLocal() as session:
user = await AuthService.authenticate_user(
db=session,
email="nonexistent@example.com",
password="password"
)
assert user is None
@pytest.mark.asyncio
async def test_authenticate_with_wrong_password(self, async_test_db, async_test_user):
"""Test authenticating with the wrong password"""
test_engine, AsyncTestingSessionLocal = async_test_db
# Set a known password for the mock user
password = "TestPassword123"
async with AsyncTestingSessionLocal() as session:
result = await session.execute(select(User).where(User.id == async_test_user.id))
user = result.scalar_one_or_none()
user.password_hash = get_password_hash(password)
await session.commit()
# Authenticate with wrong password
async with AsyncTestingSessionLocal() as session:
auth_user = await AuthService.authenticate_user(
db=session,
email=async_test_user.email,
password="WrongPassword123"
)
assert auth_user is None
@pytest.mark.asyncio
async def test_authenticate_inactive_user(self, async_test_db, async_test_user):
"""Test authenticating an inactive user"""
test_engine, AsyncTestingSessionLocal = async_test_db
# Set a known password and make user inactive
password = "TestPassword123"
async with AsyncTestingSessionLocal() as session:
result = await session.execute(select(User).where(User.id == async_test_user.id))
user = result.scalar_one_or_none()
user.password_hash = get_password_hash(password)
user.is_active = False
await session.commit()
# Should raise AuthenticationError
async with AsyncTestingSessionLocal() as session:
with pytest.raises(AuthenticationError):
await AuthService.authenticate_user(
db=session,
email=async_test_user.email,
password=password
)
class TestAuthServiceUserCreation:
"""Tests for AuthService.create_user method"""
def test_create_new_user(self, db_session):
@pytest.mark.asyncio
async def test_create_new_user(self, async_test_db):
"""Test creating a new user"""
test_engine, AsyncTestingSessionLocal = async_test_db
user_data = UserCreate(
email="newuser@example.com",
password="TestPassword123",
@@ -86,43 +116,49 @@ class TestAuthServiceUserCreation:
phone_number="1234567890"
)
user = AuthService.create_user(db=db_session, user_data=user_data)
async with AsyncTestingSessionLocal() as session:
user = await AuthService.create_user(db=session, user_data=user_data)
# Verify user was created with correct data
assert user is not None
assert user.email == user_data.email
assert user.first_name == user_data.first_name
assert user.last_name == user_data.last_name
assert user.phone_number == user_data.phone_number
# Verify user was created with correct data
assert user is not None
assert user.email == user_data.email
assert user.first_name == user_data.first_name
assert user.last_name == user_data.last_name
assert user.phone_number == user_data.phone_number
# Verify password was hashed
assert user.password_hash != user_data.password
assert verify_password(user_data.password, user.password_hash)
# Verify password was hashed
assert user.password_hash != user_data.password
assert verify_password(user_data.password, user.password_hash)
# Verify default values
assert user.is_active is True
assert user.is_superuser is False
# Verify default values
assert user.is_active is True
assert user.is_superuser is False
def test_create_user_with_existing_email(self, db_session, mock_user):
@pytest.mark.asyncio
async def test_create_user_with_existing_email(self, async_test_db, async_test_user):
"""Test creating a user with an email that already exists"""
test_engine, AsyncTestingSessionLocal = async_test_db
user_data = UserCreate(
email=mock_user.email, # Use existing email
email=async_test_user.email, # Use existing email
password="TestPassword123",
first_name="Duplicate",
last_name="User"
)
# Should raise AuthenticationError
with pytest.raises(AuthenticationError):
AuthService.create_user(db=db_session, user_data=user_data)
async with AsyncTestingSessionLocal() as session:
with pytest.raises(AuthenticationError):
await AuthService.create_user(db=session, user_data=user_data)
class TestAuthServiceTokens:
"""Tests for AuthService token-related methods"""
def test_create_tokens(self, mock_user):
@pytest.mark.asyncio
async def test_create_tokens(self, async_test_user):
"""Test creating access and refresh tokens for a user"""
tokens = AuthService.create_tokens(mock_user)
tokens = AuthService.create_tokens(async_test_user)
# Verify token structure
assert isinstance(tokens, Token)
@@ -130,50 +166,62 @@ class TestAuthServiceTokens:
assert tokens.refresh_token is not None
assert tokens.token_type == "bearer"
# This is a more in-depth test that would decode the tokens to verify claims
# but we'll rely on the auth module tests for token verification
def test_refresh_tokens(self, db_session, mock_user):
@pytest.mark.asyncio
async def test_refresh_tokens(self, async_test_db, async_test_user):
"""Test refreshing tokens with a valid refresh token"""
test_engine, AsyncTestingSessionLocal = async_test_db
# Create initial tokens
initial_tokens = AuthService.create_tokens(mock_user)
initial_tokens = AuthService.create_tokens(async_test_user)
# Refresh tokens
new_tokens = AuthService.refresh_tokens(
db=db_session,
refresh_token=initial_tokens.refresh_token
)
async with AsyncTestingSessionLocal() as session:
new_tokens = await AuthService.refresh_tokens(
db=session,
refresh_token=initial_tokens.refresh_token
)
# Verify new tokens are different from old ones
assert new_tokens.access_token != initial_tokens.access_token
assert new_tokens.refresh_token != initial_tokens.refresh_token
# Verify new tokens are different from old ones
assert new_tokens.access_token != initial_tokens.access_token
assert new_tokens.refresh_token != initial_tokens.refresh_token
def test_refresh_tokens_with_invalid_token(self, db_session):
@pytest.mark.asyncio
async def test_refresh_tokens_with_invalid_token(self, async_test_db):
"""Test refreshing tokens with an invalid token"""
test_engine, AsyncTestingSessionLocal = async_test_db
# Create an invalid token
invalid_token = "invalid.token.string"
# Should raise TokenInvalidError
with pytest.raises(TokenInvalidError):
AuthService.refresh_tokens(
db=db_session,
refresh_token=invalid_token
)
async with AsyncTestingSessionLocal() as session:
with pytest.raises(TokenInvalidError):
await AuthService.refresh_tokens(
db=session,
refresh_token=invalid_token
)
def test_refresh_tokens_with_access_token(self, db_session, mock_user):
@pytest.mark.asyncio
async def test_refresh_tokens_with_access_token(self, async_test_db, async_test_user):
"""Test refreshing tokens with an access token instead of refresh token"""
test_engine, AsyncTestingSessionLocal = async_test_db
# Create tokens
tokens = AuthService.create_tokens(mock_user)
tokens = AuthService.create_tokens(async_test_user)
# Try to refresh with access token
with pytest.raises(TokenInvalidError):
AuthService.refresh_tokens(
db=db_session,
refresh_token=tokens.access_token
)
async with AsyncTestingSessionLocal() as session:
with pytest.raises(TokenInvalidError):
await AuthService.refresh_tokens(
db=session,
refresh_token=tokens.access_token
)
def test_refresh_tokens_with_nonexistent_user(self, db_session):
@pytest.mark.asyncio
async def test_refresh_tokens_with_nonexistent_user(self, async_test_db):
"""Test refreshing tokens for a user that doesn't exist in the database"""
test_engine, AsyncTestingSessionLocal = async_test_db
# Create a token for a non-existent user
non_existent_id = str(uuid.uuid4())
with patch('app.core.auth.decode_token'), patch('app.core.auth.get_token_data') as mock_get_data:
@@ -181,72 +229,96 @@ class TestAuthServiceTokens:
mock_get_data.return_value.user_id = uuid.UUID(non_existent_id)
# Should raise TokenInvalidError
with pytest.raises(TokenInvalidError):
AuthService.refresh_tokens(
db=db_session,
refresh_token="some.refresh.token"
)
async with AsyncTestingSessionLocal() as session:
with pytest.raises(TokenInvalidError):
await AuthService.refresh_tokens(
db=session,
refresh_token="some.refresh.token"
)
class TestAuthServicePasswordChange:
"""Tests for AuthService.change_password method"""
def test_change_password(self, db_session, mock_user):
@pytest.mark.asyncio
async def test_change_password(self, async_test_db, async_test_user):
"""Test changing a user's password"""
test_engine, AsyncTestingSessionLocal = async_test_db
# Set a known password for the mock user
current_password = "CurrentPassword123"
mock_user.password_hash = get_password_hash(current_password)
db_session.commit()
async with AsyncTestingSessionLocal() as session:
result = await session.execute(select(User).where(User.id == async_test_user.id))
user = result.scalar_one_or_none()
user.password_hash = get_password_hash(current_password)
await session.commit()
# Change password
new_password = "NewPassword456"
result = AuthService.change_password(
db=db_session,
user_id=mock_user.id,
current_password=current_password,
new_password=new_password
)
async with AsyncTestingSessionLocal() as session:
result = await AuthService.change_password(
db=session,
user_id=async_test_user.id,
current_password=current_password,
new_password=new_password
)
# Verify operation was successful
assert result is True
# Verify operation was successful
assert result is True
# Refresh user from DB
db_session.refresh(mock_user)
# Verify password was changed
async with AsyncTestingSessionLocal() as session:
result = await session.execute(select(User).where(User.id == async_test_user.id))
updated_user = result.scalar_one_or_none()
# Verify old password no longer works
assert not verify_password(current_password, mock_user.password_hash)
# Verify old password no longer works
assert not verify_password(current_password, updated_user.password_hash)
# Verify new password works
assert verify_password(new_password, mock_user.password_hash)
# Verify new password works
assert verify_password(new_password, updated_user.password_hash)
def test_change_password_wrong_current_password(self, db_session, mock_user):
@pytest.mark.asyncio
async def test_change_password_wrong_current_password(self, async_test_db, async_test_user):
"""Test changing password with incorrect current password"""
test_engine, AsyncTestingSessionLocal = async_test_db
# Set a known password for the mock user
current_password = "CurrentPassword123"
mock_user.password_hash = get_password_hash(current_password)
db_session.commit()
async with AsyncTestingSessionLocal() as session:
result = await session.execute(select(User).where(User.id == async_test_user.id))
user = result.scalar_one_or_none()
user.password_hash = get_password_hash(current_password)
await session.commit()
# Try to change password with wrong current password
wrong_password = "WrongPassword123"
with pytest.raises(AuthenticationError):
AuthService.change_password(
db=db_session,
user_id=mock_user.id,
current_password=wrong_password,
new_password="NewPassword456"
)
async with AsyncTestingSessionLocal() as session:
with pytest.raises(AuthenticationError):
await AuthService.change_password(
db=session,
user_id=async_test_user.id,
current_password=wrong_password,
new_password="NewPassword456"
)
# Verify password was not changed
assert verify_password(current_password, mock_user.password_hash)
async with AsyncTestingSessionLocal() as session:
result = await session.execute(select(User).where(User.id == async_test_user.id))
user = result.scalar_one_or_none()
assert verify_password(current_password, user.password_hash)
def test_change_password_nonexistent_user(self, db_session):
@pytest.mark.asyncio
async def test_change_password_nonexistent_user(self, async_test_db):
"""Test changing password for a user that doesn't exist"""
test_engine, AsyncTestingSessionLocal = async_test_db
non_existent_id = uuid.uuid4()
with pytest.raises(AuthenticationError):
AuthService.change_password(
db=db_session,
user_id=non_existent_id,
current_password="CurrentPassword123",
new_password="NewPassword456"
)
async with AsyncTestingSessionLocal() as session:
with pytest.raises(AuthenticationError):
await AuthService.change_password(
db=session,
user_id=non_existent_id,
current_password="CurrentPassword123",
new_password="NewPassword456"
)