def test_validate_return_an_error( minimal_spec_dict, simple_operation_dict, old_response_schema, new_response_schema, expected_references, ): old_spec_dict = dict( minimal_spec_dict, paths={ '/endpoint': { 'get': simple_operation_dict, }, }, ) old_spec_dict['paths']['/endpoint']['get']['responses']['200']['schema'] = old_response_schema new_spec_dict = deepcopy(old_spec_dict) new_spec_dict['paths']['/endpoint']['get']['responses']['200']['schema'] = new_response_schema old_spec = load_spec_from_spec_dict(old_spec_dict) new_spec = load_spec_from_spec_dict(new_spec_dict) expected_results = [ AddedEnumValueInRequest.validation_message( reference='#/paths//endpoint/get/responses/200/schema{}'.format(reference), ) for reference in expected_references ] assert list(AddedEnumValueInRequest.validate( left_spec=old_spec, right_spec=new_spec, )) == expected_results
def test_validate_does_not_error_if_changes_in_top_level_parameters( minimal_spec_dict): old_spec_dict = dict( minimal_spec_dict, parameters={ 'param': { 'in': 'body', 'name': 'body', 'required': True, 'schema': { 'properties': { 'property_1': { 'type': 'string' }, }, 'type': 'object', }, }, }, ) new_spec_dict = deepcopy(old_spec_dict) new_spec_dict['parameters']['param']['schema']['required'] = ['property_1'] old_spec = load_spec_from_spec_dict(old_spec_dict) new_spec = load_spec_from_spec_dict(new_spec_dict) assert list( AddedRequiredPropertyInRequest.validate( left_spec=old_spec, right_spec=new_spec, )) == []
def test_validate_succeed( minimal_spec_dict, simple_operation_dict, schema_path, old_schema, new_schema, ): base_spec = dict( minimal_spec_dict, paths={ '/endpoint': { 'get': simple_operation_dict, }, }, ) old_spec_dict = dict(base_spec, **{ schema_path: old_schema, }) new_spec_dict = dict(base_spec, **{ schema_path: new_schema, }) old_spec = load_spec_from_spec_dict(old_spec_dict) new_spec = load_spec_from_spec_dict(new_spec_dict) assert list(ChangedType.validate( left_spec=old_spec, right_spec=new_spec, )) == []
def test_validate_does_not_error_if_changes_in_top_level_parameters( minimal_spec_dict): old_spec_dict = dict( minimal_spec_dict, parameters={ 'param': { 'in': 'body', 'name': 'body', 'required': True, 'schema': { 'properties': { 'property_1': { 'type': 'string', 'enum': ['v1', 'v2'] }, }, 'type': 'object', }, }, }, ) new_spec_dict = deepcopy(old_spec_dict) del new_spec_dict['parameters']['param']['schema']['properties'][ 'property_1']['enum'][0] old_spec = load_spec_from_spec_dict(old_spec_dict) new_spec = load_spec_from_spec_dict(new_spec_dict) assert list( RemovedEnumValueFromRequest.validate( left_spec=old_spec, right_spec=new_spec, )) == []
def test_validate_does_not_errors_if_changes_in_parameters_or_definitions( minimal_spec_dict, simple_operation_dict, schema_path, old_schema, new_schema, ): base_spec = dict( minimal_spec_dict, paths={ '/endpoint': { 'get': simple_operation_dict, }, }, ) old_spec_dict = dict( base_spec, **{ schema_path: old_schema, } ) new_spec_dict = dict( base_spec, **{ schema_path: new_schema, } ) old_spec = load_spec_from_spec_dict(old_spec_dict) new_spec = load_spec_from_spec_dict(new_spec_dict) assert list(AddedEnumValueInRequest.validate( left_spec=old_spec, right_spec=new_spec, )) == []
def test_validate_does_not_errors_if_changes_in_parameters_or_definitions( minimal_spec_dict, simple_operation_dict, schema_path, old_schema, new_schema, ): base_spec = dict( minimal_spec_dict, paths={ '/endpoint': { 'get': simple_operation_dict, }, }, ) old_spec_dict = dict(base_spec, **{ schema_path: old_schema, }) new_spec_dict = dict(base_spec, **{ schema_path: new_schema, }) old_spec = load_spec_from_spec_dict(old_spec_dict) new_spec = load_spec_from_spec_dict(new_spec_dict) assert list( AddedPropertiesInResponseObjectsWithAdditionalPropertiesSetToFalse. validate( left_spec=old_spec, right_spec=new_spec, )) == []
def test_RequiredPropertiesDifferWalker(minimal_spec_dict, left_schema, right_schema, expected_diffs): left_spec = load_spec_from_spec_dict( spec_dict=dict(minimal_spec_dict, definitions={'model': left_schema})) right_spec = load_spec_from_spec_dict( spec_dict=dict(minimal_spec_dict, definitions={'model': right_schema})) assert RequiredPropertiesDifferWalker( left_spec=left_spec, right_spec=right_spec, ).walk() == expected_diffs
def test_RequiredPropertiesDifferWalker_recursive_definition( minimal_spec_dict): minimal_spec_dict['definitions'] = { 'recursive_object': { 'type': 'object', 'properties': { 'property': { '$ref': '#/definitions/model' }, 'recursive_property': { '$ref': '#/definitions/recursive_object' }, }, }, } left_spec_dict = dict( minimal_spec_dict, definitions={ 'model': { 'properties': { 'old_only': { 'type': 'string' }, }, 'required': ['old_only'], 'type': 'object', }, }, ) right_spec_dict = dict( minimal_spec_dict, definitions={ 'model': { 'properties': { 'old_only': { 'type': 'string' }, }, 'type': 'object', }, }, ) left_spec = load_spec_from_spec_dict(spec_dict=left_spec_dict) right_spec = load_spec_from_spec_dict(spec_dict=right_spec_dict) assert RequiredPropertiesDifferWalker( left_spec=left_spec, right_spec=right_spec, ).walk() == [ RequiredPropertiesDiff(path=('definitions', 'model'), mapping=EntityMapping(old={'old_only'}, new=set())) ]
def test_validate_fails_if_parameters_are_defined_in_different_locations_with_different_required_properties( minimal_spec_dict, simple_operation_dict, ): parameter_schema = { 'in': 'body', 'name': 'body', 'required': True, 'schema': { 'properties': { 'property': { 'type': 'string', 'enum': ['v1', 'v2'] }, }, 'type': 'object', }, } old_spec = load_spec_from_spec_dict( dict( minimal_spec_dict, paths={ '/endpoint': { 'parameters': [deepcopy(parameter_schema)], 'get': simple_operation_dict, }, }, )) new_spec_dict = dict( minimal_spec_dict, paths={ '/endpoint': { 'get': dict( simple_operation_dict, parameters=[deepcopy(parameter_schema)], ), }, }, ) del new_spec_dict['paths']['/endpoint']['get']['parameters'][0]['schema'][ 'properties']['property']['enum'][0] new_spec = load_spec_from_spec_dict(new_spec_dict) assert list( RemovedEnumValueFromRequest.validate( left_spec=old_spec, right_spec=new_spec, )) == [ RemovedEnumValueFromRequest.validation_message( reference='#/paths//endpoint/get/parameters/0/schema'), ]
def test_ResponsePathsWalker_returns_paths_of_endpoints_responses( minimal_spec, minimal_spec_dict): minimal_spec_dict['paths'] = { '/endpoint': { 'get': { 'responses': { '200': { 'description': '' }, 'default': { 'description': '' }, }, }, 'put': { 'responses': { '403': { 'description': '' }, }, }, }, } spec = load_spec_from_spec_dict(minimal_spec_dict) assert set(ResponsePathsWalker(spec, spec).walk()) == { ('paths', '/endpoint', 'get', 'responses', '200'), ('paths', '/endpoint', 'get', 'responses', 'default'), ('paths', '/endpoint', 'put', 'responses', '403'), }
def test_RequestParametersWalker_returns_paths_of_endpoints_parameters( minimal_spec, minimal_spec_dict): minimal_spec_dict['paths'] = { '/endpoint': { 'get': { 'parameters': [ { 'in': 'body', 'name': 'body', 'required': True, 'schema': { 'type': 'string', }, }, ], 'responses': { 'default': { 'description': '' }, }, }, 'put': { 'responses': { 'default': { 'description': '' }, }, }, }, } spec = load_spec_from_spec_dict(minimal_spec_dict) assert set(RequestParametersWalker(spec, spec).walk()) == { ('paths', '/endpoint', 'get', 'parameters', 0), }
def test_validate_succeed_if_parameters_are_defined_in_different_locations( minimal_spec_dict, simple_operation_dict): parameter_schema = { 'in': 'body', 'name': 'body', 'required': True, 'schema': { 'properties': { 'property_1': { 'type': 'string' }, }, 'required': ['property_1'], 'type': 'object', }, } old_spec = load_spec_from_spec_dict( dict( minimal_spec_dict, paths={ '/endpoint': { 'parameters': [parameter_schema], 'get': simple_operation_dict, }, }, )) new_spec = load_spec_from_spec_dict( dict( minimal_spec_dict, paths={ '/endpoint': { 'get': dict( simple_operation_dict, parameters=[parameter_schema], ), }, }, )) assert list( AddedRequiredPropertyInRequest.validate( left_spec=old_spec, right_spec=new_spec, )) == []
def test_validate_return_an_error( minimal_spec_dict, simple_operation_dict, old_parameter_schema, new_parameter_schema, expected_references, ): old_spec_dict = dict( minimal_spec_dict, paths={ '/endpoint': { 'get': simple_operation_dict, }, }, ) old_spec_dict['paths']['/endpoint']['get']['parameters'] = [{ 'in': 'body', 'name': 'body', 'required': True, 'schema': old_parameter_schema, }] new_spec_dict = deepcopy(old_spec_dict) new_spec_dict['paths']['/endpoint']['get']['parameters'][0][ 'schema'] = new_parameter_schema old_spec = load_spec_from_spec_dict(old_spec_dict) new_spec = load_spec_from_spec_dict(new_spec_dict) expected_results = [ AddedRequiredPropertyInRequest.validation_message( reference='#/paths//endpoint/get/parameters/0/schema{}'.format( reference), ) for reference in expected_references ] assert list( AddedRequiredPropertyInRequest.validate( left_spec=old_spec, right_spec=new_spec, )) == expected_results
def spec_and_operation(minimal_spec_dict, simple_operation_dict): spec = load_spec_from_spec_dict( dict( minimal_spec_dict, paths={ '/endpoint': { 'get': simple_operation_dict, }, }, )) return spec, spec.resources['endpoint'].operations['get_endpoint']
def test_validate_return_an_error( minimal_spec_dict, simple_operation_dict, is_parameter, old_schema, new_schema, expected_references, ): base_spec = dict( minimal_spec_dict, paths={ '/endpoint': { 'get': simple_operation_dict, }, }, ) old_spec_dict = deepcopy(base_spec) new_spec_dict = deepcopy(base_spec) if is_parameter: old_spec_dict['paths']['/endpoint']['get']['parameters'] = [old_schema] new_spec_dict['paths']['/endpoint']['get']['parameters'] = [new_schema] else: old_spec_dict['paths']['/endpoint']['get']['responses']['200'][ 'schema'] = old_schema new_spec_dict['paths']['/endpoint']['get']['responses']['200'][ 'schema'] = new_schema old_spec = load_spec_from_spec_dict(old_spec_dict) new_spec = load_spec_from_spec_dict(new_spec_dict) expected_results = [ ChangedType.validation_message( reference='#/paths//endpoint/get{}'.format(reference), ) for reference in expected_references ] assert list(ChangedType.validate( left_spec=old_spec, right_spec=new_spec, )) == expected_results
def test_validate_succeed_if_parameters_are_defined_in_different_locations( minimal_spec_dict, simple_operation_dict): parameter_schema = { 'in': 'body', 'name': 'body', 'required': True, 'schema': { 'type': 'string', 'enum': ['v1'] }, } old_spec = load_spec_from_spec_dict( dict( minimal_spec_dict, paths={ '/endpoint': { 'parameters': [parameter_schema], 'get': simple_operation_dict, }, }, )) new_spec = load_spec_from_spec_dict( dict( minimal_spec_dict, paths={ '/endpoint': { 'get': dict( simple_operation_dict, parameters=[parameter_schema], ), }, }, )) assert list( RemovedEnumValueFromRequest.validate( left_spec=old_spec, right_spec=new_spec, )) == []
def test_validate_does_not_error_if_changes_to_additional_properties_type( minimal_spec_dict, simple_operation_dict): old_spec_dict = dict( minimal_spec_dict, paths={ '/endpoint': { 'get': simple_operation_dict, }, }, ) old_spec_dict['paths']['/endpoint']['get']['responses']['200'][ 'schema'] = { 'additionalProperties': False, 'properties': { 'property_1': { 'type': 'string' }, 'property_2': { 'type': 'string' }, }, 'type': 'object', } new_spec_dict = deepcopy(old_spec_dict) del new_spec_dict['paths']['/endpoint']['get']['responses']['200'][ 'schema']['additionalProperties'] old_spec = load_spec_from_spec_dict(old_spec_dict) new_spec = load_spec_from_spec_dict(new_spec_dict) assert list( AddedPropertiesInResponseObjectsWithAdditionalPropertiesSetToFalse. validate( left_spec=old_spec, right_spec=new_spec, )) == []
def test_validate_does_not_error_if_changes_in_response_schema( minimal_spec_dict): old_spec_dict = dict( minimal_spec_dict, paths={ '/endpoint': { 'get': { 'responses': { '200': { 'description': '', 'schema': { 'properties': { 'property_1': { 'type': 'string' }, }, 'type': 'object', }, }, }, }, }, }, ) new_spec_dict = deepcopy(old_spec_dict) new_spec_dict['paths']['/endpoint']['get']['responses']['200']['schema'][ 'required'] = ['property_1'] old_spec = load_spec_from_spec_dict(old_spec_dict) new_spec = load_spec_from_spec_dict(new_spec_dict) assert list( AddedRequiredPropertyInRequest.validate( left_spec=old_spec, right_spec=new_spec, )) == []
def test_validate_return_an_error(minimal_spec_dict, simple_operation_dict, minimal_spec): old_spec_dict = dict( minimal_spec_dict, paths={ '/endpoint': { 'get': simple_operation_dict, }, }, ) old_spec = load_spec_from_spec_dict(old_spec_dict) operation = old_spec.resources['endpoint'].operations['get_endpoint'] assert list( DeletedEndpoint.validate( left_spec=old_spec, right_spec=minimal_spec, )) == [ DeletedEndpoint.validation_message(reference=str( Endpoint( http_verb=HTTPVerb.GET, path='/endpoint', operation=operation, ), ), ), ]
def minimal_spec(minimal_spec_dict): return load_spec_from_spec_dict(minimal_spec_dict)
def test_load_spec_from_spec(minimal_spec_dict): assert load_spec_from_spec_dict( minimal_spec_dict).spec_dict == minimal_spec_dict
def test_EnumValuesDifferWalker_returns_paths_of_endpoints_responses(minimal_spec_dict): old_spec_dict = dict( minimal_spec_dict, definitions={ 'enum_1': { 'type': 'string', 'enum': ['value_to_remove', 'E2', 'E3'], 'x-model': 'enum_1', }, 'enum_2': { 'type': 'string', 'enum': ['E1', 'E2', 'E3'], 'x-model': 'enum_2', }, 'object': { 'properties': { 'enum_1': {'$ref': '#/definitions/enum_1'}, 'enum_2': {'$ref': '#/definitions/enum_2'}, }, 'type': 'object', 'x-model': 'object', }, }, paths={ '/endpoint': { 'get': { 'parameters': [{ 'in': 'body', 'name': 'body', 'required': True, 'schema': { '$ref': '#/definitions/object', }, }], 'responses': { '200': { 'description': '', 'schema': { '$ref': '#/definitions/object', }, }, }, }, }, }, ) new_spec_dict = deepcopy(old_spec_dict) del new_spec_dict['definitions']['enum_1']['enum'][0] new_spec_dict['definitions']['enum_2']['enum'].append('new_value') old_spec = load_spec_from_spec_dict(old_spec_dict) new_spec = load_spec_from_spec_dict(new_spec_dict) assert sorted(EnumValuesDifferWalker(old_spec, new_spec).walk()) == sorted([ EnumValuesDiff( path=('definitions', 'enum_2'), mapping=EntityMapping(old=set(), new={'new_value'}), ), EnumValuesDiff( path=('definitions', 'object', 'properties', 'enum_2'), mapping=EntityMapping(old=set(), new={'new_value'}), ), EnumValuesDiff( path=('definitions', 'object', 'properties', 'enum_1'), mapping=EntityMapping(old={'value_to_remove'}, new=set()), ), EnumValuesDiff( path=('definitions', 'enum_1'), mapping=EntityMapping(old={'value_to_remove'}, new=set()), ), EnumValuesDiff( path=('paths', '/endpoint', 'get', 'responses', '200', 'schema', 'properties', 'enum_2'), mapping=EntityMapping(old=set(), new={'new_value'}), ), EnumValuesDiff( path=('paths', '/endpoint', 'get', 'responses', '200', 'schema', 'properties', 'enum_1'), mapping=EntityMapping(old={'value_to_remove'}, new=set()), ), EnumValuesDiff( path=('paths', '/endpoint', 'get', 'parameters', 0, 'schema', 'properties', 'enum_2'), mapping=EntityMapping(old=set(), new={'new_value'}), ), EnumValuesDiff( path=('paths', '/endpoint', 'get', 'parameters', 0, 'schema', 'properties', 'enum_1'), mapping=EntityMapping(old={'value_to_remove'}, new=set()), ), ])