audio-processor / test_api_dependencies.py
vitek
add bearer token to endpoints
acb0ec6
raw
history blame
5.44 kB
"""Unit tests for API dependencies."""
import pytest
import base64
import json
from unittest.mock import patch
from fastapi import HTTPException
class TestValidateBearerToken:
"""Test cases for bearer token validation dependency."""
def setup_method(self):
"""Set up test fixtures."""
# Create a valid JWT token for testing
header = {"alg": "HS256", "typ": "JWT"}
payload = {"sub": "1234567890", "name": "John Doe", "iat": 1516239022}
header_b64 = base64.urlsafe_b64encode(
json.dumps(header).encode()
).decode().rstrip('=')
payload_b64 = base64.urlsafe_b64encode(
json.dumps(payload).encode()
).decode().rstrip('=')
self.valid_token = f"{header_b64}.{payload_b64}.test_signature"
self.valid_auth_header = f"Bearer {self.valid_token}"
@pytest.mark.asyncio
async def test_validate_bearer_token_success(self):
"""Test successful bearer token validation."""
# Import here to avoid module loading issues during collection
from interfaces.api.dependencies import validate_bearer_token
result = await validate_bearer_token(self.valid_auth_header)
assert result == self.valid_token
@pytest.mark.asyncio
async def test_validate_bearer_token_missing_header(self):
"""Test validation fails when Authorization header is missing."""
from interfaces.api.dependencies import validate_bearer_token
with pytest.raises(HTTPException) as exc_info:
await validate_bearer_token(None)
assert exc_info.value.status_code == 401
assert "Missing Authorization header" in exc_info.value.detail
assert exc_info.value.headers["WWW-Authenticate"] == "Bearer"
@pytest.mark.asyncio
async def test_validate_bearer_token_invalid_format(self):
"""Test validation fails for invalid Authorization header format."""
from interfaces.api.dependencies import validate_bearer_token
with pytest.raises(HTTPException) as exc_info:
await validate_bearer_token("Basic dXNlcjpwYXNz") # Basic auth instead of Bearer
assert exc_info.value.status_code == 401
assert "Invalid Authorization header format" in exc_info.value.detail
assert exc_info.value.headers["WWW-Authenticate"] == "Bearer"
@pytest.mark.asyncio
async def test_validate_bearer_token_missing_bearer_prefix(self):
"""Test validation fails when Bearer prefix is missing."""
from interfaces.api.dependencies import validate_bearer_token
with pytest.raises(HTTPException) as exc_info:
await validate_bearer_token(self.valid_token) # Token without "Bearer " prefix
assert exc_info.value.status_code == 401
assert "Invalid Authorization header format" in exc_info.value.detail
@pytest.mark.asyncio
async def test_validate_bearer_token_empty_token(self):
"""Test validation fails for empty token after Bearer prefix."""
from interfaces.api.dependencies import validate_bearer_token
with pytest.raises(HTTPException) as exc_info:
await validate_bearer_token("Bearer ") # Bearer with no token
assert exc_info.value.status_code == 401
assert "Empty bearer token" in exc_info.value.detail
@pytest.mark.asyncio
async def test_validate_bearer_token_invalid_jwt_structure(self):
"""Test validation fails for invalid JWT token structure."""
from interfaces.api.dependencies import validate_bearer_token
with pytest.raises(HTTPException) as exc_info:
await validate_bearer_token("Bearer invalid.token") # Invalid JWT structure
assert exc_info.value.status_code == 401
assert "Invalid JWT token structure" in exc_info.value.detail
@pytest.mark.asyncio
async def test_validate_bearer_token_malformed_jwt(self):
"""Test validation fails for malformed JWT."""
from interfaces.api.dependencies import validate_bearer_token
with pytest.raises(HTTPException) as exc_info:
await validate_bearer_token("Bearer not_a_jwt_at_all")
assert exc_info.value.status_code == 401
assert "Invalid JWT token structure" in exc_info.value.detail
@pytest.mark.asyncio
async def test_validate_bearer_token_case_sensitive(self):
"""Test that Bearer prefix is case sensitive."""
with pytest.raises(HTTPException) as exc_info:
await validate_bearer_token(f"bearer {self.valid_token}") # lowercase 'bearer'
assert exc_info.value.status_code == 401
assert "Invalid Authorization header format" in exc_info.value.detail
@pytest.mark.asyncio
async def test_validate_bearer_token_extra_spaces(self):
"""Test handling of extra spaces in Authorization header."""
# Should work with proper spacing
result = await validate_bearer_token(f"Bearer {self.valid_token}")
assert result == self.valid_token
# Should fail with extra spaces
with pytest.raises(HTTPException) as exc_info:
await validate_bearer_token(f"Bearer {self.valid_token}") # Extra space
assert exc_info.value.status_code == 401