Skip to content

Commit

Permalink
Correctly resolve path of yaml resource if double referenced.
Browse files Browse the repository at this point in the history
Where previously following path was resolved `testdata/components/models/error.yaml`, missing `recursiveRef` folder.
  • Loading branch information
d-sauer committed Sep 26, 2022
1 parent fa5d9a9 commit 9300b0d
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 9 deletions.
16 changes: 8 additions & 8 deletions openapi3/internalize_refs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package openapi3

import (
"context"
"io/ioutil"
"os"
"regexp"
"testing"

Expand Down Expand Up @@ -41,25 +41,25 @@ func TestInternalizeRefs(t *testing.T) {
err = doc.Validate(ctx)
require.NoError(t, err, "validating internalized spec")

data, err := doc.MarshalJSON()
actual, err := doc.MarshalJSON()
require.NoError(t, err, "marshalling internalized spec")

// run a static check over the file, making sure each occurence of a
// reference is followed by a #
numRefs := len(regexpRef.FindAll(data, -1))
numInternalRefs := len(regexpRefInternal.FindAll(data, -1))
numRefs := len(regexpRef.FindAll(actual, -1))
numInternalRefs := len(regexpRefInternal.FindAll(actual, -1))
require.Equal(t, numRefs, numInternalRefs, "checking all references are internal")

// load from data, but with the path set to the current directory
doc2, err := sl.LoadFromData(data)
// load from actual, but with the path set to the current directory
doc2, err := sl.LoadFromData(actual)
require.NoError(t, err, "reloading spec")
err = doc2.Validate(ctx)
require.NoError(t, err, "validating reloaded spec")

// compare with expected
data0, err := ioutil.ReadFile(test.filename + ".internalized.yml")
expected, err := os.ReadFile(test.filename + ".internalized.yml")
require.NoError(t, err)
require.JSONEq(t, string(data), string(data0))
require.JSONEq(t, string(expected), string(actual))
})
}
}
9 changes: 8 additions & 1 deletion openapi3/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ type Loader struct {

Context context.Context

rootDir string
rootDir string
rootLocation string

visitedPathItemRefs map[string]struct{}

Expand Down Expand Up @@ -148,6 +149,7 @@ func (loader *Loader) LoadFromDataWithPath(data []byte, location *url.URL) (*T,
func (loader *Loader) loadFromDataWithPathInternal(data []byte, location *url.URL) (*T, error) {
if loader.visitedDocuments == nil {
loader.visitedDocuments = make(map[string]*T)
loader.rootLocation = location.Path
}
uri := location.String()
if doc, ok := loader.visitedDocuments[uri]; ok {
Expand Down Expand Up @@ -420,6 +422,11 @@ func (loader *Loader) documentPathForRecursiveRef(current *url.URL, resolvedRef
if loader.rootDir == "" {
return current
}

if resolvedRef == "" {
return &url.URL{Path: loader.rootLocation}
}

return &url.URL{Path: path.Join(loader.rootDir, resolvedRef)}
}

Expand Down
2 changes: 2 additions & 0 deletions openapi3/loader_recursive_ref_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ func TestLoaderSupportsRecursiveReference(t *testing.T) {
err = doc.Validate(loader.Context)
require.NoError(t, err)
require.Equal(t, "bar", doc.Paths["/foo"].Get.Responses.Get(200).Value.Content.Get("application/json").Schema.Value.Properties["foo2"].Value.Properties["foo"].Value.Properties["bar"].Value.Example)
require.Equal(t, "ErrorDetails", doc.Paths["/foo"].Get.Responses.Get(400).Value.Content.Get("application/json").Schema.Value.Title)
require.Equal(t, "ErrorDetails", doc.Paths["/double-ref-foo"].Get.Responses.Get(400).Value.Content.Get("application/json").Schema.Value.Title)
}

func TestIssue447(t *testing.T) {
Expand Down
2 changes: 2 additions & 0 deletions openapi3/testdata/recursiveRef/components/models/error.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
type: object
title: ErrorDetails
16 changes: 16 additions & 0 deletions openapi3/testdata/recursiveRef/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ info:
paths:
/foo:
$ref: ./paths/foo.yml
/double-ref-foo:
get:
summary: Double ref response
description: Reference response with double reference.
responses:
"400":
$ref: "#/components/responses/400"
components:
schemas:
Foo:
Expand All @@ -15,3 +22,12 @@ components:
$ref: ./components/Bar.yml
Cat:
$ref: ./components/Cat.yml
Error:
$ref: ./components/models/error.yaml
responses:
"400":
description: 400 Bad Request
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
34 changes: 34 additions & 0 deletions openapi3/testdata/recursiveRef/openapi.yml.internalized.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,27 @@
}
}
},
"responses": {
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "400 Bad Request"
}
},
"schemas": {
"Bar": {
"example": "bar",
"type": "string"
},
"Error":{
"title":"ErrorDetails",
"type":"object"
},
"Foo": {
"properties": {
"bar": {
Expand All @@ -30,6 +46,10 @@
},
"type": "object"
},
"error":{
"title":"ErrorDetails",
"type":"object"
},
"Cat": {
"properties": {
"cat": {
Expand All @@ -46,6 +66,17 @@
},
"openapi": "3.0.3",
"paths": {
"/double-ref-foo": {
"get": {
"description": "Reference response with double reference.",
"responses": {
"400": {
"$ref": "#/components/responses/400"
}
},
"summary": "Double ref response"
}
},
"/foo": {
"get": {
"responses": {
Expand All @@ -63,6 +94,9 @@
}
},
"description": "OK"
},
"400": {
"$ref": "#/components/responses/400"
}
}
},
Expand Down
2 changes: 2 additions & 0 deletions openapi3/testdata/recursiveRef/paths/foo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ get:
properties:
foo2:
$ref: ../openapi.yml#/components/schemas/Foo2
"400":
$ref: "../openapi.yml#/components/responses/400"

0 comments on commit 9300b0d

Please sign in to comment.