Skip to content

Commit

Permalink
fix(filters): allow oneOf inside deepObject
Browse files Browse the repository at this point in the history
  • Loading branch information
Koumbaya committed Nov 21, 2023
1 parent a53cd59 commit 8f26aa6
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 0 deletions.
109 changes: 109 additions & 0 deletions openapi3filter/issue294_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package openapi3filter_test

import (
"github.com/getkin/kin-openapi/openapi3"
"github.com/getkin/kin-openapi/openapi3filter"
"github.com/getkin/kin-openapi/routers/gorillamux"
"github.com/stretchr/testify/require"
"net/http"
"testing"
)

func TestIssue294(t *testing.T) {

deepObjectSpec := `
openapi: 3.0.0
info:
version: 1.0.0
title: Sample API
paths:
/items:
get:
description: List documents in a collection
parameters:
- in: query
name: filter
required: false
style: deepObject
explode: true
schema:
type: object
properties:
id:
oneOf:
- oneOf:
- type: string
- type: object
title: StringFieldEqualsComparison
additionalProperties: false
properties:
eq:
type: string
required: [eq]
- oneOf:
- type: object
title: StringFieldOEQFilter
additionalProperties: false
properties:
oeq:
type: string
required: [oeq]
responses:
'200':
description: Documents in the collection
`
tests := []struct {
name string
req string
errStr string
}{
{
name: "success",
req: "/items?filter[id][eq]=1",
},
{
name: "success",
req: "/items?filter[id][oeq]=1,2",
},
{
name: "success",
req: "/items?filter[id]=1",
},
{
name: "success",
req: "/items?filter[id]=1",
},
}
for _, testcase := range tests {
t.Run(testcase.name, func(t *testing.T) {
loader := openapi3.NewLoader()
ctx := loader.Context

doc, err := loader.LoadFromData([]byte(deepObjectSpec))
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.ErrorContains(t, err, testcase.errStr)
}
})
}
}
8 changes: 8 additions & 0 deletions openapi3filter/req_resp_decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,14 @@ func parsePrimitive(raw string, schema *openapi3.SchemaRef) (interface{}, error)
case "string":
return raw, nil
default:
if len(schema.Value.OneOf) > 0 {
for i := range schema.Value.OneOf {
res, err := parsePrimitive(raw, schema.Value.OneOf[i])
if err == nil {
return res, nil
}
}
}
panic(fmt.Sprintf("schema has non primitive type %q", schema.Value.Type))
}
}
Expand Down

0 comments on commit 8f26aa6

Please sign in to comment.