Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: query param pattern #665

Merged
merged 4 commits into from Nov 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
109 changes: 109 additions & 0 deletions openapi3filter/issue641_test.go
@@ -0,0 +1,109 @@
package openapi3filter_test

import (
"net/http"
"strings"
"testing"

"github.com/stretchr/testify/require"

"github.com/getkin/kin-openapi/openapi3"
"github.com/getkin/kin-openapi/openapi3filter"
"github.com/getkin/kin-openapi/routers/gorillamux"
)

func TestIssue641(t *testing.T) {

anyOfSpec := `
openapi: 3.0.0
info:
version: 1.0.0
title: Sample API
paths:
/items:
get:
description: Returns a list of stuff
parameters:
- description: test object
explode: false
in: query
name: test
required: false
schema:
anyOf:
- pattern: "^[0-9]{1,4}$"
- pattern: "^[0-9]{1,4}$"
type: string
responses:
'200':
description: Successful response
`[1:]

allOfSpec := strings.ReplaceAll(anyOfSpec, "anyOf", "allOf")

tests := []struct {
name string
spec string
req string
errStr string
}{

{
name: "success anyof pattern",
spec: anyOfSpec,
req: "/items?test=51",
},
{
name: "failed anyof pattern",
spec: anyOfSpec,
req: "/items?test=999999",
errStr: `parameter "test" in query has an error: Doesn't match schema "anyOf"`,
},

{
name: "success allof pattern",
spec: allOfSpec,
req: `/items?test=51`,
},
{
name: "failed allof pattern",
spec: allOfSpec,
req: `/items?test=999999`,
errStr: `parameter "test" in query has an error: string doesn't match the regular expression`,
},
}

for _, testcase := range tests {
t.Run(testcase.name, func(t *testing.T) {
loader := openapi3.NewLoader()
ctx := loader.Context

doc, err := loader.LoadFromData([]byte(testcase.spec))
require.NoError(t, err)

err = doc.Validate(ctx)
require.NoError(t, err)

router, err := gorillamux.NewRouter(doc)
require.NoError(t, err)
httpReq, err := http.NewRequest(http.MethodGet, testcase.req, nil)
require.NoError(t, err)

route, pathParams, err := router.FindRoute(httpReq)
require.NoError(t, err)

requestValidationInput := &openapi3filter.RequestValidationInput{
Request: httpReq,
PathParams: pathParams,
Route: route,
}
err = openapi3filter.ValidateRequest(ctx, requestValidationInput)
if testcase.errStr == "" {
require.NoError(t, err)
} else {
require.Contains(t, err.Error(), testcase.errStr)
}
},
)
}
}
7 changes: 7 additions & 0 deletions openapi3filter/req_resp_decoder.go
Expand Up @@ -334,6 +334,9 @@ func decodeValue(dec valueDecoder, param string, sm *openapi3.SerializationMetho
case *pathParamDecoder:
_, found = vDecoder.pathParams[param]
case *urlValuesDecoder:
if schema.Value.Pattern != "" {
return dec.DecodePrimitive(param, sm, schema)
}
_, found = vDecoder.values[param]
case *headerParamDecoder:
_, found = vDecoder.header[param]
Expand Down Expand Up @@ -500,6 +503,10 @@ func (d *urlValuesDecoder) DecodePrimitive(param string, sm *openapi3.Serializat
// HTTP request does not contain a value of the target query parameter.
return nil, ok, nil
}

if schema.Value.Type == "" && schema.Value.Pattern != "" {
return values[0], ok, nil
}
val, err := parsePrimitive(values[0], schema)
return val, ok, err
}
Expand Down