Some checks failed
Cross-Node Transaction Testing / transaction-test (push) Has been cancelled
Deploy to Testnet / deploy-testnet (push) Has been cancelled
Documentation Validation / validate-docs (push) Has been cancelled
Documentation Validation / validate-policies-strict (push) Has been cancelled
Integration Tests / test-service-integration (push) Has been cancelled
Multi-Node Stress Testing / stress-test (push) Has been cancelled
Python Tests / test-python (push) Has been cancelled
Security Scanning / security-scan (push) Has been cancelled
- Added logger initialization to EventRouter in events.py - Fixed datetime.timedelta references to use timedelta directly in security_hardening.py - Fixed StateTransition timestamp default_factory to use lambda in state.py - Fixed StateValidator.validate_transitions to only check source states exist - Moved cross_chain_bridge_enhanced.py to cross_chain/bridge_enhanced.py - Updated import paths in global_marketplace
181 lines
6.3 KiB
Python
181 lines
6.3 KiB
Python
"""
|
|
Tests for request validation middleware
|
|
"""
|
|
|
|
import pytest
|
|
from unittest.mock import Mock, patch, AsyncMock
|
|
from fastapi import Request, HTTPException
|
|
from starlette.responses import Response
|
|
|
|
from aitbc.middleware.validation import RequestValidationMiddleware
|
|
|
|
|
|
class TestRequestValidationMiddleware:
|
|
"""Tests for RequestValidationMiddleware"""
|
|
|
|
@patch('aitbc.middleware.validation.logger')
|
|
def test_initialization(self, mock_logger):
|
|
"""Test middleware initialization"""
|
|
app = Mock()
|
|
middleware = RequestValidationMiddleware(app)
|
|
|
|
assert middleware.max_request_size == 10 * 1024 * 1024
|
|
assert middleware.max_response_size == 10 * 1024 * 1024
|
|
|
|
@patch('aitbc.middleware.validation.logger')
|
|
def test_initialization_custom_sizes(self, mock_logger):
|
|
"""Test middleware with custom sizes"""
|
|
app = Mock()
|
|
middleware = RequestValidationMiddleware(
|
|
app,
|
|
max_request_size=5 * 1024 * 1024,
|
|
max_response_size=5 * 1024 * 1024
|
|
)
|
|
|
|
assert middleware.max_request_size == 5 * 1024 * 1024
|
|
assert middleware.max_response_size == 5 * 1024 * 1024
|
|
|
|
@pytest.mark.asyncio
|
|
@patch('aitbc.middleware.validation.logger')
|
|
async def test_dispatch_valid_request(self, mock_logger):
|
|
"""Test dispatch with valid request size"""
|
|
app = Mock()
|
|
middleware = RequestValidationMiddleware(app, max_request_size=1024)
|
|
|
|
request = Mock(spec=Request)
|
|
request.headers = {"content-length": "512"}
|
|
request.client = Mock(host="127.0.0.1")
|
|
request.url = Mock(path="/test")
|
|
|
|
call_next = AsyncMock()
|
|
response = Mock(spec=Response)
|
|
response.body = b"test response"
|
|
call_next.return_value = response
|
|
|
|
result = await middleware.dispatch(request, call_next)
|
|
|
|
assert result == response
|
|
call_next.assert_called_once_with(request)
|
|
|
|
@pytest.mark.asyncio
|
|
@patch('aitbc.middleware.validation.logger')
|
|
async def test_dispatch_request_too_large(self, mock_logger):
|
|
"""Test dispatch with request too large"""
|
|
app = Mock()
|
|
middleware = RequestValidationMiddleware(app, max_request_size=1024)
|
|
|
|
request = Mock(spec=Request)
|
|
request.headers = {"content-length": "2048"}
|
|
request.client = Mock(host="127.0.0.1")
|
|
|
|
call_next = AsyncMock()
|
|
|
|
with pytest.raises(HTTPException) as exc_info:
|
|
await middleware.dispatch(request, call_next)
|
|
|
|
assert exc_info.value.status_code == 413
|
|
assert "Request too large" in exc_info.value.detail
|
|
mock_logger.warning.assert_called_once()
|
|
|
|
@pytest.mark.asyncio
|
|
@patch('aitbc.middleware.validation.logger')
|
|
async def test_dispatch_invalid_content_length(self, mock_logger):
|
|
"""Test dispatch with invalid content-length header"""
|
|
app = Mock()
|
|
middleware = RequestValidationMiddleware(app, max_request_size=1024)
|
|
|
|
request = Mock(spec=Request)
|
|
request.headers = {"content-length": "invalid"}
|
|
|
|
call_next = AsyncMock()
|
|
response = Mock(spec=Response)
|
|
response.body = b"test"
|
|
call_next.return_value = response
|
|
|
|
result = await middleware.dispatch(request, call_next)
|
|
|
|
assert result == response
|
|
mock_logger.warning.assert_called_once()
|
|
|
|
@pytest.mark.asyncio
|
|
@patch('aitbc.middleware.validation.logger')
|
|
async def test_dispatch_no_content_length(self, mock_logger):
|
|
"""Test dispatch without content-length header"""
|
|
app = Mock()
|
|
middleware = RequestValidationMiddleware(app, max_request_size=1024)
|
|
|
|
request = Mock(spec=Request)
|
|
request.headers = {}
|
|
|
|
call_next = AsyncMock()
|
|
response = Mock(spec=Response)
|
|
response.body = b"test"
|
|
call_next.return_value = response
|
|
|
|
result = await middleware.dispatch(request, call_next)
|
|
|
|
assert result == response
|
|
|
|
@pytest.mark.asyncio
|
|
@patch('aitbc.middleware.validation.logger')
|
|
async def test_dispatch_response_too_large(self, mock_logger):
|
|
"""Test dispatch with response too large"""
|
|
app = Mock()
|
|
middleware = RequestValidationMiddleware(app, max_response_size=100)
|
|
|
|
request = Mock(spec=Request)
|
|
request.headers = {}
|
|
request.url = Mock(path="/test")
|
|
|
|
call_next = AsyncMock()
|
|
response = Mock(spec=Response)
|
|
response.body = b"x" * 200 # 200 bytes, exceeds max_response_size
|
|
call_next.return_value = response
|
|
|
|
with pytest.raises(HTTPException) as exc_info:
|
|
await middleware.dispatch(request, call_next)
|
|
|
|
assert exc_info.value.status_code == 500
|
|
assert "Response too large" in exc_info.value.detail
|
|
mock_logger.warning.assert_called_once()
|
|
|
|
@pytest.mark.asyncio
|
|
@patch('aitbc.middleware.validation.logger')
|
|
async def test_dispatch_response_no_body(self, mock_logger):
|
|
"""Test dispatch with response without body attribute"""
|
|
app = Mock()
|
|
middleware = RequestValidationMiddleware(app, max_response_size=100)
|
|
|
|
request = Mock(spec=Request)
|
|
request.headers = {}
|
|
|
|
call_next = AsyncMock()
|
|
response = Mock(spec=Response)
|
|
# Response doesn't have body attribute (streaming response)
|
|
delattr(response, 'body')
|
|
call_next.return_value = response
|
|
|
|
result = await middleware.dispatch(request, call_next)
|
|
|
|
assert result == response
|
|
|
|
@pytest.mark.asyncio
|
|
@patch('aitbc.middleware.validation.logger')
|
|
async def test_dispatch_response_within_limit(self, mock_logger):
|
|
"""Test dispatch with response within size limit"""
|
|
app = Mock()
|
|
middleware = RequestValidationMiddleware(app, max_response_size=1024)
|
|
|
|
request = Mock(spec=Request)
|
|
request.headers = {}
|
|
request.url = Mock(path="/test")
|
|
|
|
call_next = AsyncMock()
|
|
response = Mock(spec=Request)
|
|
response.body = b"x" * 512 # 512 bytes, within limit
|
|
call_next.return_value = response
|
|
|
|
result = await middleware.dispatch(request, call_next)
|
|
|
|
assert result == response
|