83 lines
3.2 KiB
Python
83 lines
3.2 KiB
Python
"""Tests for token utilities."""
|
|
|
|
from datetime import UTC, datetime, timedelta
|
|
from zoneinfo import ZoneInfo
|
|
|
|
from app.utils.auth import TokenUtils
|
|
|
|
TOKEN_LENGTH = 43 # Length of URL-safe base64 encoded 32-byte token
|
|
UNIQUE_TOKENS_COUNT = 10 # Number of unique tokens to generate for uniqueness test
|
|
|
|
|
|
class TestTokenUtils:
|
|
"""Test token utility functions."""
|
|
|
|
def test_generate_api_token(self) -> None:
|
|
"""Test API token generation."""
|
|
token = TokenUtils.generate_api_token()
|
|
|
|
# Should be a string
|
|
assert isinstance(token, str)
|
|
|
|
# Should not be empty
|
|
assert len(token) > 0
|
|
|
|
# Should be URL-safe base64 (43 characters for 32 bytes)
|
|
assert len(token) == TOKEN_LENGTH
|
|
|
|
# Should be unique (generate multiple and check they're different)
|
|
tokens = [TokenUtils.generate_api_token() for _ in range(UNIQUE_TOKENS_COUNT)]
|
|
assert len(set(tokens)) == UNIQUE_TOKENS_COUNT
|
|
|
|
def test_is_token_expired_none(self) -> None:
|
|
"""Test token expiration check with None expires_at."""
|
|
result = TokenUtils.is_token_expired(None)
|
|
assert result is False
|
|
|
|
def test_is_token_expired_future_naive(self) -> None:
|
|
"""Test token expiration check with future naive datetime."""
|
|
# Use UTC time for naive datetime (as the function assumes)
|
|
expires_at = datetime.now(UTC) + timedelta(hours=1)
|
|
result = TokenUtils.is_token_expired(expires_at)
|
|
assert result is False
|
|
|
|
def test_is_token_expired_past_naive(self) -> None:
|
|
"""Test token expiration check with past naive datetime."""
|
|
# Use UTC time for naive datetime (as the function assumes)
|
|
expires_at = datetime.now(UTC) - timedelta(hours=1)
|
|
result = TokenUtils.is_token_expired(expires_at)
|
|
assert result is True
|
|
|
|
def test_is_token_expired_future_aware(self) -> None:
|
|
"""Test token expiration check with future timezone-aware datetime."""
|
|
expires_at = datetime.now(UTC) + timedelta(hours=1)
|
|
result = TokenUtils.is_token_expired(expires_at)
|
|
assert result is False
|
|
|
|
def test_is_token_expired_past_aware(self) -> None:
|
|
"""Test token expiration check with past timezone-aware datetime."""
|
|
expires_at = datetime.now(UTC) - timedelta(hours=1)
|
|
result = TokenUtils.is_token_expired(expires_at)
|
|
assert result is True
|
|
|
|
def test_is_token_expired_edge_case_now(self) -> None:
|
|
"""Test token expiration check with time very close to now."""
|
|
# Token expires in 1 second
|
|
expires_at = datetime.now(UTC) + timedelta(seconds=1)
|
|
result = TokenUtils.is_token_expired(expires_at)
|
|
assert result is False
|
|
|
|
# Token expired 1 second ago
|
|
expires_at = datetime.now(UTC) - timedelta(seconds=1)
|
|
result = TokenUtils.is_token_expired(expires_at)
|
|
assert result is True
|
|
|
|
def test_is_token_expired_timezone_conversion(self) -> None:
|
|
"""Test token expiration check with different timezone."""
|
|
# Create a datetime in a different timezone
|
|
eastern = ZoneInfo("US/Eastern")
|
|
expires_at = datetime.now(eastern) + timedelta(hours=1)
|
|
|
|
result = TokenUtils.is_token_expired(expires_at)
|
|
assert result is False
|