Updated `decode_token` for stricter validation of token claims and explicit error handling. Added utilities for token revocation and verification, improving
86 lines
2.5 KiB
Python
86 lines
2.5 KiB
Python
from datetime import datetime, timezone
|
|
from unittest.mock import AsyncMock
|
|
|
|
import pytest
|
|
from fastapi import HTTPException
|
|
from jose import jwt
|
|
|
|
from app.auth.dependencies import get_current_user, get_current_active_user
|
|
from app.auth.security import SECRET_KEY, ALGORITHM
|
|
from app.models.user import User
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_user():
|
|
return User(
|
|
id="123e4567-e89b-12d3-a456-426614174000",
|
|
email="test@example.com",
|
|
password_hash="hashedpassword",
|
|
is_active=True
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_current_user_success(mock_user):
|
|
# Create a valid access token with required claims
|
|
valid_token = jwt.encode(
|
|
{"sub": str(mock_user.id), "type": "access", "exp": datetime.now(tz=timezone.utc).timestamp() + 3600},
|
|
SECRET_KEY,
|
|
algorithm=ALGORITHM
|
|
)
|
|
|
|
# Mock database session
|
|
mock_db = AsyncMock()
|
|
mock_db.get.return_value = mock_user # Ensure `db.get()` returns the mock_user
|
|
|
|
# Call the dependency
|
|
user = await get_current_user(token=valid_token, db=mock_db)
|
|
|
|
# Assertions
|
|
assert user == mock_user, "Returned user does not match the mocked user."
|
|
mock_db.get.assert_called_once_with(User, mock_user.id)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_current_user_invalid_token():
|
|
invalid_token = "invalid.token.payload"
|
|
|
|
with pytest.raises(HTTPException) as exc_info:
|
|
await get_current_user(token=invalid_token, db=AsyncMock())
|
|
|
|
assert exc_info.value.status_code == 401
|
|
assert exc_info.value.detail == "Could not validate credentials"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_current_user_wrong_token_type():
|
|
token = jwt.encode({"sub": "123", "type": "refresh"}, SECRET_KEY, algorithm=ALGORITHM)
|
|
|
|
with pytest.raises(HTTPException) as exc_info:
|
|
await get_current_user(token=token, db=AsyncMock())
|
|
|
|
assert exc_info.value.status_code == 401
|
|
assert exc_info.value.detail == "Could not validate credentials"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_current_active_user_success(mock_user):
|
|
result = await get_current_active_user(mock_user)
|
|
assert result == mock_user
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_current_active_user_inactive():
|
|
inactive_user = User(
|
|
id="123e4567-e89b-12d3-a456-426614174000",
|
|
email="inactive@example.com",
|
|
password_hash="hashedpassword",
|
|
is_active=False
|
|
)
|
|
|
|
with pytest.raises(HTTPException) as exc_info:
|
|
await get_current_active_user(inactive_user)
|
|
|
|
assert exc_info.value.status_code == 400
|
|
assert exc_info.value.detail == "Inactive user"
|