diff --git a/openapi3/callback.go b/openapi3/callback.go index 6246d6d8..62cea72d 100644 --- a/openapi3/callback.go +++ b/openapi3/callback.go @@ -26,7 +26,7 @@ func (c Callbacks) JSONLookup(token string) (interface{}, error) { } // Callback is specified by OpenAPI/Swagger standard version 3. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#callbackObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#callback-object type Callback map[string]*PathItem // Validate returns an error if Callback does not comply with the OpenAPI spec. diff --git a/openapi3/components.go b/openapi3/components.go index 16b39f30..8abc3fe9 100644 --- a/openapi3/components.go +++ b/openapi3/components.go @@ -10,7 +10,7 @@ import ( ) // Components is specified by OpenAPI/Swagger standard version 3. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#componentsObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#components-object type Components struct { ExtensionProps `json:"-" yaml:"-"` diff --git a/openapi3/discriminator.go b/openapi3/discriminator.go index 8eb29602..8ab344a8 100644 --- a/openapi3/discriminator.go +++ b/openapi3/discriminator.go @@ -7,7 +7,7 @@ import ( ) // Discriminator is specified by OpenAPI/Swagger standard version 3. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#discriminatorObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#discriminator-object type Discriminator struct { ExtensionProps `json:"-" yaml:"-"` diff --git a/openapi3/doc.go b/openapi3/doc.go index fc2735cb..41c9965c 100644 --- a/openapi3/doc.go +++ b/openapi3/doc.go @@ -1,4 +1,4 @@ // Package openapi3 parses and writes OpenAPI 3 specification documents. // -// See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md +// See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md package openapi3 diff --git a/openapi3/encoding.go b/openapi3/encoding.go index 082d3f2e..003833e1 100644 --- a/openapi3/encoding.go +++ b/openapi3/encoding.go @@ -9,7 +9,7 @@ import ( ) // Encoding is specified by OpenAPI/Swagger 3.0 standard. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#encodingObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#encoding-object type Encoding struct { ExtensionProps `json:"-" yaml:"-"` diff --git a/openapi3/example.go b/openapi3/example.go index e75d4d3d..f4cbfc07 100644 --- a/openapi3/example.go +++ b/openapi3/example.go @@ -28,7 +28,7 @@ func (e Examples) JSONLookup(token string) (interface{}, error) { } // Example is specified by OpenAPI/Swagger 3.0 standard. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#exampleObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#example-object type Example struct { ExtensionProps `json:"-" yaml:"-"` diff --git a/openapi3/header.go b/openapi3/header.go index aefaa06a..454fad51 100644 --- a/openapi3/header.go +++ b/openapi3/header.go @@ -28,7 +28,7 @@ func (h Headers) JSONLookup(token string) (interface{}, error) { } // Header is specified by OpenAPI/Swagger 3.0 standard. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#headerObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#header-object type Header struct { Parameter } diff --git a/openapi3/info.go b/openapi3/info.go index c67f73ab..72076095 100644 --- a/openapi3/info.go +++ b/openapi3/info.go @@ -8,7 +8,7 @@ import ( ) // Info is specified by OpenAPI/Swagger standard version 3. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#infoObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#info-object type Info struct { ExtensionProps `json:"-" yaml:"-"` @@ -58,7 +58,7 @@ func (info *Info) Validate(ctx context.Context, opts ...ValidationOption) error } // Contact is specified by OpenAPI/Swagger standard version 3. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#contactObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#contact-object type Contact struct { ExtensionProps `json:"-" yaml:"-"` @@ -85,7 +85,7 @@ func (contact *Contact) Validate(ctx context.Context, opts ...ValidationOption) } // License is specified by OpenAPI/Swagger standard version 3. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#licenseObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#license-object type License struct { ExtensionProps `json:"-" yaml:"-"` diff --git a/openapi3/link.go b/openapi3/link.go index 1040a040..137aef30 100644 --- a/openapi3/link.go +++ b/openapi3/link.go @@ -28,7 +28,7 @@ func (links Links) JSONLookup(token string) (interface{}, error) { var _ jsonpointer.JSONPointable = (*Links)(nil) // Link is specified by OpenAPI/Swagger standard version 3. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#linkObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#link-object type Link struct { ExtensionProps `json:"-" yaml:"-"` diff --git a/openapi3/media_type.go b/openapi3/media_type.go index 74c11b78..8e3fef7e 100644 --- a/openapi3/media_type.go +++ b/openapi3/media_type.go @@ -12,7 +12,7 @@ import ( ) // MediaType is specified by OpenAPI/Swagger 3.0 standard. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#mediaTypeObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#media-type-object type MediaType struct { ExtensionProps `json:"-" yaml:"-"` diff --git a/openapi3/openapi3.go b/openapi3/openapi3.go index 714f2803..d9506a9c 100644 --- a/openapi3/openapi3.go +++ b/openapi3/openapi3.go @@ -9,7 +9,7 @@ import ( ) // T is the root of an OpenAPI v3 document -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#oasObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#openapi-object type T struct { ExtensionProps `json:"-" yaml:"-"` diff --git a/openapi3/path_item.go b/openapi3/path_item.go index 5cba0a87..db83a0a5 100644 --- a/openapi3/path_item.go +++ b/openapi3/path_item.go @@ -10,7 +10,7 @@ import ( ) // PathItem is specified by OpenAPI/Swagger standard version 3. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#pathItemObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#path-item-object type PathItem struct { ExtensionProps `json:"-" yaml:"-"` diff --git a/openapi3/refs.go b/openapi3/refs.go index 7311c9d3..d36d562f 100644 --- a/openapi3/refs.go +++ b/openapi3/refs.go @@ -9,7 +9,7 @@ import ( ) // Ref is specified by OpenAPI/Swagger 3.0 standard. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#referenceObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#reference-object type Ref struct { Ref string `json:"$ref" yaml:"$ref"` } diff --git a/openapi3/request_body.go b/openapi3/request_body.go index 225c3d3c..baf7f81e 100644 --- a/openapi3/request_body.go +++ b/openapi3/request_body.go @@ -28,7 +28,7 @@ func (r RequestBodies) JSONLookup(token string) (interface{}, error) { } // RequestBody is specified by OpenAPI/Swagger 3.0 standard. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#requestBodyObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#request-body-object type RequestBody struct { ExtensionProps `json:"-" yaml:"-"` diff --git a/openapi3/response.go b/openapi3/response.go index d2f907d1..eaf8e57f 100644 --- a/openapi3/response.go +++ b/openapi3/response.go @@ -13,7 +13,7 @@ import ( ) // Responses is specified by OpenAPI/Swagger 3.0 standard. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#responsesObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#responses-object type Responses map[string]*ResponseRef var _ jsonpointer.JSONPointable = (*Responses)(nil) @@ -68,7 +68,7 @@ func (responses Responses) JSONLookup(token string) (interface{}, error) { } // Response is specified by OpenAPI/Swagger 3.0 standard. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#responseObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#response-object type Response struct { ExtensionProps `json:"-" yaml:"-"` diff --git a/openapi3/schema.go b/openapi3/schema.go index 67cc7dce..c5af8536 100644 --- a/openapi3/schema.go +++ b/openapi3/schema.go @@ -111,7 +111,7 @@ func (s SchemaRefs) JSONLookup(token string) (interface{}, error) { } // Schema is specified by OpenAPI/Swagger 3.0 standard. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#schemaObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#schema-object type Schema struct { ExtensionProps `json:"-" yaml:"-"` diff --git a/openapi3/security_requirements.go b/openapi3/security_requirements.go index dcdad0c4..3f5bd951 100644 --- a/openapi3/security_requirements.go +++ b/openapi3/security_requirements.go @@ -28,7 +28,7 @@ func (srs SecurityRequirements) Validate(ctx context.Context, opts ...Validation } // SecurityRequirement is specified by OpenAPI/Swagger standard version 3. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#securityRequirementObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#security-requirement-object type SecurityRequirement map[string][]string func NewSecurityRequirement() SecurityRequirement { diff --git a/openapi3/security_scheme.go b/openapi3/security_scheme.go index 2b3235df..83330f24 100644 --- a/openapi3/security_scheme.go +++ b/openapi3/security_scheme.go @@ -29,7 +29,7 @@ func (s SecuritySchemes) JSONLookup(token string) (interface{}, error) { var _ jsonpointer.JSONPointable = (*SecuritySchemes)(nil) // SecurityScheme is specified by OpenAPI/Swagger standard version 3. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#securitySchemeObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#security-scheme-object type SecurityScheme struct { ExtensionProps `json:"-" yaml:"-"` @@ -177,7 +177,7 @@ func (ss *SecurityScheme) Validate(ctx context.Context, opts ...ValidationOption } // OAuthFlows is specified by OpenAPI/Swagger standard version 3. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#oauthFlowsObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#oauth-flows-object type OAuthFlows struct { ExtensionProps `json:"-" yaml:"-"` @@ -234,7 +234,7 @@ func (flows *OAuthFlows) Validate(ctx context.Context, opts ...ValidationOption) } // OAuthFlow is specified by OpenAPI/Swagger standard version 3. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#oauthFlowObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#oauth-flow-object type OAuthFlow struct { ExtensionProps `json:"-" yaml:"-"` diff --git a/openapi3/security_scheme_test.go b/openapi3/security_scheme_test.go index 5958c533..48ea0460 100644 --- a/openapi3/security_scheme_test.go +++ b/openapi3/security_scheme_test.go @@ -30,7 +30,7 @@ func TestSecuritySchemaExample(t *testing.T) { } } -// from https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#fixed-fields-23 +// from https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#fixed-fields-23 var securitySchemeExamples = []securitySchemeExample{ { title: "Basic Authentication Sample", diff --git a/openapi3/server.go b/openapi3/server.go index 30479963..587e8e0e 100644 --- a/openapi3/server.go +++ b/openapi3/server.go @@ -50,7 +50,7 @@ func (servers Servers) MatchURL(parsedURL *url.URL) (*Server, []string, string) } // Server is specified by OpenAPI/Swagger standard version 3. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#serverObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#server-object type Server struct { ExtensionProps `json:"-" yaml:"-"` diff --git a/openapi3/tag.go b/openapi3/tag.go index f151e503..b5cb7f89 100644 --- a/openapi3/tag.go +++ b/openapi3/tag.go @@ -32,7 +32,7 @@ func (tags Tags) Validate(ctx context.Context, opts ...ValidationOption) error { } // Tag is specified by OpenAPI/Swagger 3.0 standard. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#tagObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#tag-object type Tag struct { ExtensionProps `json:"-" yaml:"-"` diff --git a/openapi3/xml.go b/openapi3/xml.go index 4ed3d94e..a55ff410 100644 --- a/openapi3/xml.go +++ b/openapi3/xml.go @@ -7,7 +7,7 @@ import ( ) // XML is specified by OpenAPI/Swagger standard version 3. -// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#xmlObject +// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#xml-object type XML struct { ExtensionProps `json:"-" yaml:"-"` diff --git a/openapi3filter/issue625_test.go b/openapi3filter/issue625_test.go index d9e5bae4..5642a7e0 100644 --- a/openapi3filter/issue625_test.go +++ b/openapi3filter/issue625_test.go @@ -72,7 +72,7 @@ paths: name: "failed allof object array", spec: allOfArraySpec, req: `/items?test=1.2,3.1`, - errStr: `parameter "test" in query has an error: Error at "/0": value "1.2" must be an integer`, + errStr: `parameter "test" in query has an error: path 0: value 1.2: an invalid integer: invalid syntax`, }, { name: "success oneof object array", diff --git a/openapi3filter/req_resp_decoder.go b/openapi3filter/req_resp_decoder.go index 52c65afa..870651ce 100644 --- a/openapi3filter/req_resp_decoder.go +++ b/openapi3filter/req_resp_decoder.go @@ -895,7 +895,14 @@ func parsePrimitive(raw string, schema *openapi3.SchemaRef) (interface{}, error) } switch schema.Value.Type { case "integer": - v, err := strconv.ParseFloat(raw, 64) + if schema.Value.Format == "int32" { + v, err := strconv.ParseInt(raw, 0, 32) + if err != nil { + return nil, &ParseError{Kind: KindInvalidFormat, Value: raw, Reason: "an invalid " + schema.Value.Type, Cause: err.(*strconv.NumError).Err} + } + return int32(v), nil + } + v, err := strconv.ParseInt(raw, 0, 64) if err != nil { return nil, &ParseError{Kind: KindInvalidFormat, Value: raw, Reason: "an invalid " + schema.Value.Type, Cause: err.(*strconv.NumError).Err} } diff --git a/openapi3filter/req_resp_decoder_test.go b/openapi3filter/req_resp_decoder_test.go index 8bd62b1c..709cdc92 100644 --- a/openapi3filter/req_resp_decoder_test.go +++ b/openapi3filter/req_resp_decoder_test.go @@ -175,7 +175,7 @@ func TestDecodeParameter(t *testing.T) { name: "integer", param: &openapi3.Parameter{Name: "param", In: "path", Schema: integerSchema}, path: "/1", - want: float64(1), + want: int64(1), found: true, }, { @@ -456,7 +456,7 @@ func TestDecodeParameter(t *testing.T) { name: "integer", param: &openapi3.Parameter{Name: "param", In: "query", Schema: integerSchema}, query: "param=1", - want: float64(1), + want: int64(1), found: true, }, { @@ -522,7 +522,7 @@ func TestDecodeParameter(t *testing.T) { name: "anyofSchema integer", param: &openapi3.Parameter{Name: "param", In: "query", Schema: anyofSchema}, query: "param=1", - want: float64(1), + want: int64(1), found: true, }, { @@ -548,7 +548,7 @@ func TestDecodeParameter(t *testing.T) { name: "oneofSchema int", param: &openapi3.Parameter{Name: "param", In: "query", Schema: oneofSchema}, query: "param=1122", - want: float64(1122), + want: int64(1122), found: true, }, { @@ -724,7 +724,7 @@ func TestDecodeParameter(t *testing.T) { name: "integer", param: &openapi3.Parameter{Name: "X-Param", In: "header", Schema: integerSchema}, header: "X-Param:1", - want: float64(1), + want: int64(1), found: true, }, { @@ -835,6 +835,13 @@ func TestDecodeParameter(t *testing.T) { want: map[string]interface{}{"id": "foo", "name": "bar"}, found: true, }, + { + name: "valid integer prop", + param: &openapi3.Parameter{Name: "X-Param", In: "header", Schema: integerSchema}, + header: "X-Param:88", + found: true, + want: int64(88), + }, { name: "invalid integer prop", param: &openapi3.Parameter{Name: "X-Param", In: "header", Schema: objectOf("foo", integerSchema)}, @@ -893,7 +900,7 @@ func TestDecodeParameter(t *testing.T) { name: "integer", param: &openapi3.Parameter{Name: "X-Param", In: "cookie", Schema: integerSchema}, cookie: "X-Param:1", - want: float64(1), + want: int64(1), found: true, }, { @@ -1180,7 +1187,7 @@ func TestDecodeBody(t *testing.T) { WithProperty("a", openapi3.NewStringSchema()). WithProperty("b", openapi3.NewIntegerSchema()). WithProperty("c", openapi3.NewArraySchema().WithItems(openapi3.NewStringSchema())), - want: map[string]interface{}{"a": "a1", "b": float64(10), "c": []interface{}{"c1", "c2"}}, + want: map[string]interface{}{"a": "a1", "b": int64(10), "c": []interface{}{"c1", "c2"}}, }, { name: "urlencoded space delimited", @@ -1193,7 +1200,7 @@ func TestDecodeBody(t *testing.T) { encoding: map[string]*openapi3.Encoding{ "c": {Style: openapi3.SerializationSpaceDelimited, Explode: boolPtr(false)}, }, - want: map[string]interface{}{"a": "a1", "b": float64(10), "c": []interface{}{"c1", "c2"}}, + want: map[string]interface{}{"a": "a1", "b": int64(10), "c": []interface{}{"c1", "c2"}}, }, { name: "urlencoded pipe delimited", @@ -1206,7 +1213,7 @@ func TestDecodeBody(t *testing.T) { encoding: map[string]*openapi3.Encoding{ "c": {Style: openapi3.SerializationPipeDelimited, Explode: boolPtr(false)}, }, - want: map[string]interface{}{"a": "a1", "b": float64(10), "c": []interface{}{"c1", "c2"}}, + want: map[string]interface{}{"a": "a1", "b": int64(10), "c": []interface{}{"c1", "c2"}}, }, { name: "multipart", diff --git a/routers/gorillamux/router.go b/routers/gorillamux/router.go index 811ba7d1..6977808e 100644 --- a/routers/gorillamux/router.go +++ b/routers/gorillamux/router.go @@ -57,8 +57,6 @@ func NewRouter(doc *openapi3.T) (routers.Router, error) { muxRouter := mux.NewRouter().UseEncodedPath() r := &Router{} for _, path := range orderedPaths(doc.Paths) { - servers := servers - pathItem := doc.Paths[path] if len(pathItem.Servers) > 0 { if servers, err = makeServers(pathItem.Servers); err != nil { @@ -140,19 +138,13 @@ func makeServers(in openapi3.Servers) ([]srv, error) { if lhs := strings.TrimSuffix(serverURL, server.Variables[sVar].Default); lhs != "" { varsUpdater = func(vars map[string]string) { vars[sVar] = lhs } } - servers = append(servers, srv{ - base: server.Variables[sVar].Default, - server: server, - varsUpdater: varsUpdater, - }) - continue - } + svr, err := newSrv(serverURL, server, varsUpdater) + if err != nil { + return nil, err + } - var schemes []string - if strings.Contains(serverURL, "://") { - scheme0 := strings.Split(serverURL, "://")[0] - schemes = permutePart(scheme0, server) - serverURL = strings.Replace(serverURL, scheme0+"://", schemes[0]+"://", 1) + servers = append(servers, svr) + continue } // If a variable represents the port "http://domain.tld:{port}/bla" @@ -172,21 +164,11 @@ func makeServers(in openapi3.Servers) ([]srv, error) { } } - u, err := url.Parse(bEncode(serverURL)) + svr, err := newSrv(serverURL, server, varsUpdater) if err != nil { return nil, err } - path := bDecode(u.EscapedPath()) - if len(path) > 0 && path[len(path)-1] == '/' { - path = path[:len(path)-1] - } - servers = append(servers, srv{ - host: bDecode(u.Host), //u.Hostname()? - base: path, - schemes: schemes, // scheme: []string{scheme0}, TODO: https://github.com/gorilla/mux/issues/624 - server: server, - varsUpdater: varsUpdater, - }) + servers = append(servers, svr) } if len(servers) == 0 { servers = append(servers, srv{}) @@ -195,6 +177,32 @@ func makeServers(in openapi3.Servers) ([]srv, error) { return servers, nil } +func newSrv(serverURL string, server *openapi3.Server, varsUpdater varsf) (srv, error) { + var schemes []string + if strings.Contains(serverURL, "://") { + scheme0 := strings.Split(serverURL, "://")[0] + schemes = permutePart(scheme0, server) + serverURL = strings.Replace(serverURL, scheme0+"://", schemes[0]+"://", 1) + } + + u, err := url.Parse(bEncode(serverURL)) + if err != nil { + return srv{}, err + } + path := bDecode(u.EscapedPath()) + if len(path) > 0 && path[len(path)-1] == '/' { + path = path[:len(path)-1] + } + svr := srv{ + host: bDecode(u.Host), //u.Hostname()? + base: path, + schemes: schemes, // scheme: []string{scheme0}, TODO: https://github.com/gorilla/mux/issues/624 + server: server, + varsUpdater: varsUpdater, + } + return svr, nil +} + func orderedPaths(paths map[string]*openapi3.PathItem) []string { // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#pathsObject // When matching URLs, concrete (non-templated) paths would be matched diff --git a/routers/gorillamux/router_test.go b/routers/gorillamux/router_test.go index 104056e1..3e744006 100644 --- a/routers/gorillamux/router_test.go +++ b/routers/gorillamux/router_test.go @@ -6,6 +6,7 @@ import ( "sort" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/getkin/kin-openapi/openapi3" @@ -249,7 +250,16 @@ func TestServerPath(t *testing.T) { "http://example.com:{port}/path", map[string]string{ "port": "8088", - })}, + }), + newServerWithVariables( + "{server}", + map[string]string{ + "server": "/", + }), + newServerWithVariables( + "/", + nil, + )}, }) require.NoError(t, err) } @@ -325,6 +335,157 @@ func TestRelativeURL(t *testing.T) { require.Equal(t, "/hello", route.Path) } +func Test_makeServers(t *testing.T) { + type testStruct struct { + name string + servers openapi3.Servers + want []srv + wantErr bool + initFn func(tt *testStruct) + } + tests := []testStruct{ + { + name: "server is root path", + servers: openapi3.Servers{ + newServerWithVariables("/", nil), + }, + want: []srv{{ + schemes: nil, + host: "", + base: "", + server: nil, + varsUpdater: nil, + }}, + wantErr: false, + initFn: func(tt *testStruct) { + for i, server := range tt.servers { + tt.want[i].server = server + } + }, + }, + { + name: "server with single variable that evaluates to root path", + servers: openapi3.Servers{ + newServerWithVariables("{server}", map[string]string{"server": "/"}), + }, + want: []srv{{ + schemes: nil, + host: "", + base: "", + server: nil, + varsUpdater: nil, + }}, + wantErr: false, + initFn: func(tt *testStruct) { + for i, server := range tt.servers { + tt.want[i].server = server + } + }, + }, + { + name: "server is http://localhost:28002", + servers: openapi3.Servers{ + newServerWithVariables("http://localhost:28002", nil), + }, + want: []srv{{ + schemes: []string{"http"}, + host: "localhost:28002", + base: "", + server: nil, + varsUpdater: nil, + }}, + wantErr: false, + initFn: func(tt *testStruct) { + for i, server := range tt.servers { + tt.want[i].server = server + } + }, + }, + { + name: "server with single variable that evaluates to http://localhost:28002", + servers: openapi3.Servers{ + newServerWithVariables("{server}", map[string]string{"server": "http://localhost:28002"}), + }, + want: []srv{{ + schemes: []string{"http"}, + host: "localhost:28002", + base: "", + server: nil, + varsUpdater: nil, + }}, + wantErr: false, + initFn: func(tt *testStruct) { + for i, server := range tt.servers { + tt.want[i].server = server + } + }, + }, + { + name: "server with multiple variables that evaluates to http://localhost:28002", + servers: openapi3.Servers{ + newServerWithVariables("{scheme}://{host}:{port}", map[string]string{"scheme": "http", "host": "localhost", "port": "28002"}), + }, + want: []srv{{ + schemes: []string{"http"}, + host: "{host}:28002", + base: "", + server: nil, + varsUpdater: func(vars map[string]string) { vars["port"] = "28002" }, + }}, + wantErr: false, + initFn: func(tt *testStruct) { + for i, server := range tt.servers { + tt.want[i].server = server + } + }, + }, + { + name: "server with unparsable URL fails", + servers: openapi3.Servers{ + newServerWithVariables("exam^ple.com:443", nil), + }, + want: nil, + wantErr: true, + initFn: nil, + }, + { + name: "server with single variable that evaluates to unparsable URL fails", + servers: openapi3.Servers{ + newServerWithVariables("{server}", map[string]string{"server": "exam^ple.com:443"}), + }, + want: nil, + wantErr: true, + initFn: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.initFn != nil { + tt.initFn(&tt) + } + got, err := makeServers(tt.servers) + if (err != nil) != tt.wantErr { + t.Errorf("makeServers() error = %v, wantErr %v", err, tt.wantErr) + return + } + assert.Equal(t, len(tt.want), len(got), "expected and actual servers lengths are not equal") + for i := 0; i < len(tt.want); i++ { + // Unfortunately using assert.Equals or reflect.DeepEquals isn't + // an option because function pointers cannot be compared + assert.Equal(t, tt.want[i].schemes, got[i].schemes) + assert.Equal(t, tt.want[i].host, got[i].host) + assert.Equal(t, tt.want[i].host, got[i].host) + assert.Equal(t, tt.want[i].server, got[i].server) + if tt.want[i].varsUpdater == nil { + assert.Nil(t, got[i].varsUpdater, "expected and actual varsUpdater should point to same function") + } else { + assert.NotNil(t, got[i].varsUpdater, "expected and actual varsUpdater should point to same function") + } + } + }) + } +} + func newServerWithVariables(url string, variables map[string]string) *openapi3.Server { var serverVariables = map[string]*openapi3.ServerVariable{}