def test_issue_65_partial_resolution_files(): specs = '''openapi: "3.0.0" info: title: '' version: '1.0.0' paths: {} components: schemas: SampleArray: type: array items: $ref: '#/components/schemas/ItemType' ItemType: type: integer ''' from prance.util import formats specs = formats.parse_spec(specs, 'issue_65.yaml') res = resolver.RefResolver(specs, fs.abspath('issue_65.yaml'), resolve_types = resolver.RESOLVE_FILES ) res.resolve_references() from prance.util.path import path_get val = path_get(res.specs, ('components', 'schemas', 'SampleArray', 'items')) assert '$ref' in val
def test_issue_23_partial_resolution_http(mock_get): mock_get.side_effect = mock_get_petstore specs = get_specs('tests/specs/with_externals.yaml') res = resolver.RefResolver(specs, fs.abspath('tests/specs/with_externals.yaml'), resolve_types = resolver.RESOLVE_HTTP ) res.resolve_references() # By default, all externals need to be resolved. from prance.util.path import path_get val = path_get(res.specs, ('paths', '/pets', 'get', 'responses', '200', 'schema')) assert '$ref' in val val = path_get(res.specs, ('paths', '/pets', 'get', 'responses', 'default', 'schema')) assert '$ref' in val val = path_get(res.specs, ('paths', '/pets', 'post', 'responses', 'default', 'schema')) assert '$ref' in val val = path_get(res.specs, ('paths', '/pets/{petId}', 'get', 'parameters', 0)) assert '$ref' in val val = path_get(res.specs, ('paths', '/pets/{petId}', 'get', 'responses', '200', 'schema')) assert '$ref' not in val val = path_get(res.specs, ('paths', '/pets/{petId}', 'get', 'responses', 'default', 'schema')) assert '$ref' in val
def test_issue_77_translate_external_refs_internal(): specs = '' with open('tests/specs/issue_78/openapi.json', 'r') as fh: specs = fh.read() from prance.util import formats specs = formats.parse_spec(specs, 'openapi.json') res = resolver.RefResolver(specs, fs.abspath('openapi.json'), resolve_types = resolver.RESOLVE_FILES | resolver.RESOLVE_INTERNAL, resolve_method= resolver.TRANSLATE_EXTERNAL ) res.resolve_references() from prance.util.path import path_get val = path_get(res.specs, ('components', 'schemas', '_schemas.json_Body')) # Reference to file is translated in components/schemas assert 'content' in val assert 'application/json' in val['content'] # Internal Reference links updated assert '#/components/schemas/_schemas.json_Something' == val['content']['application/json']['$ref'] # Internal references is copied to componnents/schemas seperately val = path_get(res.specs, ('components', 'schemas', '_schemas.json_Something')) assert 'type' in val # File reference url is updated as well val = path_get(res.specs, ('paths', '/endpoint', 'post', 'requestBody', '$ref')) assert val == '#/components/schemas/_schemas.json_Body'
def test_issue_22_empty_path(mock_get, externals_file): mock_get.side_effect = mock_get_petstore # The raw externals file must have unresolved data assert len(externals_file['paths']['/pets/{petId}']['get']['parameters']) == 1 param = externals_file['paths']['/pets/{petId}']['get']['parameters'][0] assert 'overwritten' in param assert '$ref' in param import os.path from prance.util import fs res = resolver.RefResolver(externals_file, fs.abspath('tests/specs/with_externals.yaml')) res.resolve_references() # The tests should resolve the reference, but the reference overwrites # all else. assert len(res.specs['paths']['/pets/{petId}']['get']['parameters']) == 1 param = res.specs['paths']['/pets/{petId}']['get']['parameters'][0] # Dereferenced keys must exist here assert 'type' in param assert 'description' in param assert 'required' in param assert 'in' in param assert 'name' in param # Previously defined keys must not assert 'overwritten' not in param assert '$ref' not in param
def test_issue_23_partial_resolution_invalid_scheme(): specs = {'$ref': 'foo://cannot-do-anything'} res = resolver.RefResolver(specs, fs.abspath('tests/specs/with_externals.yaml')) with pytest.raises(ValueError): res.resolve_references()
def test_recursion_limit_set_limit_ignore_files(recursion_limit_files_file): # If we overload the handler, and set the recursion limit higher, # we should get nested Pet objects a few levels deep. import os.path res = resolver.RefResolver(recursion_limit_files_file, fs.abspath('tests/recursion_limit_files.yaml'), recursion_limit = 2, recursion_limit_handler = recursion_limit_handler_none) res.resolve_references() from prance.util import formats contents = formats.serialize_spec(res.specs, 'foo.yaml') # The effect of returning None on recursion limit should be that # despite having recursion, the outermost reference to # definitions/Pet should get resolved. assert 'properties' in res.specs['paths']['/pets']['get']['responses']['200']['schema'] # However, the 'next' field should be resolved due to the higher recursion limit next_field = res.specs['paths']['/pets']['get']['responses']['200']['schema']['properties']['next']['schema'] assert next_field is not None # But the 'next' field of the 'next' field should not be resolved. assert next_field['properties']['next']['schema'] is None
def test_resolver_recursive_files(mock_get, recursive_files_file): mock_get.side_effect = mock_get_petstore # Recursive references to files are not a problem import os.path res = resolver.RefResolver(recursive_files_file, fs.abspath('tests/specs/recursive_files.yaml')) res.resolve_references()
def test_resolver_recursive(recursive_file): import os.path res = resolver.RefResolver(recursive_file, os.path.abspath('tests/recursive.yaml')) with pytest.raises(ResolutionError) as exc: res.resolve_references() assert str(exc.value).startswith('Recursion detected')
def test_resolver_named(mock_get, externals_file): mock_get.side_effect = mock_get_petstore import os.path from prance.util import fs res = resolver.RefResolver(externals_file, fs.abspath('tests/specs/with_externals.yaml')) res.resolve_references()
def test_resolver_missing_reference(missing_file): import os.path res = resolver.RefResolver(missing_file, fs.abspath('tests/missing_reference.yaml')) with pytest.raises(ResolutionError) as exc: res.resolve_references() assert str(exc.value).startswith('Cannot resolve')
def test_resolver_recursive_objects(recursive_objs_file): # Recursive references to objects are a problem import os.path res = resolver.RefResolver(recursive_objs_file, fs.abspath('tests/recursive_objs.yaml')) with pytest.raises(ResolutionError) as exc: res.resolve_references() assert str(exc.value).startswith('Recursion reached limit')
def test_issue_69_urlparse_error(): specs = {'$ref': "file://a\u2100b/bad/netloc"} res = resolver.RefResolver(specs, fs.abspath('tests/specs/with_externals.yaml')) with pytest.raises(ResolutionError) as ex: res.resolve_references() assert 'bad/netloc' in str(ex)
def test_issue_72_nonexistent_file_error(): specs = {'$ref': "file://does/not/exist"} res = resolver.RefResolver(specs, fs.abspath('tests/specs/with_externals.yaml')) with pytest.raises(ResolutionError) as exinfo: res.resolve_references() assert 'not/exist' in str(exinfo.value)
def test_recursion_limit_do_not_recurse_raise_files(recursion_limit_files_file): # Expect the default behaviour to raise. import os.path res = resolver.RefResolver(recursion_limit_files_file, fs.abspath('tests/recursion_limit_files.yaml')) with pytest.raises(ResolutionError) as exc: res.resolve_references() assert str(exc.value).startswith('Recursion reached limit of 1')
def test_resolver_missing_reference(mock_get, missing_file): mock_get.side_effect = mock_get_petstore import os.path res = resolver.RefResolver(missing_file, fs.abspath('tests/specs/missing_reference.yaml')) with pytest.raises(ResolutionError) as exc: res.resolve_references() assert str(exc.value).startswith('Cannot resolve')
def test_issue_38_tilde_one(): specs = get_specs('tests/specs/issue_38_a.yaml') res = resolver.RefResolver(specs, fs.abspath('tests/specs/issue_38_a.yaml')) res.resolve_references() path = res.specs['paths']['/api/v2/vms'] assert 'get' in path assert 'operationId' in path['get'] assert 'description' in path['get']
def test_issue_69_urlparse_error(): # XXX depending on python version, the error may not actually come from # parsing the URL, but from trying to load a local file that does # not exist. See test_issue_72_* for a test case that specifically # tries for a nonexistent file url. specs = {'$ref': "file://a\u2100b/bad/netloc"} res = resolver.RefResolver(specs, fs.abspath('tests/specs/with_externals.yaml')) with pytest.raises(ResolutionError) as exinfo: res.resolve_references() assert 'bad/netloc' in str(exinfo.value)
def test_issue_205_swagger_resolution_failure(): specs = '' with open('tests/specs/kubernetes_api_docs.json', 'r') as fh: specs = fh.read() from prance.util import formats specs = formats.parse_spec(specs, 'kubernetes_api_docs.json') res = resolver.RefResolver(specs, fs.abspath('kubernetes_api_docs.json'), resolve_types = resolver.RESOLVE_FILES, resolve_method= resolver.TRANSLATE_EXTERNAL ) # test will raise an exception res.resolve_references()
def test_recursion_limit_do_not_recurse_ignore_files(recursion_limit_files_file): # If we overload the handler, we should not get an error but should # also simply not have the 'next' field - or it should be None import os.path res = resolver.RefResolver(recursion_limit_files_file, fs.abspath('tests/recursion_limit_files.yaml'), recursion_limit_handler = recursion_limit_handler_none) res.resolve_references() from prance.util import formats contents = formats.serialize_spec(res.specs, 'foo.yaml') # The effect of returning None on recursion limit should be that # despite having recursion, the outermost reference to # definitions/Pet should get resolved. assert 'properties' in res.specs['paths']['/pets']['get']['responses']['200']['schema'] # However, the 'next' field should not be resolved. assert res.specs['paths']['/pets']['get']['responses']['200']['schema']['properties']['next']['schema'] is None
def test_issue_78_resolve_internal_bug(): specs = '' with open('tests/specs/issue_78/openapi.json', 'r') as fh: specs = fh.read() from prance.util import formats specs = formats.parse_spec(specs, 'openapi.json') res = resolver.RefResolver(specs, fs.abspath('openapi.json'), resolve_types = resolver.RESOLVE_FILES ) res.resolve_references() from prance.util.path import path_get val = path_get(res.specs, ('paths', '/endpoint', 'post', 'requestBody', 'content')) # Reference to file is resolved assert 'application/json' in val # Internal reference within file is NOT resolved assert '$ref' in val['application/json']
def test_issue_77_internal_refs_unresolved(): specs = '' with open('tests/specs/issue_78/openapi.json', 'r') as fh: specs = fh.read() from prance.util import formats specs = formats.parse_spec(specs, 'openapi.json') res = resolver.RefResolver(specs, fs.abspath('openapi.json'), resolve_types=resolver.RESOLVE_FILES, resolve_method=resolver.TRANSLATE_EXTERNAL) res.resolve_references() from prance.util.path import path_get val = path_get(res.specs, ('components', 'schemas')) # File reference resolved assert '_schemas.json_Body' in val # Internal file reference not resolved assert '_schemas.json_Something' not in val
def test_resolver_recursive_files(recursive_files_file): # Recursive references to files are not a problem import os.path res = resolver.RefResolver(recursive_files_file, fs.abspath('tests/recursive_files.yaml')) res.resolve_references()
def test_resolver_noname(externals_file): res = resolver.RefResolver(externals_file) # Can't build a fragment URL without reference with pytest.raises(ResolutionError): res.resolve_references()
def test_resolver_named(externals_file): import os.path res = resolver.RefResolver(externals_file, os.path.abspath('tests/with_externals.yaml')) res.resolve_references()
def test_resolver_named(externals_file): import os.path from prance.util import fs res = resolver.RefResolver(externals_file, fs.abspath('tests/with_externals.yaml')) res.resolve_references()