Skip to content

Commit

Permalink
Preserve existing media type value during response parsing (#118)
Browse files Browse the repository at this point in the history
  • Loading branch information
vearutop authored Jun 25, 2024
1 parent 28402d8 commit ff01e36
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 14 deletions.
11 changes: 4 additions & 7 deletions openapi3/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -717,13 +717,10 @@ func (r *Reflector) parseJSONResponse(resp *Response, oc openapi.OperationContex
contentType = mimeJSON
}

resp.Content[contentType] = MediaType{
Schema: &oaiSchema,
Example: nil,
Examples: nil,
Encoding: nil,
MapOfAnything: nil,
}
mt := resp.Content[contentType]
mt.Schema = &oaiSchema

resp.Content[contentType] = mt

if sch.Description != nil && resp.Description == "" {
resp.Description = *sch.Description
Expand Down
89 changes: 89 additions & 0 deletions openapi3/reflect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1209,3 +1209,92 @@ func TestReflector_AddOperation_jsonschemaStruct(t *testing.T) {
}
}`, r.SpecSchema())
}

func TestNewReflector_examples(t *testing.T) {
r := openapi3.NewReflector()

op, err := r.NewOperationContext(http.MethodGet, "/")
require.NoError(t, err)

type O1 struct {
F1 int `json:"f1,omitempty"`
Code string `json:"code"`
}

type O2 struct {
F2 int `json:"f2,omitempty"`
Code string `json:"code"`
}

st := http.StatusCreated

op.AddRespStructure(jsonschema.OneOf(O1{}, O2{}), func(cu *openapi.ContentUnit) {
cu.HTTPStatus = st
})

if o3, ok := op.(openapi3.OperationExposer); ok {
c := openapi3.MediaType{}
c.Examples = map[string]openapi3.ExampleOrRef{
"responseOne": {
Example: (&openapi3.Example{}).WithSummary("First possible answer").WithValue(O1{Code: "1234567890123456789012"}),
},
"responseTwo": {
Example: (&openapi3.Example{}).WithSummary("Other possible answer").WithValue(O2{Code: "0000000000000000000000"}),
},
}
resp := openapi3.Response{}
resp.WithContentItem("application/json", c)

o3.Operation().Responses.WithMapOfResponseOrRefValuesItem(strconv.Itoa(st), openapi3.ResponseOrRef{
Response: &resp,
})
}

require.NoError(t, r.AddOperation(op))
assertjson.EqMarshal(t, `{
"openapi":"3.0.3","info":{"title":"","version":""},
"paths":{
"/":{
"get":{
"responses":{
"201":{
"description":"Created",
"content":{
"application/json":{
"schema":{
"oneOf":[
{"$ref":"#/components/schemas/Openapi3TestO1"},
{"$ref":"#/components/schemas/Openapi3TestO2"}
]
},
"examples":{
"responseOne":{
"summary":"First possible answer",
"value":{"code":"1234567890123456789012"}
},
"responseTwo":{
"summary":"Other possible answer",
"value":{"code":"0000000000000000000000"}
}
}
}
}
}
}
}
}
},
"components":{
"schemas":{
"Openapi3TestO1":{
"type":"object",
"properties":{"code":{"type":"string"},"f1":{"type":"integer"}}
},
"Openapi3TestO2":{
"type":"object",
"properties":{"code":{"type":"string"},"f2":{"type":"integer"}}
}
}
}
}`, r.SpecSchema())
}
11 changes: 4 additions & 7 deletions openapi31/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -666,13 +666,10 @@ func (r *Reflector) parseJSONResponse(resp *Response, oc openapi.OperationContex
contentType = mimeJSON
}

resp.Content[contentType] = MediaType{
Schema: sm,
Example: nil,
Examples: nil,
Encoding: nil,
MapOfAnything: nil,
}
mt := resp.Content[contentType]
mt.Schema = sm

resp.Content[contentType] = mt

if sch.Description != nil && resp.Description == "" {
resp.Description = *sch.Description
Expand Down
89 changes: 89 additions & 0 deletions openapi31/reflect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1337,3 +1337,92 @@ func TestReflector_AddOperation_jsonschemaStruct(t *testing.T) {
}
}`, r.SpecSchema())
}

func TestNewReflector_examples(t *testing.T) {
r := openapi31.NewReflector()

op, err := r.NewOperationContext(http.MethodGet, "/")
require.NoError(t, err)

type O1 struct {
F1 int `json:"f1,omitempty"`
Code string `json:"code"`
}

type O2 struct {
F2 int `json:"f2,omitempty"`
Code string `json:"code"`
}

st := http.StatusCreated

op.AddRespStructure(jsonschema.OneOf(O1{}, O2{}), func(cu *openapi.ContentUnit) {
cu.HTTPStatus = st
})

if o3, ok := op.(openapi31.OperationExposer); ok {
c := openapi31.MediaType{}
c.Examples = map[string]openapi31.ExampleOrReference{
"responseOne": {
Example: (&openapi31.Example{}).WithSummary("First possible answer").WithValue(O1{Code: "1234567890123456789012"}),
},
"responseTwo": {
Example: (&openapi31.Example{}).WithSummary("Other possible answer").WithValue(O2{Code: "0000000000000000000000"}),
},
}
resp := openapi31.Response{}
resp.WithContentItem("application/json", c)

o3.Operation().ResponsesEns().WithMapOfResponseOrReferenceValuesItem(strconv.Itoa(st), openapi31.ResponseOrReference{
Response: &resp,
})
}

require.NoError(t, r.AddOperation(op))
assertjson.EqMarshal(t, `{
"openapi":"3.1.0","info":{"title":"","version":""},
"paths":{
"/":{
"get":{
"responses":{
"201":{
"description":"Created",
"content":{
"application/json":{
"schema":{
"oneOf":[
{"$ref":"#/components/schemas/Openapi31TestO1"},
{"$ref":"#/components/schemas/Openapi31TestO2"}
]
},
"examples":{
"responseOne":{
"summary":"First possible answer",
"value":{"code":"1234567890123456789012"}
},
"responseTwo":{
"summary":"Other possible answer",
"value":{"code":"0000000000000000000000"}
}
}
}
}
}
}
}
}
},
"components":{
"schemas":{
"Openapi31TestO1":{
"properties":{"code":{"type":"string"},"f1":{"type":"integer"}},
"type":"object"
},
"Openapi31TestO2":{
"properties":{"code":{"type":"string"},"f2":{"type":"integer"}},
"type":"object"
}
}
}
}`, r.SpecSchema())
}

0 comments on commit ff01e36

Please sign in to comment.