Skip to content

Commit

Permalink
reproduce and explore #495
Browse files Browse the repository at this point in the history
Signed-off-by: Pierre Fenoll <pierrefenoll@gmail.com>
  • Loading branch information
fenollp committed Nov 26, 2023
1 parent bd3ac0e commit 22a6c33
Show file tree
Hide file tree
Showing 34 changed files with 523 additions and 43 deletions.
26 changes: 26 additions & 0 deletions openapi2/marsh.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package openapi2

import (
"encoding/json"
"fmt"
"strings"

"github.com/invopop/yaml"
)

func unmarshalError(jsonUnmarshalErr error) error {
if before, after, found := strings.Cut(jsonUnmarshalErr.Error(), "Bis."); found && before != "" && after != "" {
before = strings.ReplaceAll(before, " Go struct ", " ")
return fmt.Errorf("%s.%s", before, after)
}
return jsonUnmarshalErr
}

func unmarshal(data []byte, v interface{}) error {
// See https://github.com/getkin/kin-openapi/issues/680
if err := json.Unmarshal(data, v); err != nil {
// UnmarshalStrict(data, v) TODO: investigate how ymlv3 handles duplicate map keys
return yaml.Unmarshal(data, v)
}
return nil
}
61 changes: 61 additions & 0 deletions openapi2/marsh_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package openapi2

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestUnmarshalError(t *testing.T) {
{
v2 := []byte(`
openapi: '2.0'
info:
version: '1.10'
title: title
paths:
"/ping":
post:
consumes:
- multipart/form-data
parameters:
name: file # <-- Missing dash
in: formData
description: file
required: true
type: file
responses:
'200':
description: OK
`[1:])

var doc T
err := unmarshal(v2, &doc)
require.ErrorContains(t, err, `json: cannot unmarshal object into field Operation.parameters of type openapi2.Parameters`)
}

v2 := []byte(`
openapi: '2.0'
info:
version: '1.10'
title: title
paths:
"/ping":
post:
consumes:
- multipart/form-data
parameters:
- name: file # <--
in: formData
description: file
required: true
type: file
responses:
'200':
description: OK
`[1:])

var doc T
err := unmarshal(v2, &doc)
require.NoError(t, err)
}
2 changes: 1 addition & 1 deletion openapi2/openapi2.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (doc *T) UnmarshalJSON(data []byte) error {
type TBis T
var x TBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "swagger")
Expand Down
2 changes: 1 addition & 1 deletion openapi2/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func (operation *Operation) UnmarshalJSON(data []byte) error {
type OperationBis Operation
var x OperationBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "summary")
Expand Down
2 changes: 1 addition & 1 deletion openapi2/parameter.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ func (parameter *Parameter) UnmarshalJSON(data []byte) error {
type ParameterBis Parameter
var x ParameterBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "$ref")
Expand Down
2 changes: 1 addition & 1 deletion openapi2/path_item.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (pathItem *PathItem) UnmarshalJSON(data []byte) error {
type PathItemBis PathItem
var x PathItemBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "$ref")
Expand Down
2 changes: 1 addition & 1 deletion openapi2/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (response *Response) UnmarshalJSON(data []byte) error {
type ResponseBis Response
var x ResponseBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "$ref")
Expand Down
2 changes: 1 addition & 1 deletion openapi2/security_scheme.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (securityScheme *SecurityScheme) UnmarshalJSON(data []byte) error {
type SecuritySchemeBis SecurityScheme
var x SecuritySchemeBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "$ref")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/components.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func (components *Components) UnmarshalJSON(data []byte) error {
type ComponentsBis Components
var x ComponentsBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "schemas")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/contact.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (contact *Contact) UnmarshalJSON(data []byte) error {
type ContactBis Contact
var x ContactBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "name")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/discriminator.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (discriminator *Discriminator) UnmarshalJSON(data []byte) error {
type DiscriminatorBis Discriminator
var x DiscriminatorBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "propertyName")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func (encoding *Encoding) UnmarshalJSON(data []byte) error {
type EncodingBis Encoding
var x EncodingBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "contentType")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (example *Example) UnmarshalJSON(data []byte) error {
type ExampleBis Example
var x ExampleBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "summary")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/external_docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (e *ExternalDocs) UnmarshalJSON(data []byte) error {
type ExternalDocsBis ExternalDocs
var x ExternalDocsBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "description")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (info *Info) UnmarshalJSON(data []byte) error {
type InfoBis Info
var x InfoBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "title")
Expand Down
157 changes: 157 additions & 0 deletions openapi3/issue495_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
package openapi3

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestIssue495(t *testing.T) {
{
spec := []byte(`
openapi: 3.0.1
info:
version: v1
title: Products api
components:
schemas:
someSchema:
type: object
schemaArray:
type: array
minItems: 1
items:
$ref: '#'
paths:
/categories:
get:
responses:
'200':
description: ''
content:
application/json:
schema:
properties:
allOf:
$ref: '#/components/schemas/schemaArray'
`[1:])

sl := NewLoader()

doc, err := sl.LoadFromData(spec)
require.NoError(t, err)

err = doc.Validate(sl.Context)
require.EqualError(t, err, `invalid components: schema "schemaArray": found unresolved ref: "#"`)
}

spec := []byte(`
openapi: 3.0.1
info:
version: v1
title: Products api
components:
schemas:
someSchema:
type: object
schemaArray:
type: array
minItems: 1
items:
$ref: '#/components/schemas/someSchema'
paths:
/categories:
get:
responses:
'200':
description: ''
content:
application/json:
schema:
properties:
allOf:
$ref: '#/components/schemas/schemaArray'
`[1:])

sl := NewLoader()

doc, err := sl.LoadFromData(spec)
require.NoError(t, err)

err = doc.Validate(sl.Context)
require.NoError(t, err)

require.Equal(t, &Schema{Type: "object"}, doc.Components.Schemas["schemaArray"].Value.Items.Value)
}

func TestIssue495WithDraft04(t *testing.T) {
spec := []byte(`
openapi: 3.0.1
servers:
- url: http://localhost:5000
info:
version: v1
title: Products api
contact:
name: me
email: me@github.com
description: This is a sample
paths:
/categories:
get:
summary: Provides the available categories for the store
operationId: list-categories
responses:
'200':
description: this is a desc
content:
application/json:
schema:
$ref: http://json-schema.org/draft-04/schema
`[1:])

sl := NewLoader()
sl.IsExternalRefsAllowed = true

doc, err := sl.LoadFromData(spec)
require.NoError(t, err)

err = doc.Validate(sl.Context)
require.ErrorContains(t, err, `found unresolved ref: "#"`)
}

func TestIssue495WithDraft04Bis(t *testing.T) {
spec := []byte(`
openapi: 3.0.1
servers:
- url: http://localhost:5000
info:
version: v1
title: Products api
contact:
name: me
email: me@github.com
description: This is a sample
paths:
/categories:
get:
summary: Provides the available categories for the store
operationId: list-categories
responses:
'200':
description: this is a desc
content:
application/json:
schema:
$ref: testdata/draft04.yml
`[1:])

sl := NewLoader()
sl.IsExternalRefsAllowed = true

doc, err := sl.LoadFromData(spec)
require.NoError(t, err)

err = doc.Validate(sl.Context)
require.ErrorContains(t, err, `found unresolved ref: "#"`)
}
2 changes: 1 addition & 1 deletion openapi3/license.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (license *License) UnmarshalJSON(data []byte) error {
type LicenseBis License
var x LicenseBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "name")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/link.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (link *Link) UnmarshalJSON(data []byte) error {
type LinkBis Link
var x LinkBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "operationRef")
Expand Down
Loading

0 comments on commit 22a6c33

Please sign in to comment.