Add test files: server, fuzzer, validator tests
Some checks failed
CI / test (push) Failing after 13s
Some checks failed
CI / test (push) Failing after 13s
This commit is contained in:
152
tests/test_validator.py
Normal file
152
tests/test_validator.py
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
"""Tests for Request Validator."""
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from src.core.validator import RequestValidator, ValidationFailure
|
||||||
|
|
||||||
|
|
||||||
|
class TestRequestValidator:
|
||||||
|
"""Tests for RequestValidator class."""
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def spec(self, sample_openapi_yaml):
|
||||||
|
"""Create a parser and return the spec."""
|
||||||
|
import yaml
|
||||||
|
return yaml.safe_load(sample_openapi_yaml)
|
||||||
|
|
||||||
|
def test_validate_headers_success(self, spec):
|
||||||
|
"""Test successful header validation."""
|
||||||
|
validator = RequestValidator(spec)
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"content-type": "application/json",
|
||||||
|
"accept": "application/json"
|
||||||
|
}
|
||||||
|
|
||||||
|
result = validator.validate_headers(headers)
|
||||||
|
assert result is None
|
||||||
|
|
||||||
|
def test_validate_query_params_success(self, spec):
|
||||||
|
"""Test successful query parameter validation."""
|
||||||
|
validator = RequestValidator(spec)
|
||||||
|
|
||||||
|
params = {"page": "1", "limit": "10"}
|
||||||
|
|
||||||
|
param_schemas = {
|
||||||
|
"page": {"type": "string"},
|
||||||
|
"limit": {"type": "string"}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = validator.validate_query_params(params, param_schemas)
|
||||||
|
assert result is None
|
||||||
|
|
||||||
|
def test_validate_path_params_success(self, spec):
|
||||||
|
"""Test successful path parameter validation."""
|
||||||
|
validator = RequestValidator(spec)
|
||||||
|
|
||||||
|
params = {"userId": "123"}
|
||||||
|
|
||||||
|
param_schemas = {
|
||||||
|
"userId": {"type": "integer"}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = validator.validate_path_params(params, param_schemas)
|
||||||
|
assert result is None
|
||||||
|
|
||||||
|
def test_validate_path_params_missing(self, spec):
|
||||||
|
"""Test path parameter validation with missing param."""
|
||||||
|
validator = RequestValidator(spec)
|
||||||
|
|
||||||
|
params = {}
|
||||||
|
|
||||||
|
param_schemas = {
|
||||||
|
"userId": {"type": "integer"}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = validator.validate_path_params(params, param_schemas)
|
||||||
|
|
||||||
|
assert result is not None
|
||||||
|
assert isinstance(result, ValidationFailure)
|
||||||
|
|
||||||
|
def test_validate_body_success(self, spec):
|
||||||
|
"""Test successful body validation."""
|
||||||
|
validator = RequestValidator(spec)
|
||||||
|
|
||||||
|
body = {"name": "Test User", "email": "test@example.com"}
|
||||||
|
schema = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {"type": "string"},
|
||||||
|
"email": {"type": "string", "format": "email"}
|
||||||
|
},
|
||||||
|
"required": ["name"]
|
||||||
|
}
|
||||||
|
|
||||||
|
result = validator.validate_body(body, schema)
|
||||||
|
assert result is None
|
||||||
|
|
||||||
|
def test_validate_body_missing_required(self, spec):
|
||||||
|
"""Test body validation with missing required field."""
|
||||||
|
validator = RequestValidator(spec)
|
||||||
|
|
||||||
|
body = {"email": "test@example.com"}
|
||||||
|
schema = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {"type": "string"},
|
||||||
|
"email": {"type": "string"}
|
||||||
|
},
|
||||||
|
"required": ["name"]
|
||||||
|
}
|
||||||
|
|
||||||
|
result = validator.validate_body(body, schema)
|
||||||
|
|
||||||
|
assert result is not None
|
||||||
|
assert isinstance(result, ValidationFailure)
|
||||||
|
|
||||||
|
def test_validate_body_no_schema(self, spec):
|
||||||
|
"""Test body validation with no schema."""
|
||||||
|
validator = RequestValidator(spec)
|
||||||
|
|
||||||
|
body = {"any": "data"}
|
||||||
|
|
||||||
|
result = validator.validate_body(body, None)
|
||||||
|
assert result is None
|
||||||
|
|
||||||
|
def test_validate_body_empty(self, spec):
|
||||||
|
"""Test body validation with empty body."""
|
||||||
|
validator = RequestValidator(spec)
|
||||||
|
|
||||||
|
result = validator.validate_body(None, None)
|
||||||
|
assert result is None
|
||||||
|
|
||||||
|
def test_format_validation_errors(self, spec):
|
||||||
|
"""Test formatting validation errors."""
|
||||||
|
from jsonschema import ValidationError
|
||||||
|
|
||||||
|
validator = RequestValidator(spec)
|
||||||
|
|
||||||
|
errors = [
|
||||||
|
ValidationError("Field is required", path=["name"]),
|
||||||
|
ValidationError("Invalid email format", path=["email"])
|
||||||
|
]
|
||||||
|
|
||||||
|
formatted = validator.format_validation_errors(errors)
|
||||||
|
|
||||||
|
assert len(formatted) == 2
|
||||||
|
assert formatted[0]["message"] == "Field is required"
|
||||||
|
assert formatted[1]["message"] == "Invalid email format"
|
||||||
|
|
||||||
|
def test_create_error_response(self, spec):
|
||||||
|
"""Test creating error response from validation failure."""
|
||||||
|
from jsonschema import ValidationError
|
||||||
|
|
||||||
|
validator = RequestValidator(spec)
|
||||||
|
|
||||||
|
errors = [ValidationError("Test error")]
|
||||||
|
failure = ValidationFailure("Validation failed", errors)
|
||||||
|
|
||||||
|
response = validator.create_error_response(failure)
|
||||||
|
|
||||||
|
assert response["status_code"] == 400
|
||||||
|
assert response["body"]["error"]["type"] == "Validation Error"
|
||||||
|
assert "details" in response["body"]["error"]
|
||||||
Reference in New Issue
Block a user