def test_parametrized_path_with_parameter_definition_as_reference(): context = SchemaFactory( paths={ '/get/{id}': { 'parameters': [ {'$ref': '#/parameters/id'} ], }, }, parameters={ 'id': { 'name': 'id', 'in': PATH, 'description': 'The primary key', 'type': INTEGER, 'required': True, } } ) request = RequestFactory(url='http://www.example.com/get/12345') path = validate_path_to_api_path( path=request.path, context=context, **context ) assert path == '/get/{id}'
def validate_response(response, request_method, schema): """ Response validation involves the following steps. 4. validate that the response status_code is in the allowed responses for the request method. 5. validate that the response content validates against any provided schemas for the responses. 6. headers, content-types, etc..., ??? """ with ErrorDict() as errors: # 1 # TODO: tests try: api_path = validate_path_to_api_path( path=response.path, context=schema, **schema ) except ValidationError as err: errors['path'].extend(list(err.messages)) return # this causes an exception to be raised since errors is no longer falsy. path_definition = schema['paths'][api_path] or {} # TODO: tests try: operation_definition = validate_request_method_to_operation( request_method=request_method, path_definition=path_definition, ) except ValidationError as err: errors['method'].append(err.message) return # 4 try: response_definition = validate_status_code_to_response_definition( response=response, operation_definition=operation_definition, ) except ValidationError as err: errors['status_code'].add_error(err.detail) else: # 5 response_validator = generate_response_validator( api_path, operation_definition=operation_definition, path_definition=path_definition, response_definition=response_definition, context=schema, ) try: response_validator(response, context=schema) except ValidationError as err: errors['body'].add_error(err.detail)
def validate_response(response, request_method, schema): """ Response validation involves the following steps. 4. validate that the response status_code is in the allowed responses for the request method. 5. validate that the response content validates against any provided schemas for the responses. 6. headers, content-types, etc..., ??? """ with ErrorDict() as errors: # 1 # TODO: tests try: api_path = validate_path_to_api_path( path=response.path, context=schema, **schema ) except ValidationError as err: errors['path'].extend(list(err.messages)) return # this causes an exception to be raised since errors is no longer falsy. path_definition = schema['paths'][api_path] or {} # TODO: tests try: operation_definition = validate_request_method_to_operation( request_method=request_method, path_definition=path_definition, ) except ValidationError as err: errors['method'].add_error(err.detail) return # 4 try: response_definition = validate_status_code_to_response_definition( response=response, operation_definition=operation_definition, ) except ValidationError as err: errors['status_code'].add_error(err.detail) else: # 5 response_validator = generate_response_validator( api_path, operation_definition=operation_definition, path_definition=path_definition, response_definition=response_definition, context=schema, ) try: response_validator(response, context=schema) except ValidationError as err: errors['body'].add_error(err.detail)
def test_basic_request_path_validation_with_unspecified_paths(request_path): context = SchemaFactory( paths={'/get': {}}, ) url = 'http://www.example.com{0}'.format(request_path) request = RequestFactory(url=url) with pytest.raises(ValidationError) as err: validate_path_to_api_path( path=request.path, context=context, **context ) assert_message_in_errors( MESSAGES['path']['no_matching_paths_found'], err.value.detail, )
def validate_request(request, schema): """ Request validation does the following steps. 1. validate that the path matches one of the defined paths in the schema. 2. validate that the request method conforms to a supported methods for the given path. 3. validate that the request parameters conform to the parameter definitions for the operation definition. """ with ErrorCollection() as errors: # 1 try: api_path = validate_path_to_api_path( path=request.path, context=schema, **schema ) except ValidationError as err: errors['path'].add_error(err.detail) return # this causes an exception to be raised since errors is no longer falsy. path_definition = schema['paths'][api_path] or {} if not path_definition: # TODO: is it valid to not have a definition for a path? return # 2 try: operation_definition = validate_request_method_to_operation( request_method=request.method, path_definition=path_definition, ) except ValidationError as err: errors['method'].add_error(err.detail) return if operation_definition is None: # TODO: is this compliant with swagger, can path operations have a null # definition? return # 3 operation_validators = construct_operation_validators( api_path=api_path, path_definition=path_definition, operation_definition=operation_definition, context=schema, ) try: validate_operation(request, operation_validators, context=schema) except ValidationError as err: errors['method'].add_error(err.detail)
def test_basic_request_path_validation(): context = SchemaFactory( paths={'/get': {}}, ) request = RequestFactory(url='http://www.example.com/get') path = validate_path_to_api_path( path=request.path, context=context, **context ) assert path == '/get'
def validate_request(request, schema): """ Request validation does the following steps. 1. validate that the path matches one of the defined paths in the schema. 2. validate that the request method conforms to a supported methods for the given path. 3. validate that the request parameters conform to the parameter definitions for the operation definition. """ with ErrorCollection() as errors: # 1 try: api_path = validate_path_to_api_path(path=request.path, context=schema, **schema) except ValidationError as err: errors['path'].add_error(err.detail) return # this causes an exception to be raised since errors is no longer falsy. path_definition = schema['paths'][api_path] or {} if not path_definition: # TODO: is it valid to not have a definition for a path? return # 2 try: operation_definition = validate_request_method_to_operation( request_method=request.method, path_definition=path_definition, ) except ValidationError as err: errors['method'].add_error(err.detail) return if operation_definition is None: # TODO: is this compliant with swagger, can path operations have a null # definition? return # 3 operation_validators = construct_operation_validators( api_path=api_path, path_definition=path_definition, operation_definition=operation_definition, context=schema, ) try: validate_operation(request, operation_validators, context=schema) except ValidationError as err: errors['method'].add_error(err.detail)
def test_parametrized_integer_path_validation(): context = SchemaFactory(paths={ '/get/{id}': { 'parameters': [ # One very plain id of type string. {'name': 'id', 'in': PATH, 'description': 'The id', 'type': INTEGER, 'required': True}, ], } }) request = RequestFactory(url='http://www.example.com/get/25') path = validate_path_to_api_path( path=request.path, context=context, **context ) assert path == '/get/{id}'
def test_parametrized_path_with_multiple_prameters(): context = SchemaFactory(paths={ '/users/{username}/posts/{id}': { 'parameters': [ # One very plain id of type string. {'name': 'id', 'in': PATH, 'description': 'The id', 'type': INTEGER, 'required': True}, {'name': 'username', 'in': PATH, 'description': 'The username', 'type': STRING, 'required': True}, ], } }) request = RequestFactory(url='http://www.example.com/users/john-smith/posts/47') path = validate_path_to_api_path( path=request.path, context=context, **context ) assert path == '/users/{username}/posts/{id}'