Spaces:
Sleeping
Sleeping
| """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}" | |
| 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 | |
| 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" | |
| 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" | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 |