Leave body param validation to external lib

This commit is contained in:
Rafael Caricio
2016-02-22 14:02:35 +01:00
parent b60646e047
commit 2fec6e9259
7 changed files with 93 additions and 127 deletions

View File

@@ -60,7 +60,7 @@ def parameter_to_arg(parameters, function):
"""
body_parameters = [parameter for parameter in parameters if parameter['in'] == 'body'] or [{}]
body_name = body_parameters[0].get('name')
default_body = body_parameters[0].get('default')
default_body = body_parameters[0].get('schema', {}).get('default')
query_types = {parameter['name']: parameter
for parameter in parameters if parameter['in'] == 'query'} # type: dict[str, str]
form_types = {parameter['name']: parameter

View File

@@ -87,7 +87,7 @@ class RequestBodyValidator:
:param has_default: Flag to indicate if default value is present.
"""
self.schema = schema
self.has_default = has_default
self.has_default = schema.get('default', False)
def __call__(self, function):
"""

View File

@@ -15,7 +15,6 @@ from copy import deepcopy
import functools
import logging
import jsonschema
from jsonschema import ValidationError
from .decorators import validation
@@ -169,28 +168,12 @@ class Operation(SecureOperation):
self.endpoint_name = flaskify_endpoint(self.operation_id)
self.__undecorated_function = resolution.function
for param in self.parameters:
if param['in'] == 'body' and 'default' in param:
self.default_body = param
break
else:
self.default_body = None
self.validate_defaults()
def validate_defaults(self):
for param in self.parameters:
try:
if param['in'] == 'body' and 'default' in param:
param = param.copy()
if 'required' in param:
del param['required']
if param['type'] == 'object':
jsonschema.validate(param['default'], self.body_schema,
format_checker=jsonschema.draft4_format_checker)
else:
jsonschema.validate(param['default'], param, format_checker=jsonschema.draft4_format_checker)
elif param['in'] == 'query' and 'default' in param:
if param['in'] == 'query' and 'default' in param:
validation.validate_type(param, param['default'], 'query', param['name'])
except (TypeValidationError, ValidationError):
raise InvalidSpecification('The parameter \'{param_name}\' has a default value which is not of'
@@ -386,7 +369,7 @@ class Operation(SecureOperation):
if self.parameters:
yield ParameterValidator(self.parameters)
if self.body_schema:
yield RequestBodyValidator(self.body_schema, self.default_body is not None)
yield RequestBodyValidator(self.body_schema)
@property
def __response_validation_decorator(self):

View File

@@ -1,26 +1,4 @@
import pathlib
import logging
import json
import pytest
from connexion.app import App
logging.basicConfig(level=logging.DEBUG)
TEST_FOLDER = pathlib.Path(__file__).parent.parent
FIXTURES_FOLDER = TEST_FOLDER / 'fixtures'
@pytest.fixture
def simple_api_spec_dir():
return FIXTURES_FOLDER / 'simple'
@pytest.fixture
def simple_app(simple_api_spec_dir):
app = App(__name__, 5001, simple_api_spec_dir, debug=True)
app.add_api('swagger.yaml', validate_responses=True)
return app
def test_app(simple_app):

82
tests/conftest.py Normal file
View File

@@ -0,0 +1,82 @@
import pathlib
import json
import logging
import pytest
from connexion.app import App
logging.basicConfig(level=logging.DEBUG)
TEST_FOLDER = pathlib.Path(__file__).parent
FIXTURES_FOLDER = TEST_FOLDER / 'fixtures'
SPEC_FOLDER = TEST_FOLDER / "fakeapi"
class FakeResponse:
def __init__(self, status_code, text):
"""
:type status_code: int
:type text: ste
"""
self.status_code = status_code
self.text = text
self.ok = status_code == 200
def json(self):
return json.loads(self.text)
# Helper fixtures functions
# =========================
@pytest.fixture
def oauth_requests(monkeypatch):
def fake_get(url, params=None, timeout=None):
"""
:type url: str
:type params: dict| None
"""
params = params or {}
if url == "https://ouath.example/token_info":
token = params['access_token']
if token == "100":
return FakeResponse(200, '{"uid": "test-user", "scope": ["myscope"]}')
if token == "200":
return FakeResponse(200, '{"uid": "test-user", "scope": ["wrongscope"]}')
if token == "300":
return FakeResponse(404, '')
return url
monkeypatch.setattr('connexion.decorators.security.session.get', fake_get)
@pytest.fixture
def app():
app = App(__name__, 5001, SPEC_FOLDER, debug=True)
app.add_api('api.yaml', validate_responses=True)
return app
@pytest.fixture
def simple_api_spec_dir():
return FIXTURES_FOLDER / 'simple'
@pytest.fixture
def problem_api_spec_dir():
return FIXTURES_FOLDER / 'problem'
@pytest.fixture
def simple_app(simple_api_spec_dir):
app = App(__name__, 5001, simple_api_spec_dir, debug=True)
app.add_api('swagger.yaml', validate_responses=True)
return app
@pytest.fixture
def problem_app(problem_api_spec_dir):
app = App(__name__, 5001, problem_api_spec_dir, debug=True)
app.add_api('swagger.yaml', validate_responses=True)
return app

View File

@@ -1,85 +1,7 @@
import pathlib
import json
import logging
import pytest
from connexion.app import App
logging.basicConfig(level=logging.DEBUG)
TEST_FOLDER = pathlib.Path(__file__).parent
FIXTURES_FOLDER = TEST_FOLDER / 'fixtures'
SPEC_FOLDER = TEST_FOLDER / "fakeapi"
class FakeResponse:
def __init__(self, status_code, text):
"""
:type status_code: int
:type text: ste
"""
self.status_code = status_code
self.text = text
self.ok = status_code == 200
def json(self):
return json.loads(self.text)
# Helper fixtures functions
# =========================
@pytest.fixture
def oauth_requests(monkeypatch):
def fake_get(url, params=None, timeout=None):
"""
:type url: str
:type params: dict| None
"""
params = params or {}
if url == "https://ouath.example/token_info":
token = params['access_token']
if token == "100":
return FakeResponse(200, '{"uid": "test-user", "scope": ["myscope"]}')
if token == "200":
return FakeResponse(200, '{"uid": "test-user", "scope": ["wrongscope"]}')
if token == "300":
return FakeResponse(404, '')
return url
monkeypatch.setattr('connexion.decorators.security.session.get', fake_get)
@pytest.fixture
def app():
app = App(__name__, 5001, SPEC_FOLDER, debug=True)
app.add_api('api.yaml', validate_responses=True)
return app
@pytest.fixture
def simple_api_spec_dir():
return FIXTURES_FOLDER / 'simple'
@pytest.fixture
def problem_api_spec_dir():
return FIXTURES_FOLDER / 'problem'
@pytest.fixture
def simple_app(simple_api_spec_dir):
app = App(__name__, 5001, simple_api_spec_dir, debug=True)
app.add_api('swagger.yaml', validate_responses=True)
return app
@pytest.fixture
def problem_app(problem_api_spec_dir):
app = App(__name__, 5001, problem_api_spec_dir, debug=True)
app.add_api('swagger.yaml', validate_responses=True)
return app
from conftest import TEST_FOLDER, SPEC_FOLDER
# Test Resolvers
@@ -102,7 +24,7 @@ def test_app_with_relative_path(simple_api_spec_dir):
debug=True)
app.add_api('swagger.yaml')
app_client = simple_app.app.test_client()
app_client = app.app.test_client()
get_bye = app_client.get('/v1.0/bye/jsantos') # type: flask.Response
assert get_bye.status_code == 200
assert get_bye.data == b'Goodbye jsantos'
@@ -111,6 +33,7 @@ def test_app_with_relative_path(simple_api_spec_dir):
def test_no_swagger(simple_api_spec_dir):
app = App(__name__, 5001, simple_api_spec_dir, swagger_ui=False, debug=True)
app.add_api('swagger.yaml')
app_client = app.app.test_client()
swagger_ui = app_client.get('/v1.0/ui/') # type: flask.Response
assert swagger_ui.status_code == 404
@@ -488,7 +411,7 @@ def test_schema_map(app):
assert wrong_items_response['detail'].startswith("42 is not of type 'object'")
right_type = app_client.post('/v1.0/test_schema_map', headers=headers,
data=json.dumps(valid_object)) # type: flask.Response
data=json.dumps(valid_object)) # type: flask.Response
assert right_type.status_code == 200
@@ -510,7 +433,8 @@ def test_schema_recursive(app):
"children": [42]
}
wrong_type = app_client.post('/v1.0/test_schema_recursive', headers=headers, data=json.dumps(42)) # type: flask.Response
wrong_type = app_client.post('/v1.0/test_schema_recursive', headers=headers,
data=json.dumps(42)) # type: flask.Response
assert wrong_type.status_code == 400
assert wrong_type.content_type == 'application/problem+json'
wrong_type_response = json.loads(wrong_type.data.decode()) # type: dict
@@ -526,7 +450,7 @@ def test_schema_recursive(app):
assert wrong_items_response['detail'].startswith("42 is not of type 'object'")
right_type = app_client.post('/v1.0/test_schema_recursive', headers=headers,
data=json.dumps(valid_object)) # type: flask.Response
data=json.dumps(valid_object)) # type: flask.Response
assert right_type.status_code == 200

View File

@@ -1,5 +1,4 @@
import json
import pytest
# we are using "mock" module here for Py 2.7 support
from mock import MagicMock