add test, fix RemoteURLHandler field name

This commit is contained in:
Federico Bevione
2023-06-23 14:43:48 +02:00
committed by quobix
parent c99d552d9e
commit 572130c666
8 changed files with 6626 additions and 23 deletions

6542
coverage.out Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -18,9 +18,9 @@ type DocumentConfiguration struct {
// Schema must be set to "http/https". // Schema must be set to "http/https".
BaseURL *url.URL BaseURL *url.URL
// RemoteDocumentGetter is a function that will be used to retrieve remote documents. If not set, the default // RemoteURLHandler is a function that will be used to retrieve remote documents. If not set, the default
// remote document getter will be used. // remote document getter will be used.
RemoteDocumentGetter func(url string) (*http.Response, error) RemoteURLHandler func(url string) (*http.Response, error)
// If resolving locally, the BasePath will be the root from which relative references will be resolved from. // If resolving locally, the BasePath will be the root from which relative references will be resolved from.
// It's usually the location of the root specification. // It's usually the location of the root specification.

View File

@@ -144,7 +144,7 @@ func createDocument(info *datamodel.SpecInfo, config *datamodel.DocumentConfigur
// build an index // build an index
idx := index.NewSpecIndexWithConfig(info.RootNode, &index.SpecIndexConfig{ idx := index.NewSpecIndexWithConfig(info.RootNode, &index.SpecIndexConfig{
BaseURL: config.BaseURL, BaseURL: config.BaseURL,
RemoteDocumentGetter: config.RemoteDocumentGetter, RemoteURLHandler: config.RemoteURLHandler,
AllowRemoteLookup: config.AllowRemoteReferences, AllowRemoteLookup: config.AllowRemoteReferences,
AllowFileLookup: config.AllowFileReferences, AllowFileLookup: config.AllowFileReferences,
}) })

View File

@@ -6,11 +6,12 @@ package v3
import ( import (
"crypto/sha256" "crypto/sha256"
"fmt" "fmt"
"sort"
"strings"
"github.com/pb33f/libopenapi/datamodel/low" "github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index" "github.com/pb33f/libopenapi/index"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"sort"
"strings"
) )
// Callback represents a low-level Callback object for OpenAPI 3+. // Callback represents a low-level Callback object for OpenAPI 3+.

View File

@@ -49,7 +49,7 @@ func createDocument(info *datamodel.SpecInfo, config *datamodel.DocumentConfigur
// build an index // build an index
idx := index.NewSpecIndexWithConfig(info.RootNode, &index.SpecIndexConfig{ idx := index.NewSpecIndexWithConfig(info.RootNode, &index.SpecIndexConfig{
BaseURL: config.BaseURL, BaseURL: config.BaseURL,
RemoteDocumentGetter: config.RemoteDocumentGetter, RemoteURLHandler: config.RemoteURLHandler,
BasePath: cwd, BasePath: cwd,
AllowFileLookup: config.AllowFileReferences, AllowFileLookup: config.AllowFileReferences,
AllowRemoteLookup: config.AllowRemoteReferences, AllowRemoteLookup: config.AllowRemoteReferences,

View File

@@ -88,9 +88,9 @@ func (index *SpecIndex) FindComponent(componentId string, parent *yaml.Node) *Re
var httpClient = &http.Client{Timeout: time.Duration(60) * time.Second} var httpClient = &http.Client{Timeout: time.Duration(60) * time.Second}
type RemoteDocumentGetter = func(url string) (*http.Response, error) type RemoteURLHandler = func(url string) (*http.Response, error)
func getRemoteDoc(g RemoteDocumentGetter, u string, d chan []byte, e chan error) { func getRemoteDoc(g RemoteURLHandler, u string, d chan []byte, e chan error) {
resp, err := g(u) resp, err := g(u)
if err != nil { if err != nil {
e <- err e <- err
@@ -124,9 +124,9 @@ func (index *SpecIndex) lookupRemoteReference(ref string) (*yaml.Node, *yaml.Nod
go func(uri string) { go func(uri string) {
bc := make(chan []byte) bc := make(chan []byte)
ec := make(chan error) ec := make(chan error)
var getter RemoteDocumentGetter = httpClient.Get var getter RemoteURLHandler = httpClient.Get
if index.config != nil && index.config.RemoteDocumentGetter != nil { if index.config != nil && index.config.RemoteURLHandler != nil {
getter = index.config.RemoteDocumentGetter getter = index.config.RemoteURLHandler
} }
go getRemoteDoc(getter, uri, bc, ec) go getRemoteDoc(getter, uri, bc, ec)
select { select {

View File

@@ -4,10 +4,14 @@
package index package index
import ( import (
"net/http"
"net/http/httptest"
"os"
"reflect"
"testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"os"
"testing"
) )
func TestSpecIndex_performExternalLookup(t *testing.T) { func TestSpecIndex_performExternalLookup(t *testing.T) {
@@ -143,3 +147,59 @@ paths:
assert.Equal(t, "query", crsParam.Node.Content[3].Value) assert.Equal(t, "query", crsParam.Node.Content[3].Value)
assert.Equal(t, "form", crsParam.Node.Content[9].Value) assert.Equal(t, "form", crsParam.Node.Content[9].Value)
} }
func TestSpecIndex_LocateRemoteDocsWithRemoteURLHandler(t *testing.T) {
// This test will push the index to do try and locate remote references that use relative references
spec := `openapi: 3.0.2
info:
title: Test
version: 1.0.0
paths:
/test:
get:
parameters:
- $ref: "https://schemas.opengis.net/ogcapi/features/part2/1.0/openapi/ogcapi-features-2.yaml#/components/parameters/crs"`
var rootNode yaml.Node
_ = yaml.Unmarshal([]byte(spec), &rootNode)
c := CreateOpenAPIIndexConfig()
c.RemoteURLHandler = httpClient.Get
index := NewSpecIndexWithConfig(&rootNode, c)
// extract crs param from index
crsParam := index.GetMappedReferences()["https://schemas.opengis.net/ogcapi/features/part2/1.0/openapi/ogcapi-features-2.yaml#/components/parameters/crs"]
assert.NotNil(t, crsParam)
assert.True(t, crsParam.IsRemote)
assert.Equal(t, "crs", crsParam.Node.Content[1].Value)
assert.Equal(t, "query", crsParam.Node.Content[3].Value)
assert.Equal(t, "form", crsParam.Node.Content[9].Value)
}
func TestGetRemoteDoc(t *testing.T) {
// Mock HTTP server
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Write([]byte(`OK`))
}))
// Close the server when test finishes
defer server.Close()
// Channel for data and error
dataChan := make(chan []byte)
errorChan := make(chan error)
go getRemoteDoc(http.Get, server.URL, dataChan, errorChan)
data := <-dataChan
err := <-errorChan
if err != nil {
t.Errorf("Expected no error, got %v", err)
}
expectedData := []byte(`OK`)
if !reflect.DeepEqual(data, expectedData) {
t.Errorf("Expected %v, got %v", expectedData, data)
}
}

View File

@@ -61,9 +61,9 @@ type SpecIndexConfig struct {
// More details on relative references can be found in issue #73: https://github.com/pb33f/libopenapi/issues/73 // More details on relative references can be found in issue #73: https://github.com/pb33f/libopenapi/issues/73
BaseURL *url.URL // set the Base URL for resolving relative references if the spec is exploded. BaseURL *url.URL // set the Base URL for resolving relative references if the spec is exploded.
// If resolving remotely, the RemoteDocumentGetter will be used to fetch the remote document. // If resolving remotely, the RemoteURLHandler will be used to fetch the remote document.
// If not set, the default http client will be used. // If not set, the default http client will be used.
RemoteDocumentGetter func(url string) (*http.Response, error) RemoteURLHandler func(url string) (*http.Response, error)
// If resolving locally, the BasePath will be the root from which relative references will be resolved from // If resolving locally, the BasePath will be the root from which relative references will be resolved from
BasePath string // set the Base Path for resolving relative references if the spec is exploded. BasePath string // set the Base Path for resolving relative references if the spec is exploded.