audio-processor / test_api_dependencies.py
tedowski's picture
n8n-improvements (#1)
dbe78dd verified
"""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