Files
fast-next-template/backend/tests/api/dependencies/test_auth_dependencies.py
Felipe Cardoso 6d34f81912 Add deployment Docker Compose file, testing utilities, security helpers, and database initialization script
- Introduced `docker-compose.deploy.yml` for deployment scenarios with pre-built Docker images.
- Added `auth_test_utils.py` to simplify authentication testing in FastAPI.
- Implemented `security.py` for token-based operations like file uploads and password resets.
- Created `init_db.py` for database initialization and superuser creation during startup.
- Updated dependencies and tests to support optional authentication in FastAPI.
- Enhanced entrypoint script to handle database initialization.
2025-10-29 22:30:43 +01:00

214 lines
8.1 KiB
Python

# tests/api/dependencies/test_auth_dependencies.py
import pytest
import uuid
from unittest.mock import patch
from fastapi import HTTPException
from app.api.dependencies.auth import (
get_current_user,
get_current_active_user,
get_current_superuser,
get_optional_current_user
)
from app.core.auth import TokenExpiredError, TokenInvalidError
@pytest.fixture
def mock_token():
"""Fixture providing a mock JWT token"""
return "mock.jwt.token"
class TestGetCurrentUser:
"""Tests for get_current_user dependency"""
def test_get_current_user_success(self, db_session, mock_user, mock_token):
"""Test successfully getting the current user"""
# Mock get_token_data to return user_id that matches our mock_user
with patch('app.api.dependencies.auth.get_token_data') as mock_get_data:
mock_get_data.return_value.user_id = mock_user.id
# Call the dependency
user = get_current_user(db=db_session, token=mock_token)
# Verify the correct user was returned
assert user.id == mock_user.id
assert user.email == mock_user.email
def test_get_current_user_nonexistent(self, db_session, mock_token):
"""Test when the token contains a user ID that doesn't exist"""
# Mock get_token_data to return a non-existent user ID
nonexistent_id = uuid.UUID("11111111-1111-1111-1111-111111111111")
with patch('app.api.dependencies.auth.get_token_data') as mock_get_data:
mock_get_data.return_value.user_id = nonexistent_id
# Should raise HTTPException with 404 status
with pytest.raises(HTTPException) as exc_info:
get_current_user(db=db_session, token=mock_token)
assert exc_info.value.status_code == 404
assert "User not found" in exc_info.value.detail
def test_get_current_user_inactive(self, db_session, mock_user, mock_token):
"""Test when the user is inactive"""
# Make the user inactive
mock_user.is_active = False
db_session.commit()
# Mock get_token_data
with patch('app.api.dependencies.auth.get_token_data') as mock_get_data:
mock_get_data.return_value.user_id = mock_user.id
# Should raise HTTPException with 403 status
with pytest.raises(HTTPException) as exc_info:
get_current_user(db=db_session, token=mock_token)
assert exc_info.value.status_code == 403
assert "Inactive user" in exc_info.value.detail
def test_get_current_user_expired_token(self, db_session, mock_token):
"""Test with an expired token"""
# Mock get_token_data to raise TokenExpiredError
with patch('app.api.dependencies.auth.get_token_data') as mock_get_data:
mock_get_data.side_effect = TokenExpiredError("Token expired")
# Should raise HTTPException with 401 status
with pytest.raises(HTTPException) as exc_info:
get_current_user(db=db_session, token=mock_token)
assert exc_info.value.status_code == 401
assert "Token expired" in exc_info.value.detail
def test_get_current_user_invalid_token(self, db_session, mock_token):
"""Test with an invalid token"""
# Mock get_token_data to raise TokenInvalidError
with patch('app.api.dependencies.auth.get_token_data') as mock_get_data:
mock_get_data.side_effect = TokenInvalidError("Invalid token")
# Should raise HTTPException with 401 status
with pytest.raises(HTTPException) as exc_info:
get_current_user(db=db_session, token=mock_token)
assert exc_info.value.status_code == 401
assert "Could not validate credentials" in exc_info.value.detail
class TestGetCurrentActiveUser:
"""Tests for get_current_active_user dependency"""
def test_get_current_active_user(self, mock_user):
"""Test getting an active user"""
# Ensure user is active
mock_user.is_active = True
# Call the dependency with mocked current_user
user = get_current_active_user(current_user=mock_user)
# Should return the same user
assert user == mock_user
def test_get_current_inactive_user(self, mock_user):
"""Test getting an inactive user"""
# Make user inactive
mock_user.is_active = False
# Should raise HTTPException with 403 status
with pytest.raises(HTTPException) as exc_info:
get_current_active_user(current_user=mock_user)
assert exc_info.value.status_code == 403
assert "Inactive user" in exc_info.value.detail
class TestGetCurrentSuperuser:
"""Tests for get_current_superuser dependency"""
def test_get_current_superuser(self, mock_user):
"""Test getting a superuser"""
# Make user a superuser
mock_user.is_superuser = True
# Call the dependency with mocked current_user
user = get_current_superuser(current_user=mock_user)
# Should return the same user
assert user == mock_user
def test_get_current_non_superuser(self, mock_user):
"""Test getting a non-superuser"""
# Ensure user is not a superuser
mock_user.is_superuser = False
# Should raise HTTPException with 403 status
with pytest.raises(HTTPException) as exc_info:
get_current_superuser(current_user=mock_user)
assert exc_info.value.status_code == 403
assert "Not enough permissions" in exc_info.value.detail
class TestGetOptionalCurrentUser:
"""Tests for get_optional_current_user dependency"""
def test_get_optional_current_user_with_token(self, db_session, mock_user, mock_token):
"""Test getting optional user with a valid token"""
# Mock get_token_data
with patch('app.api.dependencies.auth.get_token_data') as mock_get_data:
mock_get_data.return_value.user_id = mock_user.id
# Call the dependency
user = get_optional_current_user(db=db_session, token=mock_token)
# Should return the correct user
assert user is not None
assert user.id == mock_user.id
def test_get_optional_current_user_no_token(self, db_session):
"""Test getting optional user with no token"""
# Call the dependency with no token
user = get_optional_current_user(db=db_session, token=None)
# Should return None
assert user is None
def test_get_optional_current_user_invalid_token(self, db_session, mock_token):
"""Test getting optional user with an invalid token"""
# Mock get_token_data to raise TokenInvalidError
with patch('app.api.dependencies.auth.get_token_data') as mock_get_data:
mock_get_data.side_effect = TokenInvalidError("Invalid token")
# Call the dependency
user = get_optional_current_user(db=db_session, token=mock_token)
# Should return None, not raise an exception
assert user is None
def test_get_optional_current_user_expired_token(self, db_session, mock_token):
"""Test getting optional user with an expired token"""
# Mock get_token_data to raise TokenExpiredError
with patch('app.api.dependencies.auth.get_token_data') as mock_get_data:
mock_get_data.side_effect = TokenExpiredError("Token expired")
# Call the dependency
user = get_optional_current_user(db=db_session, token=mock_token)
# Should return None, not raise an exception
assert user is None
def test_get_optional_current_user_inactive(self, db_session, mock_user, mock_token):
"""Test getting optional user when user is inactive"""
# Make the user inactive
mock_user.is_active = False
db_session.commit()
# Mock get_token_data
with patch('app.api.dependencies.auth.get_token_data') as mock_get_data:
mock_get_data.return_value.user_id = mock_user.id
# Call the dependency
user = get_optional_current_user(db=db_session, token=mock_token)
# Should return None for inactive users
assert user is None