mirror of
https://github.com/correl/openapi-core.git
synced 2024-12-28 19:19:23 +00:00
Parameters on path item object support
This commit is contained in:
parent
40944119d1
commit
27ebae3182
6 changed files with 74 additions and 7 deletions
15
openapi_core/schema/paths/exceptions.py
Normal file
15
openapi_core/schema/paths/exceptions.py
Normal file
|
@ -0,0 +1,15 @@
|
|||
import attr
|
||||
|
||||
from openapi_core.schema.exceptions import OpenAPIMappingError
|
||||
|
||||
|
||||
class OpenAPIPathError(OpenAPIMappingError):
|
||||
pass
|
||||
|
||||
|
||||
@attr.s(hash=True)
|
||||
class InvalidPath(OpenAPIPathError):
|
||||
path_pattern = attr.ib()
|
||||
|
||||
def __str__(self):
|
||||
return "Unknown path {0}".format(self.path_pattern)
|
|
@ -4,6 +4,7 @@ import logging
|
|||
|
||||
from openapi_core.compat import partialmethod
|
||||
from openapi_core.schema.operations.exceptions import InvalidOperation
|
||||
from openapi_core.schema.paths.exceptions import InvalidPath
|
||||
from openapi_core.schema.servers.exceptions import InvalidServer
|
||||
|
||||
|
||||
|
@ -19,8 +20,8 @@ class Spec(object):
|
|||
self.servers = servers or []
|
||||
self.components = components
|
||||
|
||||
def __getitem__(self, path_name):
|
||||
return self.paths[path_name]
|
||||
def __getitem__(self, path_pattern):
|
||||
return self.get_path(path_pattern)
|
||||
|
||||
@property
|
||||
def default_url(self):
|
||||
|
@ -36,6 +37,12 @@ class Spec(object):
|
|||
def get_server_url(self, index=0):
|
||||
return self.servers[index].default_url
|
||||
|
||||
def get_path(self, path_pattern):
|
||||
try:
|
||||
return self.paths[path_pattern]
|
||||
except KeyError:
|
||||
raise InvalidPath(path_pattern)
|
||||
|
||||
def get_operation(self, path_pattern, http_method):
|
||||
try:
|
||||
return self.paths[path_pattern].operations[http_method]
|
||||
|
|
|
@ -16,6 +16,16 @@ class RequestParameters(dict):
|
|||
def __setitem__(self, location, value):
|
||||
raise NotImplementedError
|
||||
|
||||
def __add__(self, other):
|
||||
if not isinstance(other, self.__class__):
|
||||
raise ValueError("Invalid type")
|
||||
|
||||
for location in self.valid_locations:
|
||||
if location in other:
|
||||
self[location].update(other[location])
|
||||
|
||||
return self
|
||||
|
||||
@classmethod
|
||||
def validate_location(cls, location):
|
||||
if location not in cls.valid_locations:
|
||||
|
|
|
@ -26,6 +26,14 @@ class RequestValidator(object):
|
|||
server.default_url, request.full_url_pattern
|
||||
)
|
||||
|
||||
try:
|
||||
path = self.spec[operation_pattern]
|
||||
# don't process if operation errors
|
||||
except OpenAPIMappingError as exc:
|
||||
return RequestValidationResult([exc, ], None, None)
|
||||
|
||||
path_params, path_params_errors = self._get_parameters(request, path)
|
||||
|
||||
try:
|
||||
operation = self.spec.get_operation(
|
||||
operation_pattern, request.method)
|
||||
|
@ -33,11 +41,11 @@ class RequestValidator(object):
|
|||
except OpenAPIMappingError as exc:
|
||||
return RequestValidationResult([exc, ], None, None)
|
||||
|
||||
params, params_errors = self._get_parameters(request, operation)
|
||||
op_params, op_params_errors = self._get_parameters(request, operation)
|
||||
body, body_errors = self._get_body(request, operation)
|
||||
|
||||
errors = params_errors + body_errors
|
||||
return RequestValidationResult(errors, body, params)
|
||||
errors = path_params_errors + op_params_errors + body_errors
|
||||
return RequestValidationResult(errors, body, path_params + op_params)
|
||||
|
||||
def _get_parameters(self, request, operation):
|
||||
errors = []
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import pytest
|
||||
|
||||
from openapi_core.schema.operations.exceptions import InvalidOperation
|
||||
from openapi_core.schema.paths.exceptions import InvalidPath
|
||||
from openapi_core.shortcuts import create_spec
|
||||
from openapi_core.validation.request.validators import RequestValidator
|
||||
from openapi_core.wrappers.mock import MockRequest
|
||||
|
@ -39,7 +40,7 @@ class TestMinimal(object):
|
|||
spec_dict = factory.spec_from_file(spec_path)
|
||||
spec = create_spec(spec_dict)
|
||||
validator = RequestValidator(spec)
|
||||
request = MockRequest(server, "get", "/nonexistent")
|
||||
request = MockRequest(server, "post", "/status")
|
||||
|
||||
result = validator.validate(request)
|
||||
|
||||
|
@ -47,3 +48,18 @@ class TestMinimal(object):
|
|||
assert isinstance(result.errors[0], InvalidOperation)
|
||||
assert result.body is None
|
||||
assert result.parameters == {}
|
||||
|
||||
@pytest.mark.parametrize("server", servers)
|
||||
@pytest.mark.parametrize("spec_path", spec_paths)
|
||||
def test_invalid_path(self, factory, server, spec_path):
|
||||
spec_dict = factory.spec_from_file(spec_path)
|
||||
spec = create_spec(spec_dict)
|
||||
validator = RequestValidator(spec)
|
||||
request = MockRequest(server, "get", "/nonexistent")
|
||||
|
||||
result = validator.validate(request)
|
||||
|
||||
assert len(result.errors) == 1
|
||||
assert isinstance(result.errors[0], InvalidPath)
|
||||
assert result.body is None
|
||||
assert result.parameters == {}
|
||||
|
|
|
@ -10,6 +10,7 @@ from openapi_core.extensions.models.models import BaseModel
|
|||
from openapi_core.schema.operations.exceptions import InvalidOperation
|
||||
from openapi_core.schema.parameters.exceptions import MissingRequiredParameter
|
||||
from openapi_core.schema.parameters.exceptions import InvalidParameterValue
|
||||
from openapi_core.schema.paths.exceptions import InvalidPath
|
||||
from openapi_core.schema.request_bodies.exceptions import MissingRequestBody
|
||||
from openapi_core.schema.responses.exceptions import (
|
||||
MissingResponseContent, InvalidResponse,
|
||||
|
@ -55,11 +56,21 @@ class TestRequestValidator(object):
|
|||
assert result.body is None
|
||||
assert result.parameters == {}
|
||||
|
||||
def test_invalid_operation(self, validator):
|
||||
def test_invalid_path(self, validator):
|
||||
request = MockRequest(self.host_url, 'get', '/v1')
|
||||
|
||||
result = validator.validate(request)
|
||||
|
||||
assert len(result.errors) == 1
|
||||
assert type(result.errors[0]) == InvalidPath
|
||||
assert result.body is None
|
||||
assert result.parameters == {}
|
||||
|
||||
def test_invalid_operation(self, validator):
|
||||
request = MockRequest(self.host_url, 'patch', '/v1/pets')
|
||||
|
||||
result = validator.validate(request)
|
||||
|
||||
assert len(result.errors) == 1
|
||||
assert type(result.errors[0]) == InvalidOperation
|
||||
assert result.body is None
|
||||
|
|
Loading…
Reference in a new issue