Skip to content

Commit

Permalink
Adds oneOf/discriminator/mapping management (getkin#321)
Browse files Browse the repository at this point in the history
  • Loading branch information
riccardomanfrin authored Mar 8, 2021
1 parent 96aeb23 commit 1286d06
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 1 deletion.
14 changes: 13 additions & 1 deletion openapi3/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,19 @@ func (schema *Schema) visitSetOperations(settings *schemaValidationSettings, val
err := v.visitJSON(settings, value)
settings.failfast = oldfailfast
if err == nil {
ok++
if schema.Discriminator != nil {
pn := schema.Discriminator.PropertyName
if valuemap, okcheck := value.(map[string]interface{}); okcheck {
if discriminatorVal, okcheck := valuemap[pn]; okcheck == true {
mapref, okcheck := schema.Discriminator.Mapping[discriminatorVal.(string)]
if okcheck && mapref == item.Ref {
ok++
}
}
}
} else {
ok++
}
}
}
if ok != 1 {
Expand Down
98 changes: 98 additions & 0 deletions openapi3filter/validation_discriminator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package openapi3filter

import (
"bytes"
"context"
"net/http"
"testing"

"github.com/getkin/kin-openapi/openapi3"
"github.com/stretchr/testify/require"
)

var yaJsonSpecWithDiscriminator = []byte(`
openapi: 3.0.0
info:
version: 0.2.0
title: yaAPI
paths:
/blob:
put:
operationId: SetObj
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/blob'
responses:
'200':
description: Ok
components:
schemas:
blob:
oneOf:
- $ref: '#/components/schemas/objA'
- $ref: '#/components/schemas/objB'
discriminator:
propertyName: discr
mapping:
objA: '#/components/schemas/objA'
objB: '#/components/schemas/objB'
genericObj:
type: object
required:
- discr
properties:
discr:
type: string
enum:
- objA
- objB
discriminator:
propertyName: discr
mapping:
objA: '#/components/schemas/objA'
objB: '#/components/schemas/objB'
objA:
allOf:
- $ref: '#/components/schemas/genericObj'
- type: object
properties:
base64:
type: string
objB:
allOf:
- $ref: '#/components/schemas/genericObj'
- type: object
properties:
value:
type: integer
`)

func forgeRequest(body string) *http.Request {
iobody := bytes.NewReader([]byte(body))
req, _ := http.NewRequest("PUT", "/blob", iobody)
req.Header.Add("Content-Type", "application/json")
return req
}

func TestValidationWithDiscriminatorSelection(t *testing.T) {
openapi, err := openapi3.NewSwaggerLoader().LoadSwaggerFromData(yaJsonSpecWithDiscriminator)
require.NoError(t, err)
router := NewRouter().WithSwagger(openapi)
req := forgeRequest(`{"discr": "objA", "base64": "S25vY2sgS25vY2ssIE5lbyAuLi4="}`)
route, pathParams, _ := router.FindRoute(req.Method, req.URL)
requestValidationInput := &RequestValidationInput{
Request: req,
PathParams: pathParams,
Route: route,
}
ctx := context.Background()
err = ValidateRequest(ctx, requestValidationInput)
require.NoError(t, err)
}

0 comments on commit 1286d06

Please sign in to comment.