From 9deb5fcf699cfb40841beffa7ceba0447785a26c Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Wed, 3 Mar 2021 15:44:22 +0100 Subject: [PATCH 1/6] that was unexpectedly convoluted Signed-off-by: Pierre Fenoll --- openapi3/swagger_loader_test.go | 37 ++++++++++----------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/openapi3/swagger_loader_test.go b/openapi3/swagger_loader_test.go index 578932039..d313c6386 100644 --- a/openapi3/swagger_loader_test.go +++ b/openapi3/swagger_loader_test.go @@ -132,13 +132,8 @@ paths: require.Equal(t, example.Value.Value.(map[string]interface{})["error"].(bool), false) } -type sourceExample struct { - Location *url.URL - Spec []byte -} - type multipleSourceSwaggerLoaderExample struct { - Sources []*sourceExample + Sources map[string][]byte } func (l *multipleSourceSwaggerLoaderExample) LoadSwaggerFromURI( @@ -147,19 +142,13 @@ func (l *multipleSourceSwaggerLoaderExample) LoadSwaggerFromURI( ) (*Swagger, error) { source := l.resolveSourceFromURI(location) if source == nil { - return nil, fmt.Errorf("Unsupported URI: '%s'", location.String()) + return nil, fmt.Errorf("Unsupported URI: %q", location.String()) } - return loader.LoadSwaggerFromData(source.Spec) + return loader.LoadSwaggerFromData(source) } -func (l *multipleSourceSwaggerLoaderExample) resolveSourceFromURI(location fmt.Stringer) *sourceExample { - locationString := location.String() - for _, v := range l.Sources { - if v.Location.String() == locationString { - return v - } - } - return nil +func (l *multipleSourceSwaggerLoaderExample) resolveSourceFromURI(location fmt.Stringer) []byte { + return l.Sources[location.String()] } func TestResolveSchemaExternalRef(t *testing.T) { @@ -171,26 +160,22 @@ func TestResolveSchemaExternalRef(t *testing.T) { )) externalSpec := []byte(`{"openapi":"3.0.0","info":{"title":"MyAPI","version":"0.1","description":"External Spec"},"paths":{},"components":{"schemas":{"External":{"type":"string"}}}}`) multipleSourceLoader := &multipleSourceSwaggerLoaderExample{ - Sources: []*sourceExample{ - { - Location: rootLocation, - Spec: rootSpec, - }, - { - Location: externalLocation, - Spec: externalSpec, - }, + Sources: map[string][]byte{ + rootLocation.String(): rootSpec, + externalLocation.String(): externalSpec, }, } loader := &SwaggerLoader{ IsExternalRefsAllowed: true, LoadSwaggerFromURIFunc: multipleSourceLoader.LoadSwaggerFromURI, } + doc, err := loader.LoadSwaggerFromURI(rootLocation) require.NoError(t, err) - err = doc.Validate(loader.Context) + err = doc.Validate(loader.Context) require.NoError(t, err) + refRootVisited := doc.Components.Schemas["Root"].Value.AllOf[0] require.Equal(t, fmt.Sprintf("%s#/components/schemas/External", externalLocation.String()), refRootVisited.Ref) require.NotNil(t, refRootVisited.Value) From 9a786f7388d7c84b2d03c75584b8a4e57b56774b Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Wed, 3 Mar 2021 18:15:48 +0100 Subject: [PATCH 2/6] drop sl.LoadSwaggerFromURIFunc Signed-off-by: Pierre Fenoll --- README.md | 5 +++++ openapi3/swagger_loader.go | 12 ------------ openapi3/swagger_loader_test.go | 8 ++++---- 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 979c08164..c1761a6ab 100644 --- a/README.md +++ b/README.md @@ -197,3 +197,8 @@ func arrayUniqueItemsChecker(items []interface{}) bool { // Check the uniqueness of the input slice(array in JSON) } ``` + +## Sub-v0 breaking API changes + +### v0.47.0 +Field `(*openapi3.SwaggerLoader).LoadSwaggerFromURIFunc` of type `func(*openapi3.SwaggerLoader, *url.URL) (*openapi3.Swagger, error)` was removed after the addition of the field `(*openapi3.SwaggerLoader).ReadFromURIFunc` of type `func(*openapi3.SwaggerLoader, *url.URL) ([]byte, error)`. diff --git a/openapi3/swagger_loader.go b/openapi3/swagger_loader.go index db0eb44be..c8ad52716 100644 --- a/openapi3/swagger_loader.go +++ b/openapi3/swagger_loader.go @@ -29,9 +29,6 @@ type SwaggerLoader struct { // IsExternalRefsAllowed enables visiting other files IsExternalRefsAllowed bool - // LoadSwaggerFromURIFunc allows overriding the swagger file/URL reading func - LoadSwaggerFromURIFunc func(loader *SwaggerLoader, url *url.URL) (*Swagger, error) - // ReadFromURIFunc allows overriding the any file/URL reading func ReadFromURIFunc func(loader *SwaggerLoader, url *url.URL) ([]byte, error) @@ -67,10 +64,6 @@ func (swaggerLoader *SwaggerLoader) LoadSwaggerFromURI(location *url.URL) (*Swag } func (swaggerLoader *SwaggerLoader) loadSwaggerFromURIInternal(location *url.URL) (*Swagger, error) { - f := swaggerLoader.LoadSwaggerFromURIFunc - if f != nil { - return f(swaggerLoader, location) - } data, err := swaggerLoader.readURL(location) if err != nil { return nil, err @@ -145,12 +138,7 @@ func (swaggerLoader *SwaggerLoader) LoadSwaggerFromFile(path string) (*Swagger, } func (swaggerLoader *SwaggerLoader) loadSwaggerFromFileInternal(path string) (*Swagger, error) { - f := swaggerLoader.LoadSwaggerFromURIFunc pathAsURL := &url.URL{Path: path} - if f != nil { - x, err := f(swaggerLoader, pathAsURL) - return x, err - } data, err := swaggerLoader.readURL(pathAsURL) if err != nil { return nil, err diff --git a/openapi3/swagger_loader_test.go b/openapi3/swagger_loader_test.go index d313c6386..9c7b3c54f 100644 --- a/openapi3/swagger_loader_test.go +++ b/openapi3/swagger_loader_test.go @@ -139,12 +139,12 @@ type multipleSourceSwaggerLoaderExample struct { func (l *multipleSourceSwaggerLoaderExample) LoadSwaggerFromURI( loader *SwaggerLoader, location *url.URL, -) (*Swagger, error) { +) ([]byte, error) { source := l.resolveSourceFromURI(location) if source == nil { return nil, fmt.Errorf("Unsupported URI: %q", location.String()) } - return loader.LoadSwaggerFromData(source) + return source, nil } func (l *multipleSourceSwaggerLoaderExample) resolveSourceFromURI(location fmt.Stringer) []byte { @@ -166,8 +166,8 @@ func TestResolveSchemaExternalRef(t *testing.T) { }, } loader := &SwaggerLoader{ - IsExternalRefsAllowed: true, - LoadSwaggerFromURIFunc: multipleSourceLoader.LoadSwaggerFromURI, + IsExternalRefsAllowed: true, + ReadFromURIFunc: multipleSourceLoader.LoadSwaggerFromURI, } doc, err := loader.LoadSwaggerFromURI(rootLocation) From f441307a9555dee80dbd08dcef11e0c696d51d24 Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Wed, 3 Mar 2021 18:20:03 +0100 Subject: [PATCH 3/6] nitpick: only allocate visited-per-ref when needed Signed-off-by: Pierre Fenoll --- openapi3/swagger_loader.go | 48 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/openapi3/swagger_loader.go b/openapi3/swagger_loader.go index c8ad52716..96d609a2d 100644 --- a/openapi3/swagger_loader.go +++ b/openapi3/swagger_loader.go @@ -188,30 +188,6 @@ func (swaggerLoader *SwaggerLoader) loadSwaggerFromDataWithPathInternal(data []b // ResolveRefsIn expands references if for instance spec was just unmarshalled func (swaggerLoader *SwaggerLoader) ResolveRefsIn(swagger *Swagger, path *url.URL) (err error) { - if swaggerLoader.visitedExample == nil { - swaggerLoader.visitedExample = make(map[*Example]struct{}) - } - if swaggerLoader.visitedHeader == nil { - swaggerLoader.visitedHeader = make(map[*Header]struct{}) - } - if swaggerLoader.visitedLink == nil { - swaggerLoader.visitedLink = make(map[*Link]struct{}) - } - if swaggerLoader.visitedParameter == nil { - swaggerLoader.visitedParameter = make(map[*Parameter]struct{}) - } - if swaggerLoader.visitedRequestBody == nil { - swaggerLoader.visitedRequestBody = make(map[*RequestBody]struct{}) - } - if swaggerLoader.visitedResponse == nil { - swaggerLoader.visitedResponse = make(map[*Response]struct{}) - } - if swaggerLoader.visitedSchema == nil { - swaggerLoader.visitedSchema = make(map[*Schema]struct{}) - } - if swaggerLoader.visitedSecurityScheme == nil { - swaggerLoader.visitedSecurityScheme = make(map[*SecurityScheme]struct{}) - } if swaggerLoader.visitedFiles == nil { swaggerLoader.reset() } @@ -444,6 +420,9 @@ func (swaggerLoader *SwaggerLoader) resolveRefSwagger(swagger *Swagger, ref stri func (swaggerLoader *SwaggerLoader) resolveHeaderRef(swagger *Swagger, component *HeaderRef, documentPath *url.URL) error { if component != nil && component.Value != nil { + if swaggerLoader.visitedHeader == nil { + swaggerLoader.visitedHeader = make(map[*Header]struct{}) + } if _, ok := swaggerLoader.visitedHeader[component.Value]; ok { return nil } @@ -488,6 +467,9 @@ func (swaggerLoader *SwaggerLoader) resolveHeaderRef(swagger *Swagger, component func (swaggerLoader *SwaggerLoader) resolveParameterRef(swagger *Swagger, component *ParameterRef, documentPath *url.URL) error { if component != nil && component.Value != nil { + if swaggerLoader.visitedParameter == nil { + swaggerLoader.visitedParameter = make(map[*Parameter]struct{}) + } if _, ok := swaggerLoader.visitedParameter[component.Value]; ok { return nil } @@ -548,6 +530,9 @@ func (swaggerLoader *SwaggerLoader) resolveParameterRef(swagger *Swagger, compon func (swaggerLoader *SwaggerLoader) resolveRequestBodyRef(swagger *Swagger, component *RequestBodyRef, documentPath *url.URL) error { if component != nil && component.Value != nil { + if swaggerLoader.visitedRequestBody == nil { + swaggerLoader.visitedRequestBody = make(map[*RequestBody]struct{}) + } if _, ok := swaggerLoader.visitedRequestBody[component.Value]; ok { return nil } @@ -600,6 +585,9 @@ func (swaggerLoader *SwaggerLoader) resolveRequestBodyRef(swagger *Swagger, comp func (swaggerLoader *SwaggerLoader) resolveResponseRef(swagger *Swagger, component *ResponseRef, documentPath *url.URL) error { if component != nil && component.Value != nil { + if swaggerLoader.visitedResponse == nil { + swaggerLoader.visitedResponse = make(map[*Response]struct{}) + } if _, ok := swaggerLoader.visitedResponse[component.Value]; ok { return nil } @@ -671,6 +659,9 @@ func (swaggerLoader *SwaggerLoader) resolveResponseRef(swagger *Swagger, compone func (swaggerLoader *SwaggerLoader) resolveSchemaRef(swagger *Swagger, component *SchemaRef, documentPath *url.URL) error { if component != nil && component.Value != nil { + if swaggerLoader.visitedSchema == nil { + swaggerLoader.visitedSchema = make(map[*Schema]struct{}) + } if _, ok := swaggerLoader.visitedSchema[component.Value]; ok { return nil } @@ -754,6 +745,9 @@ func (swaggerLoader *SwaggerLoader) resolveSchemaRef(swagger *Swagger, component func (swaggerLoader *SwaggerLoader) resolveSecuritySchemeRef(swagger *Swagger, component *SecuritySchemeRef, documentPath *url.URL) error { if component != nil && component.Value != nil { + if swaggerLoader.visitedSecurityScheme == nil { + swaggerLoader.visitedSecurityScheme = make(map[*SecurityScheme]struct{}) + } if _, ok := swaggerLoader.visitedSecurityScheme[component.Value]; ok { return nil } @@ -789,6 +783,9 @@ func (swaggerLoader *SwaggerLoader) resolveSecuritySchemeRef(swagger *Swagger, c func (swaggerLoader *SwaggerLoader) resolveExampleRef(swagger *Swagger, component *ExampleRef, documentPath *url.URL) error { if component != nil && component.Value != nil { + if swaggerLoader.visitedExample == nil { + swaggerLoader.visitedExample = make(map[*Example]struct{}) + } if _, ok := swaggerLoader.visitedExample[component.Value]; ok { return nil } @@ -824,6 +821,9 @@ func (swaggerLoader *SwaggerLoader) resolveExampleRef(swagger *Swagger, componen func (swaggerLoader *SwaggerLoader) resolveLinkRef(swagger *Swagger, component *LinkRef, documentPath *url.URL) error { if component != nil && component.Value != nil { + if swaggerLoader.visitedLink == nil { + swaggerLoader.visitedLink = make(map[*Link]struct{}) + } if _, ok := swaggerLoader.visitedLink[component.Value]; ok { return nil } From 304083045cdc5262fd23d2de8907d45aab797122 Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Wed, 3 Mar 2021 18:27:13 +0100 Subject: [PATCH 4/6] these are not coupled Signed-off-by: Pierre Fenoll --- openapi3/swagger_loader.go | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/openapi3/swagger_loader.go b/openapi3/swagger_loader.go index 96d609a2d..292c7203e 100644 --- a/openapi3/swagger_loader.go +++ b/openapi3/swagger_loader.go @@ -34,8 +34,9 @@ type SwaggerLoader struct { Context context.Context - visitedFiles map[string]struct{} - visitedSwaggers map[string]*Swagger + visitedPathItemRefs map[string]struct{} + + visitedDocuments map[string]*Swagger visitedExample map[*Example]struct{} visitedHeader map[*Header]struct{} @@ -52,14 +53,13 @@ func NewSwaggerLoader() *SwaggerLoader { return &SwaggerLoader{} } -func (swaggerLoader *SwaggerLoader) reset() { - swaggerLoader.visitedFiles = make(map[string]struct{}) - swaggerLoader.visitedSwaggers = make(map[string]*Swagger) +func (swaggerLoader *SwaggerLoader) resetVisitedPathItemRefs() { + swaggerLoader.visitedPathItemRefs = make(map[string]struct{}) } // LoadSwaggerFromURI loads a spec from a remote URL func (swaggerLoader *SwaggerLoader) LoadSwaggerFromURI(location *url.URL) (*Swagger, error) { - swaggerLoader.reset() + swaggerLoader.resetVisitedPathItemRefs() return swaggerLoader.loadSwaggerFromURIInternal(location) } @@ -133,7 +133,7 @@ func (swaggerLoader *SwaggerLoader) readURL(location *url.URL) ([]byte, error) { // LoadSwaggerFromFile loads a spec from a local file path func (swaggerLoader *SwaggerLoader) LoadSwaggerFromFile(path string) (*Swagger, error) { - swaggerLoader.reset() + swaggerLoader.resetVisitedPathItemRefs() return swaggerLoader.loadSwaggerFromFileInternal(path) } @@ -148,7 +148,7 @@ func (swaggerLoader *SwaggerLoader) loadSwaggerFromFileInternal(path string) (*S // LoadSwaggerFromData loads a spec from a byte array func (swaggerLoader *SwaggerLoader) LoadSwaggerFromData(data []byte) (*Swagger, error) { - swaggerLoader.reset() + swaggerLoader.resetVisitedPathItemRefs() return swaggerLoader.loadSwaggerFromDataInternal(data) } @@ -163,18 +163,21 @@ func (swaggerLoader *SwaggerLoader) loadSwaggerFromDataInternal(data []byte) (*S // LoadSwaggerFromDataWithPath takes the OpenApi spec data in bytes and a path where the resolver can find referred // elements and returns a *Swagger with all resolved data or an error if unable to load data or resolve refs. func (swaggerLoader *SwaggerLoader) LoadSwaggerFromDataWithPath(data []byte, path *url.URL) (*Swagger, error) { - swaggerLoader.reset() + swaggerLoader.resetVisitedPathItemRefs() return swaggerLoader.loadSwaggerFromDataWithPathInternal(data, path) } func (swaggerLoader *SwaggerLoader) loadSwaggerFromDataWithPathInternal(data []byte, path *url.URL) (*Swagger, error) { - visited, ok := swaggerLoader.visitedSwaggers[path.String()] - if ok { - return visited, nil + if swaggerLoader.visitedDocuments == nil { + swaggerLoader.visitedDocuments = make(map[string]*Swagger) + } + uri := path.String() + if doc, ok := swaggerLoader.visitedDocuments[uri]; ok { + return doc, nil } swagger := &Swagger{} - swaggerLoader.visitedSwaggers[path.String()] = swagger + swaggerLoader.visitedDocuments[uri] = swagger if err := yaml.Unmarshal(data, swagger); err != nil { return nil, err @@ -188,8 +191,8 @@ func (swaggerLoader *SwaggerLoader) loadSwaggerFromDataWithPathInternal(data []b // ResolveRefsIn expands references if for instance spec was just unmarshalled func (swaggerLoader *SwaggerLoader) ResolveRefsIn(swagger *Swagger, path *url.URL) (err error) { - if swaggerLoader.visitedFiles == nil { - swaggerLoader.reset() + if swaggerLoader.visitedPathItemRefs == nil { + swaggerLoader.resetVisitedPathItemRefs() } // Visit all components @@ -863,10 +866,10 @@ func (swaggerLoader *SwaggerLoader) resolvePathItemRef(swagger *Swagger, entrypo key = documentPath.EscapedPath() } key += entrypoint - if _, ok := swaggerLoader.visitedFiles[key]; ok { + if _, ok := swaggerLoader.visitedPathItemRefs[key]; ok { return nil } - swaggerLoader.visitedFiles[key] = struct{}{} + swaggerLoader.visitedPathItemRefs[key] = struct{}{} const prefix = "#/paths/" if pathItem == nil { From f4b6ea23f373a47b2164c0a15178ff36b5ded164 Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Wed, 3 Mar 2021 18:32:50 +0100 Subject: [PATCH 5/6] more nits Signed-off-by: Pierre Fenoll --- openapi3/swagger_loader.go | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/openapi3/swagger_loader.go b/openapi3/swagger_loader.go index 292c7203e..3bb902dff 100644 --- a/openapi3/swagger_loader.go +++ b/openapi3/swagger_loader.go @@ -104,8 +104,7 @@ func (swaggerLoader *SwaggerLoader) loadSingleElementFromURI(ref string, rootPat } func (swaggerLoader *SwaggerLoader) readURL(location *url.URL) ([]byte, error) { - f := swaggerLoader.ReadFromURIFunc - if f != nil { + if f := swaggerLoader.ReadFromURIFunc; f != nil { return f(swaggerLoader, location) } @@ -114,21 +113,13 @@ func (swaggerLoader *SwaggerLoader) readURL(location *url.URL) ([]byte, error) { if err != nil { return nil, err } - data, err := ioutil.ReadAll(resp.Body) defer resp.Body.Close() - if err != nil { - return nil, err - } - return data, nil + return ioutil.ReadAll(resp.Body) } if location.Scheme != "" || location.Host != "" || location.RawQuery != "" { return nil, fmt.Errorf("unsupported URI: %q", location.String()) } - data, err := ioutil.ReadFile(location.Path) - if err != nil { - return nil, err - } - return data, nil + return ioutil.ReadFile(location.Path) } // LoadSwaggerFromFile loads a spec from a local file path @@ -153,11 +144,14 @@ func (swaggerLoader *SwaggerLoader) LoadSwaggerFromData(data []byte) (*Swagger, } func (swaggerLoader *SwaggerLoader) loadSwaggerFromDataInternal(data []byte) (*Swagger, error) { - swagger := &Swagger{} - if err := yaml.Unmarshal(data, swagger); err != nil { + doc := &Swagger{} + if err := yaml.Unmarshal(data, doc); err != nil { + return nil, err + } + if err := swaggerLoader.ResolveRefsIn(doc, nil); err != nil { return nil, err } - return swagger, swaggerLoader.ResolveRefsIn(swagger, nil) + return doc, nil } // LoadSwaggerFromDataWithPath takes the OpenApi spec data in bytes and a path where the resolver can find referred From d5e545530a3abe4bc1d85d5c6d08da34ac0a8a8e Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Wed, 3 Mar 2021 18:34:11 +0100 Subject: [PATCH 6/6] relocate a test Signed-off-by: Pierre Fenoll --- .../swagger_loader_read_from_uri_func_test.go | 50 +++++++++++++++++++ openapi3/swagger_loader_test.go | 49 ------------------ 2 files changed, 50 insertions(+), 49 deletions(-) diff --git a/openapi3/swagger_loader_read_from_uri_func_test.go b/openapi3/swagger_loader_read_from_uri_func_test.go index 3ac0ed74f..b15767855 100644 --- a/openapi3/swagger_loader_read_from_uri_func_test.go +++ b/openapi3/swagger_loader_read_from_uri_func_test.go @@ -1,6 +1,7 @@ package openapi3 import ( + "fmt" "io/ioutil" "net/url" "path/filepath" @@ -21,3 +22,52 @@ func TestLoaderReadFromURIFunc(t *testing.T) { require.NoError(t, doc.Validate(loader.Context)) require.Equal(t, "bar", doc.Paths["/foo"].Get.Responses.Get(200).Value.Content.Get("application/json").Schema.Value.Properties["foo"].Value.Properties["bar"].Value.Items.Value.Example) } + +type multipleSourceSwaggerLoaderExample struct { + Sources map[string][]byte +} + +func (l *multipleSourceSwaggerLoaderExample) LoadSwaggerFromURI( + loader *SwaggerLoader, + location *url.URL, +) ([]byte, error) { + source := l.resolveSourceFromURI(location) + if source == nil { + return nil, fmt.Errorf("Unsupported URI: %q", location.String()) + } + return source, nil +} + +func (l *multipleSourceSwaggerLoaderExample) resolveSourceFromURI(location fmt.Stringer) []byte { + return l.Sources[location.String()] +} + +func TestResolveSchemaExternalRef(t *testing.T) { + rootLocation := &url.URL{Scheme: "http", Host: "example.com", Path: "spec.json"} + externalLocation := &url.URL{Scheme: "http", Host: "example.com", Path: "external.json"} + rootSpec := []byte(fmt.Sprintf( + `{"openapi":"3.0.0","info":{"title":"MyAPI","version":"0.1","description":"An API"},"paths":{},"components":{"schemas":{"Root":{"allOf":[{"$ref":"%s#/components/schemas/External"}]}}}}`, + externalLocation.String(), + )) + externalSpec := []byte(`{"openapi":"3.0.0","info":{"title":"MyAPI","version":"0.1","description":"External Spec"},"paths":{},"components":{"schemas":{"External":{"type":"string"}}}}`) + multipleSourceLoader := &multipleSourceSwaggerLoaderExample{ + Sources: map[string][]byte{ + rootLocation.String(): rootSpec, + externalLocation.String(): externalSpec, + }, + } + loader := &SwaggerLoader{ + IsExternalRefsAllowed: true, + ReadFromURIFunc: multipleSourceLoader.LoadSwaggerFromURI, + } + + doc, err := loader.LoadSwaggerFromURI(rootLocation) + require.NoError(t, err) + + err = doc.Validate(loader.Context) + require.NoError(t, err) + + refRootVisited := doc.Components.Schemas["Root"].Value.AllOf[0] + require.Equal(t, fmt.Sprintf("%s#/components/schemas/External", externalLocation.String()), refRootVisited.Ref) + require.NotNil(t, refRootVisited.Value) +} diff --git a/openapi3/swagger_loader_test.go b/openapi3/swagger_loader_test.go index 9c7b3c54f..898ae9fe4 100644 --- a/openapi3/swagger_loader_test.go +++ b/openapi3/swagger_loader_test.go @@ -132,55 +132,6 @@ paths: require.Equal(t, example.Value.Value.(map[string]interface{})["error"].(bool), false) } -type multipleSourceSwaggerLoaderExample struct { - Sources map[string][]byte -} - -func (l *multipleSourceSwaggerLoaderExample) LoadSwaggerFromURI( - loader *SwaggerLoader, - location *url.URL, -) ([]byte, error) { - source := l.resolveSourceFromURI(location) - if source == nil { - return nil, fmt.Errorf("Unsupported URI: %q", location.String()) - } - return source, nil -} - -func (l *multipleSourceSwaggerLoaderExample) resolveSourceFromURI(location fmt.Stringer) []byte { - return l.Sources[location.String()] -} - -func TestResolveSchemaExternalRef(t *testing.T) { - rootLocation := &url.URL{Scheme: "http", Host: "example.com", Path: "spec.json"} - externalLocation := &url.URL{Scheme: "http", Host: "example.com", Path: "external.json"} - rootSpec := []byte(fmt.Sprintf( - `{"openapi":"3.0.0","info":{"title":"MyAPI","version":"0.1","description":"An API"},"paths":{},"components":{"schemas":{"Root":{"allOf":[{"$ref":"%s#/components/schemas/External"}]}}}}`, - externalLocation.String(), - )) - externalSpec := []byte(`{"openapi":"3.0.0","info":{"title":"MyAPI","version":"0.1","description":"External Spec"},"paths":{},"components":{"schemas":{"External":{"type":"string"}}}}`) - multipleSourceLoader := &multipleSourceSwaggerLoaderExample{ - Sources: map[string][]byte{ - rootLocation.String(): rootSpec, - externalLocation.String(): externalSpec, - }, - } - loader := &SwaggerLoader{ - IsExternalRefsAllowed: true, - ReadFromURIFunc: multipleSourceLoader.LoadSwaggerFromURI, - } - - doc, err := loader.LoadSwaggerFromURI(rootLocation) - require.NoError(t, err) - - err = doc.Validate(loader.Context) - require.NoError(t, err) - - refRootVisited := doc.Components.Schemas["Root"].Value.AllOf[0] - require.Equal(t, fmt.Sprintf("%s#/components/schemas/External", externalLocation.String()), refRootVisited.Ref) - require.NotNil(t, refRootVisited.Value) -} - func TestLoadErrorOnRefMisuse(t *testing.T) { spec := []byte(` openapi: '3.0.0'