Skip to content

Commit

Permalink
Fixed recurive reference resolving when property referencies local co… (
Browse files Browse the repository at this point in the history
#660)

Co-authored-by: Anton Tolokan <anton.tolokan@sbermarket.ru>
  • Loading branch information
derbylock and Anton Tolokan committed Nov 9, 2022
1 parent bd74bbf commit d89a84e
Show file tree
Hide file tree
Showing 12 changed files with 201 additions and 0 deletions.
4 changes: 4 additions & 0 deletions openapi3/loader.go
Expand Up @@ -748,6 +748,10 @@ func (loader *Loader) resolveSchemaRef(doc *T, component *SchemaRef, documentPat
}
documentPath = loader.documentPathForRecursiveRef(documentPath, foundPath)
}
if loader.visitedSchema == nil {
loader.visitedSchema = make(map[*Schema]struct{})
}
loader.visitedSchema[component.Value] = struct{}{}
}
value := component.Value
if value == nil {
Expand Down
23 changes: 23 additions & 0 deletions openapi3/loader_test.go
Expand Up @@ -263,6 +263,29 @@ func TestLoadWithReferenceInReference(t *testing.T) {
require.Equal(t, "string", doc.Paths["/api/test/ref/in/ref"].Post.RequestBody.Value.Content["application/json"].Schema.Value.Properties["definition_reference"].Value.Type)
}

func TestLoadWithRecursiveReferenceInLocalReferenceInParentSubdir(t *testing.T) {
loader := NewLoader()
loader.IsExternalRefsAllowed = true
doc, err := loader.LoadFromFile("testdata/refInLocalRefInParentsSubdir/spec/openapi.json")
require.NoError(t, err)
require.NotNil(t, doc)
err = doc.Validate(loader.Context)
require.NoError(t, err)
require.Equal(t, "object", doc.Paths["/api/test/ref/in/ref"].Post.RequestBody.Value.Content["application/json"].Schema.Value.Properties["definition_reference"].Value.Type)
}

func TestLoadWithRecursiveReferenceInRefrerenceInLocalReference(t *testing.T) {
loader := NewLoader()
loader.IsExternalRefsAllowed = true
doc, err := loader.LoadFromFile("testdata/refInLocalRef/openapi.json")
require.NoError(t, err)
require.NotNil(t, doc)
err = doc.Validate(loader.Context)
require.NoError(t, err)
require.Equal(t, "integer", doc.Paths["/api/test/ref/in/ref"].Post.RequestBody.Value.Content["application/json"].Schema.Value.Properties["data"].Value.Properties["definition_reference"].Value.Properties["ref_prop_part"].Value.Properties["idPart"].Value.Type)
require.Equal(t, "int64", doc.Paths["/api/test/ref/in/ref"].Post.RequestBody.Value.Content["application/json"].Schema.Value.Properties["data"].Value.Properties["definition_reference"].Value.Properties["ref_prop_part"].Value.Properties["idPart"].Value.Format)
}

func TestLoadWithReferenceInReferenceInProperty(t *testing.T) {
loader := NewLoader()
loader.IsExternalRefsAllowed = true
Expand Down
12 changes: 12 additions & 0 deletions openapi3/testdata/refInLocalRef/messages/data.json
@@ -0,0 +1,12 @@
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int32"
},
"ref_prop_part": {
"$ref": "./dataPart.json"
}
}
}
9 changes: 9 additions & 0 deletions openapi3/testdata/refInLocalRef/messages/dataPart.json
@@ -0,0 +1,9 @@
{
"type": "object",
"properties": {
"idPart": {
"type": "integer",
"format": "int64"
}
}
}
11 changes: 11 additions & 0 deletions openapi3/testdata/refInLocalRef/messages/request.json
@@ -0,0 +1,11 @@
{
"type": "object",
"required": [
"definition_reference"
],
"properties": {
"definition_reference": {
"$ref": "./data.json"
}
}
}
9 changes: 9 additions & 0 deletions openapi3/testdata/refInLocalRef/messages/response.json
@@ -0,0 +1,9 @@
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int32"
}
}
}
46 changes: 46 additions & 0 deletions openapi3/testdata/refInLocalRef/openapi.json
@@ -0,0 +1,46 @@
{
"openapi": "3.0.3",
"info": {
"title": "Reference in reference example",
"version": "1.0.0"
},
"paths": {
"/api/test/ref/in/ref": {
"post": {
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties" : {
"data": {
"$ref": "#/components/schemas/Request"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Successful response",
"content": {
"application/json": {
"schema": {
"$ref": "messages/response.json"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Request": {
"$ref": "messages/request.json"
}
}
}
}
12 changes: 12 additions & 0 deletions openapi3/testdata/refInLocalRefInParentsSubdir/messages/data.json
@@ -0,0 +1,12 @@
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int32"
},
"ref_prop_part": {
"$ref": "./dataPart.json"
}
}
}
@@ -0,0 +1,9 @@
{
"type": "object",
"properties": {
"idPart": {
"type": "integer",
"format": "int64"
}
}
}
@@ -0,0 +1,11 @@
{
"type": "object",
"required": [
"definition_reference"
],
"properties": {
"definition_reference": {
"$ref": "./data.json"
}
}
}
@@ -0,0 +1,9 @@
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int32"
}
}
}
46 changes: 46 additions & 0 deletions openapi3/testdata/refInLocalRefInParentsSubdir/spec/openapi.json
@@ -0,0 +1,46 @@
{
"openapi": "3.0.3",
"info": {
"title": "Reference in reference example",
"version": "1.0.0"
},
"paths": {
"/api/test/ref/in/ref": {
"post": {
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "../messages/request.json"
}
}
}
},
"responses": {
"200": {
"description": "Successful response",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"ref_prop": {
"$ref": "#/components/schemas/Data"
}
}
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Data": {
"$ref": "../messages/data.json"
}
}
}
}

0 comments on commit d89a84e

Please sign in to comment.