Skip to content

Commit

Permalink
Merge pull request go-openapi#166 from Aven30/fix-spec-parser-ignorin…
Browse files Browse the repository at this point in the history
…g-response-entries-with-ext-165

Fix go-openapi#165
  • Loading branch information
casualjim authored Apr 22, 2023
2 parents df35a52 + f85abf4 commit 7ee5140
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 7 deletions.
27 changes: 20 additions & 7 deletions responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"fmt"
"reflect"
"strconv"
"strings"

"github.com/go-openapi/swag"
)
Expand Down Expand Up @@ -62,6 +63,7 @@ func (r *Responses) UnmarshalJSON(data []byte) error {
if err := json.Unmarshal(data, &r.ResponsesProps); err != nil {
return err
}

if err := json.Unmarshal(data, &r.VendorExtensible); err != nil {
return err
}
Expand Down Expand Up @@ -107,20 +109,31 @@ func (r ResponsesProps) MarshalJSON() ([]byte, error) {

// UnmarshalJSON unmarshals responses from JSON
func (r *ResponsesProps) UnmarshalJSON(data []byte) error {
var res map[string]Response
var res map[string]json.RawMessage
if err := json.Unmarshal(data, &res); err != nil {
return nil
return err
}

if v, ok := res["default"]; ok {
r.Default = &v
var defaultRes Response
if err := json.Unmarshal(v, &defaultRes); err != nil {
return err
}
r.Default = &defaultRes
delete(res, "default")
}
for k, v := range res {
if nk, err := strconv.Atoi(k); err == nil {
if r.StatusCodeResponses == nil {
r.StatusCodeResponses = map[int]Response{}
if !strings.HasPrefix(k, "x-") {
var statusCodeResp Response
if err := json.Unmarshal(v, &statusCodeResp); err != nil {
return err
}
if nk, err := strconv.Atoi(k); err == nil {
if r.StatusCodeResponses == nil {
r.StatusCodeResponses = map[int]Response{}
}
r.StatusCodeResponses[nk] = statusCodeResp
}
r.StatusCodeResponses[nk] = v
}
}
return nil
Expand Down
133 changes: 133 additions & 0 deletions responses_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// Copyright 2017 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package spec

import (
"encoding/json"
"testing"

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

var responses = Responses{
VendorExtensible: VendorExtensible{
Extensions: map[string]interface{}{
"x-go-name": "PutDogExists",
},
},
ResponsesProps: ResponsesProps{
StatusCodeResponses: map[int]Response{
200: {
Refable: Refable{Ref: MustCreateRef("Dog")},
VendorExtensible: VendorExtensible{
Extensions: map[string]interface{}{
"x-go-name": "PutDogExists",
},
},
ResponseProps: ResponseProps{
Description: "Dog exists",
Schema: &Schema{SchemaProps: SchemaProps{Type: []string{"string"}}},
},
},
},
},
}

const responsesJSON = `{
"x-go-name": "PutDogExists",
"200": {
"$ref": "Dog",
"x-go-name": "PutDogExists",
"description": "Dog exists",
"schema": {
"type": "string"
}
}
}`

func TestIntegrationResponses(t *testing.T) {
var actual Responses
if assert.NoError(t, json.Unmarshal([]byte(responsesJSON), &actual)) {
assert.EqualValues(t, actual, responses)
}

assertParsesJSON(t, responsesJSON, responses)
}

func TestJSONLookupResponses(t *testing.T) {
resp200, ok := responses.StatusCodeResponses[200]
if !assert.True(t, ok) {
t.FailNow()
return
}

res, err := resp200.JSONLookup("$ref")
if !assert.NoError(t, err) {
t.FailNow()
return
}
if assert.IsType(t, &Ref{}, res) {
ref := res.(*Ref)
assert.EqualValues(t, MustCreateRef("Dog"), *ref)
}

var def string
res, err = resp200.JSONLookup("description")
if !assert.NoError(t, err) || !assert.NotNil(t, res) || !assert.IsType(t, def, res) {
t.FailNow()
return
}
def = res.(string)
assert.Equal(t, "Dog exists", def)

var x *interface{}
res, err = responses.JSONLookup("x-go-name")
if !assert.NoError(t, err) || !assert.NotNil(t, res) || !assert.IsType(t, x, res) {
t.FailNow()
return
}

x = res.(*interface{})
assert.EqualValues(t, "PutDogExists", *x)

res, err = responses.JSONLookup("unknown")
if !assert.Error(t, err) || !assert.Nil(t, res) {
t.FailNow()
return
}
}

func TestResponsesBuild(t *testing.T) {
resp := NewResponse().
WithDescription("some response").
WithSchema(new(Schema).Typed("object", "")).
AddHeader("x-header", ResponseHeader().Typed("string", "")).
AddExample("application/json", `{"key":"value"}`)
jazon, _ := json.MarshalIndent(resp, "", " ")
assert.JSONEq(t, `{
"description": "some response",
"schema": {
"type": "object"
},
"headers": {
"x-header": {
"type": "string"
}
},
"examples": {
"application/json": "{\"key\":\"value\"}"
}
}`, string(jazon))
}

0 comments on commit 7ee5140

Please sign in to comment.