def test_response_parameter_validation(): """ Test that request validation does parameter validation. This is largely a smoke test to ensure that parameter validation is wired into request validation correctly. """ from django.core.exceptions import ValidationError schema = SchemaFactory( paths={ '/get': { 'get': { 'responses': {200: {'description': 'Success'}}, }, }, }, ) response = ResponseFactory(url='http://www.example.com/get', status_code=301) with pytest.raises(ValidationError) as err: validate_response( response, paths=schema['paths'], base_path=schema.get('base_path', ''), context=schema, inner=True, ) assert 'response' in err.value.messages[0] assert_error_message_equal( err.value.messages[0]['response'][0], MESSAGES['response']['invalid_status_code'], )
def test_response_validation_with_invalid_operation_on_path(): """ Test that response validation detects request paths that are not declared in the schema. """ from django.core.exceptions import ValidationError schema = SchemaFactory( paths={ '/post': { 'post': None, }, }, ) response = ResponseFactory(url='http://www.example.com/post') with pytest.raises(ValidationError) as err: validate_response( response, paths=schema['paths'], base_path=schema.get('base_path', ''), context=schema, inner=True, ) assert 'request' in err.value.messages[0] assert_error_message_equal( err.value.messages[0]['request'][0], MESSAGES['request']['invalid_method'], )
def test_response_content_type_validation_ignores_parameters(): schema = SchemaFactory( produces=['application/json'], paths={ '/get': { 'get': { 'responses': { '200': { 'description': 'Success' } }, } }, }, ) response = ResponseFactory( url='http://www.example.com/get', content_type='application/json; charset=UTF-8', ) validate_response( response=response, request_method='get', schema=schema, )
def test_basic_response_body_schema_validation_with_invalid_value(): schema = SchemaFactory( paths={ '/get': { 'get': { 'responses': { 200: { 'description': 'Success', 'schema': {'type': INTEGER}, } }, }, }, }, ) response = ResponseFactory( url='http://www.example.com/get', status_code=200, content_type='application/json', content=json.dumps('not-an-integer'), ) with pytest.raises(ValidationError) as err: validate_response( response=response, request_method='get', schema=schema, ) assert_message_in_errors( MESSAGES['type']['invalid'], err.value.detail, 'body.schema.type', )
def test_match_target_path_to_api_path(path, schema_path): schema = SchemaFactory( paths={ '/path': {}, '/path.json': {}, '/get/{id}': { 'parameters': [{ 'name': 'id', 'in': PATH, 'type': INTEGER, 'required': True, }], }, '/post': {}, }, basePath='/api', ) paths = schema['paths'] base_path = schema['basePath'] path = match_path_to_api_path( path_definitions=paths, target_path=path, base_path=base_path, ) assert path == schema_path
def test_request_parameter_array_extraction(format_, value): schema = SchemaFactory(paths={ '/get/': { 'get': { 'responses': { '200': { 'description': "Success" } }, 'parameters': [ { 'name': 'id', 'in': QUERY, 'type': ARRAY, 'collectionFormat': format_, 'minItems': 3, 'maxItems': 3, 'items': { 'type': INTEGER, 'minimum': 1, 'maximum': 3, }, }, ], }, }, }, ) request = RequestFactory( url='http://www.example.com/get/?id={}'.format(value)) validate_request( request=request, schema=schema, )
def test_request_validation_with_valid_path_and_base_path(): """ Test that request validation is able to match api paths that also have a base api path. """ schema = SchemaFactory( basePath='/api/v1', paths={ '/get': { 'get': { 'responses': { 200: { 'description': "Success" } }, }, }, }, ) request = RequestFactory(url='http://www.example.com/api/v1/get') validate_request( request=request, schema=schema, )
def test_consumes_validation_for_valid_mimetype_from_operation_definition(): """ Test that when `consumes` is defined in an operation definition, that the local value is used in place of any global `consumes` definition. """ request = RequestFactory(content_type='application/json') response = ResponseFactory(request=request) schema = SchemaFactory( consumes=['application/xml'], paths={ '/get': { 'get': { 'responses': { '200': { 'description': 'Success' } }, 'consumes': ['application/json'], } }, }, ) validators = construct_operation_validators( api_path='/get', path_definition=schema['paths']['/get'], operation_definition=schema['paths']['/get']['get'], context=schema, ) validate_operation(response.request, validators)
def test_response_parameter_with_yaml(): """ Test that when flex is asked to load YAML file, a response value that was an integer, is converted to a string """ schema = SchemaFactory( paths={ '/get': { 'get': { 'responses': { 200: {'description': 'Success'}, 404: {'description': 'Failure'}, 'default': {'description': 'Unexpected error.'} }, }, }, }, ) response = ResponseFactory(url='http://www.example.com/get', status_code=404) validate_response( response=response, request_method='get', schema=schema, )
def test_request_validation_with_invalid_operation_on_path(): """ Test that request validation detects request paths that are not declared in the schema. """ schema = SchemaFactory( paths={ '/post': { 'post': {}, }, }, ) request = RequestFactory(url='http://www.example.com/post') with pytest.raises(ValidationError) as err: validate_request( request=request, schema=schema, ) assert_message_in_errors( MESSAGES['request']['invalid_method'], err.value.detail, 'method', )
def test_request_header_validation(): schema = SchemaFactory(paths={ '/get/': { 'get': { 'responses': { 200: { 'description': "Success" } }, 'parameters': [{ 'name': 'Authorization', 'in': HEADER, 'type': INTEGER, }] }, }, }, ) request = RequestFactory( url='http://www.example.com/get/', headers={'Authorization': 'abc'}, ) with pytest.raises(ValidationError) as err: validate_request( request=request, schema=schema, ) assert_message_in_errors( MESSAGES['type']['invalid'], err.value.detail, 'method.parameters.headers.Authorization.type', )
def test_request_validation_with_invalid_operation_on_path(): schema = SchemaFactory( consumes=['application/json'], paths={ '/get': { 'get': { 'responses': { 200: { 'description': 'Success' } }, } }, }, ) request = RequestFactory( url='http://www.example.com/get', content_type=None, ) validate_request( request=request, schema=schema, )
def test_request_content_type_validation_ignores_parameters(): schema = SchemaFactory( consumes=['application/json'], paths={ '/get': { 'get': { 'responses': { '200': { 'description': 'Success' } }, } }, }, ) request = RequestFactory( url='http://www.example.com/get', content_type='application/json; charset=utf-8', ) validate_request( request=request, schema=schema, )
def test_response_validation_with_parametrized_path_and_base_path_slash_end(): """ Test that request validation finds and validates parametrized paths even when the api has a base path being /. """ schema = SchemaFactory(basePath='/api/v1/', paths={ '/get/{id}': { 'get': { 'responses': { '200': { 'description': 'Success' } } }, 'parameters': [{ 'name': 'id', 'in': PATH, 'description': 'The Primary Key', 'type': INTEGER, 'required': True, }] }, }) response = ResponseFactory(url='http://www.example.com/api/v1/get/1234') validate_response( response=response, request_method='get', schema=schema, )
def test_response_validation_with_parametrized_path(): """ Test that request validation finds and validates parametrized paths. """ schema = SchemaFactory( paths={ '/get/{id}': { 'get': { 'responses': { 200: { 'description': 'Success' } } }, 'parameters': [{ 'name': 'id', 'in': PATH, 'description': 'The Primary Key', 'type': INTEGER, 'required': True, }] }, }) response = ResponseFactory(url='http://www.example.com/get/1234') validate_response( response=response, request_method='get', schema=schema, )
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 test_produces_validation_for_invalid_mimetype_from_operation_definition(): """ Test the situation when the operation definition has overridden the global allowed mimetypes, that that the local value is used for validation. """ response = ResponseFactory( content_type='application/xml', url='http://www.example.com/get', ) schema = SchemaFactory( produces=['application/xml'], paths={ '/get': {'get': { 'responses': {200: {'description': 'Success'}}, 'produces': ['application/json'], }}, }, ) with pytest.raises(ValidationError) as err: validate_response( response=response, request_method='get', schema=schema, ) assert_message_in_errors( MESSAGES['content_type']['invalid'], err.value.detail, 'body.produces', )
def test_consumes_validation_invalid_mimetype_from_global_definition(): """ Test that a request content_type that is in the global api consumes definitions is valid. """ request = RequestFactory(content_type='application/json') response = ResponseFactory(request=request) schema = SchemaFactory( consumes=['text/xml', 'application/xml'], paths={ '/get': { 'get': { 'responses': { '200': { 'description': 'Success' } } } }, }, ) validators = construct_operation_validators( api_path='/get', path_definition=schema['paths']['/get'], operation_definition=schema['paths']['/get']['get'], context=schema, ) with pytest.raises(ValidationError): validate_operation(response.request, validators)
def test_produces_validation_for_valid_mimetype_from_operation_definition(): """ Test that when `produces` is defined in an operation definition, that the local value is used in place of any global `produces` definition. """ response = ResponseFactory( content_type='application/json', url='http://www.example.com/get', ) schema = SchemaFactory( produces=['application/xml'], paths={ '/get': {'get': { 'responses': {200: {'description': 'Success'}}, 'produces': ['application/json'], }}, }, ) validate_response( response=response, request_method='get', schema=schema, )
def test_response_validation_with_invalid_method(): """ Test that response validation detects not defined method. """ schema = SchemaFactory( paths={ '/get': { GET: {'responses': {'200': {'description': 'Success'}}}, }, } ) response = ResponseFactory(url='http://www.example.com/get') with pytest.raises(ValidationError) as err: validate_response( response=response, request_method=POST, schema=schema, ) assert_message_in_errors( MESSAGES['request']['invalid_method'], err.value.detail, 'method', )
def test_request_validation_with_parametrized_path_with_base_path(): """ Test that request validation finds and validates parametrized paths. """ schema = SchemaFactory(basePath='/api/v1/', paths={ '/get/{id}': { 'get': { 'responses': { '200': { 'description': 'Success' } } }, 'parameters': [{ 'name': 'id', 'in': PATH, 'description': 'The Primary Key', 'type': INTEGER, 'required': True, }] }, }) request = RequestFactory(url='http://www.example.com/api/v1/get/1234') validate_request( request=request, schema=schema, )
def test_request_parameter_validation_typecasting(type_, value): """ Test that request validation does parameter validation for all parameters that require typecasting since query params are generally treated as strings. """ schema = SchemaFactory(paths={ '/get/': { 'parameters': [{ 'name': 'id', 'in': QUERY, 'type': type_, }], 'get': { 'responses': { "200": { 'description': "Success" } }, }, }, }, ) request = RequestFactory( url='http://www.example.com/get/?id={}'.format(value)) validate_request( request=request, schema=schema, )
def test_matching_with_full_nested_list_resource(): schema = SchemaFactory(paths={ '/get/main/': { 'get': {}, }, '/get/main/{id}': { 'get': { 'parameters': [{ 'name': 'id', 'in': PATH, 'type': STRING, 'required': True, }], }, }, '/get/main/{id}/nested/': { 'get': { 'parameters': [ { 'name': 'id', 'in': PATH, 'type': STRING, 'required': True, }, ], }, }, }, ) paths = schema['paths'] path = match_path_to_api_path( path_definitions=paths, target_path='/get/main/1234/nested/', ) assert path == '/get/main/{id}/nested/'
def test_request_parameter_validation_with_base_path(): """ Test that path parameter validation works even when there is a base path in the api. """ schema = SchemaFactory( basePath='/api/v1', paths={ '/get/{id}/': { 'parameters': [ { 'name': 'id', 'in': PATH, 'description': 'id', 'required': True, 'type': STRING, }, ], 'get': { 'responses': { 200: { 'description': "Success" } }, }, }, }, ) request = RequestFactory(url='http://www.example.com/api/v1/get/32/') validate_request( request=request, schema=schema, )
def test_response_parameter_validation(): """ Test that request validation does parameter validation. This is largely a smoke test to ensure that parameter validation is wired into request validation correctly. """ schema = SchemaFactory(paths={ '/get': { 'get': { 'responses': { '200': { 'description': 'Success' } }, }, }, }, ) response = ResponseFactory(url='http://www.example.com/get', status_code=301) with pytest.raises(ValidationError) as err: validate_response( response=response, request_method='get', schema=schema, ) assert 'status_code' in err.value.messages[0] assert_error_message_equal( err.value.messages[0]['status_code'][0], MESSAGES['response']['invalid_status_code'], )
def test_response_header_validation_for_non_strings(type_, value): schema = SchemaFactory(paths={ '/get': { 'get': { 'responses': { '200': { 'description': "Success", 'headers': { 'Foo': { 'type': type_ }, } } }, }, }, }, ) response = ResponseFactory( url='http://www.example.com/get', headers={'Foo': value}, ) validate_response( response=response, request_method='get', schema=schema, )
def test_response_paramater_uses_default(): """ Test that a `default` key is used if one exists and no matching response is found. See http://swagger.io/specification/#responsesObject. """ schema = SchemaFactory(paths={ '/get': { 'get': { 'responses': { '200': { 'description': 'Success' }, 'default': { 'description': 'Unexpected error.' } }, }, }, }, ) response = ResponseFactory(url='http://www.example.com/get', status_code=301) validate_response( response=response, request_method='get', schema=schema, )
def test_response_content_type_validation_when_no_content_type_specified(): schema = SchemaFactory( produces=['application/json'], paths={ '/get': { 'get': { 'responses': { '200': { 'description': 'Success' } }, } }, }, ) response = ResponseFactory( url='http://www.example.com/get', content_type=None, ) # this is considered valid currently, but may change validate_response( response=response, request_method='get', schema=schema, )
def test_basic_response_body_schema_validation_with_nullable_value(): """ Ensure objects marked with x-nullable: true attribute are treated as nullable. """ schema = SchemaFactory(paths={ '/get': { 'get': { 'responses': { '200': { 'description': 'Success', 'schema': { 'type': INTEGER, 'x-nullable': True }, } }, }, }, }, ) response = ResponseFactory( url='http://www.example.com/get', status_code=200, content_type='application/json', content=json.dumps(None), ) validate_response( response=response, request_method='get', schema=schema, )
def test_response_validation_with_valid_path_and_base_path(): """ Test that response validation is able to match api paths even when there is a base path. """ schema = SchemaFactory(basePath='/api/v1', paths={ '/get': { 'get': { 'responses': { 200: { 'description': 'Success' } } }, }, }) response = ResponseFactory(url='http://www.example.com/api/v1/get') validate_response( response=response, request_method='get', schema=schema, )
def test_consumes_validation_for_invalid_mimetype_from_operation_definition(): """ Test the situation when the operation definition has overridden the global allowed mimetypes, that that the local value is used for validation. """ request = RequestFactory(content_type='application/xml') response = ResponseFactory(request=request) schema = SchemaFactory( consumes=['application/xml'], paths={ '/get': { 'get': { 'responses': { '200': { 'description': 'Success' } }, 'consumes': ['application/json'], } }, }, ) validators = construct_operation_validators( api_path='/get', path_definition=schema['paths']['/get'], operation_definition=schema['paths']['/get']['get'], context=schema, ) with pytest.raises(ValidationError): validate_operation(response.request, validators)
def test_response_validation_with_invalid_operation_on_path(): schema = SchemaFactory( produces=['application/json'], paths={ '/get': { 'get': { 'responses': { '200': { 'description': 'Success' } }, } }, }, ) response = ResponseFactory( url='http://www.example.com/get', content_type=None, ) validate_response( response=response, request_method='get', schema=schema, )
def test_request_header_validation(): from django.core.exceptions import ValidationError schema = SchemaFactory( paths={ '/get/': { 'get': { 'responses': {200: {'description': "Success"}}, 'parameters': [ { 'name': 'Authorization', 'in': HEADER, 'type': INTEGER, } ] }, }, }, ) response = ResponseFactory( url='http://www.example.com/get/', request__headers={'Authorization': 'abc'}, ) with pytest.raises(ValidationError) as err: validate_response( response, paths=schema['paths'], base_path=schema.get('base_path', ''), context=schema, inner=True, ) assert 'request' in err.value.messages[0] assert 'parameters' in err.value.messages[0]['request'][0][0] assert 'headers' in err.value.messages[0]['request'][0][0]['parameters'][0] assert 'Authorization' in err.value.messages[0]['request'][0][0]['parameters'][0]['headers'][0] assert 'type' in err.value.messages[0]['request'][0][0]['parameters'][0]['headers'][0]['Authorization'][0] assert_error_message_equal( err.value.messages[0]['request'][0][0]['parameters'][0]['headers'][0]['Authorization'][0]['type'][0], MESSAGES['type']['invalid'], )
def test_response_parameter_validation(): """ Test that request validation does parameter validation. This is largely a smoke test to ensure that parameter validation is wired into request validation correctly. """ from django.core.exceptions import ValidationError schema = SchemaFactory( paths={ '/get/{id}/': { 'parameters': [ { 'name': 'id', 'in': PATH, 'description': 'id', 'required': True, 'type': STRING, 'format': 'uuid', }, { 'name': 'page', 'in': QUERY, 'type': INTEGER, }, ], 'get': { 'responses': {200: {'description': "Success"}}, }, }, }, ) response = ResponseFactory(url='http://www.example.com/get/32/?page=abcd') with pytest.raises(ValidationError) as err: validate_response( response, paths=schema['paths'], base_path=schema.get('base_path', ''), context=schema, inner=True, ) assert 'request' in err.value.messages[0] assert 'parameters' in err.value.messages[0]['request'][0][0] assert 'path' in err.value.messages[0]['request'][0][0]['parameters'][0] assert 'id' in err.value.messages[0]['request'][0][0]['parameters'][0]['path'][0] assert 'format' in err.value.messages[0]['request'][0][0]['parameters'][0]['path'][0]['id'][0] assert_error_message_equal( err.value.messages[0]['request'][0][0]['parameters'][0]['path'][0]['id'][0]['format'][0], MESSAGES['format']['invalid_uuid'], ) assert 'query' in err.value.messages[0]['request'][0][0]['parameters'][0] assert 'page' in err.value.messages[0]['request'][0][0]['parameters'][0]['query'][0] assert 'type' in err.value.messages[0]['request'][0][0]['parameters'][0]['query'][0]['page'][0] assert_error_message_equal( err.value.messages[0]['request'][0][0]['parameters'][0]['query'][0]['page'][0]['type'][0], MESSAGES['type']['invalid'], )