mirror of
https://github.com/LukeHagar/connexion.git
synced 2025-12-10 04:19:37 +00:00
Leave body param validation to external lib
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
82
tests/conftest.py
Normal 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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import json
|
||||
import pytest
|
||||
# we are using "mock" module here for Py 2.7 support
|
||||
from mock import MagicMock
|
||||
|
||||
|
||||
Reference in New Issue
Block a user