audio-processor / test_jwt_validation_service.py
tedowski's picture
n8n-improvements (#1)
dbe78dd verified
raw
history blame
6.43 kB
"""Unit tests for JWT validation service."""
import pytest
import base64
import json
from infrastructure.services.jwt_validation_service import JWTValidationService
class TestJWTValidationService:
"""Test cases for JWT validation service."""
def setup_method(self):
"""Set up test fixtures."""
self.jwt_service = JWTValidationService()
# Create a valid JWT token for testing
self.valid_header = {"alg": "HS256", "typ": "JWT"}
self.valid_payload = {"sub": "1234567890", "name": "John Doe", "iat": 1516239022}
self.valid_signature = "test_signature"
# Encode the parts
header_b64 = base64.urlsafe_b64encode(
json.dumps(self.valid_header).encode()
).decode().rstrip('=')
payload_b64 = base64.urlsafe_b64encode(
json.dumps(self.valid_payload).encode()
).decode().rstrip('=')
self.valid_token = f"{header_b64}.{payload_b64}.{self.valid_signature}"
def test_validate_structure_valid_token(self):
"""Test validation of a valid JWT token structure."""
assert self.jwt_service.validate_structure(self.valid_token) is True
def test_validate_structure_empty_token(self):
"""Test validation fails for empty token."""
assert self.jwt_service.validate_structure("") is False
assert self.jwt_service.validate_structure(None) is False
def test_validate_structure_invalid_type(self):
"""Test validation fails for non-string token."""
assert self.jwt_service.validate_structure(123) is False
assert self.jwt_service.validate_structure([]) is False
def test_validate_structure_wrong_part_count(self):
"""Test validation fails for wrong number of parts."""
assert self.jwt_service.validate_structure("only.one.part") is False
assert self.jwt_service.validate_structure("too.many.parts.here") is False
assert self.jwt_service.validate_structure("single_part") is False
def test_validate_structure_empty_signature(self):
"""Test validation fails for empty signature."""
header_b64 = base64.urlsafe_b64encode(
json.dumps(self.valid_header).encode()
).decode().rstrip('=')
payload_b64 = base64.urlsafe_b64encode(
json.dumps(self.valid_payload).encode()
).decode().rstrip('=')
invalid_token = f"{header_b64}.{payload_b64}."
assert self.jwt_service.validate_structure(invalid_token) is False
def test_validate_structure_invalid_base64_header(self):
"""Test validation fails for invalid base64 in header."""
invalid_token = "invalid_base64.valid_payload.signature"
assert self.jwt_service.validate_structure(invalid_token) is False
def test_validate_structure_invalid_json_header(self):
"""Test validation fails for invalid JSON in header."""
invalid_header = base64.urlsafe_b64encode(b"not_json").decode()
payload_b64 = base64.urlsafe_b64encode(
json.dumps(self.valid_payload).encode()
).decode().rstrip('=')
invalid_token = f"{invalid_header}.{payload_b64}.signature"
assert self.jwt_service.validate_structure(invalid_token) is False
def test_validate_structure_invalid_json_payload(self):
"""Test validation fails for invalid JSON in payload."""
header_b64 = base64.urlsafe_b64encode(
json.dumps(self.valid_header).encode()
).decode().rstrip('=')
invalid_payload = base64.urlsafe_b64encode(b"not_json").decode()
invalid_token = f"{header_b64}.{invalid_payload}.signature"
assert self.jwt_service.validate_structure(invalid_token) is False
def test_validate_jwt_part_valid_part(self):
"""Test validation of valid JWT part."""
header_b64 = base64.urlsafe_b64encode(
json.dumps(self.valid_header).encode()
).decode().rstrip('=')
result = self.jwt_service._validate_jwt_part(header_b64, "header")
assert result == self.valid_header
def test_validate_jwt_part_empty_part(self):
"""Test validation fails for empty part."""
with pytest.raises(ValueError, match="Empty JWT header"):
self.jwt_service._validate_jwt_part("", "header")
def test_validate_jwt_part_invalid_base64(self):
"""Test validation fails for invalid base64."""
with pytest.raises(ValueError, match="Invalid JWT header"):
self.jwt_service._validate_jwt_part("invalid_base64", "header")
def test_validate_jwt_part_non_object_json(self):
"""Test validation fails for non-object JSON."""
# JSON array instead of object
json_array = json.dumps(["not", "an", "object"])
array_b64 = base64.urlsafe_b64encode(json_array.encode()).decode()
with pytest.raises(ValueError, match="JWT header is not a JSON object"):
self.jwt_service._validate_jwt_part(array_b64, "header")
def test_extract_claims_valid_token(self):
"""Test extracting claims from valid token."""
claims = self.jwt_service.extract_claims(self.valid_token)
assert claims == self.valid_payload
def test_extract_claims_invalid_token(self):
"""Test extracting claims from invalid token."""
claims = self.jwt_service.extract_claims("invalid.token")
assert claims is None
def test_extract_claims_empty_token(self):
"""Test extracting claims from empty token."""
claims = self.jwt_service.extract_claims("")
assert claims is None
def test_jwt_with_padding(self):
"""Test JWT validation with base64 padding."""
# Create JWT parts that need padding
header = {"alg": "HS256", "typ": "JWT"}
payload = {"sub": "test"} # Shorter payload
header_b64 = base64.urlsafe_b64encode(
json.dumps(header).encode()
).decode().rstrip('=')
payload_b64 = base64.urlsafe_b64encode(
json.dumps(payload).encode()
).decode().rstrip('=')
token = f"{header_b64}.{payload_b64}.signature"
assert self.jwt_service.validate_structure(token) is True
claims = self.jwt_service.extract_claims(token)
assert claims == payload