Skip to content

Commit db52673

Browse files
authored
Correctly resolve path of yaml resource if double referenced. (#611)
1 parent fa5d9a9 commit db52673

File tree

7 files changed

+72
-9
lines changed

7 files changed

+72
-9
lines changed

openapi3/internalize_refs_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package openapi3
22

33
import (
44
"context"
5-
"io/ioutil"
5+
"os"
66
"regexp"
77
"testing"
88

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

44-
data, err := doc.MarshalJSON()
44+
actual, err := doc.MarshalJSON()
4545
require.NoError(t, err, "marshalling internalized spec")
4646

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

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

5959
// compare with expected
60-
data0, err := ioutil.ReadFile(test.filename + ".internalized.yml")
60+
expected, err := os.ReadFile(test.filename + ".internalized.yml")
6161
require.NoError(t, err)
62-
require.JSONEq(t, string(data), string(data0))
62+
require.JSONEq(t, string(expected), string(actual))
6363
})
6464
}
6565
}

openapi3/loader.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ type Loader struct {
3636

3737
Context context.Context
3838

39-
rootDir string
39+
rootDir string
40+
rootLocation string
4041

4142
visitedPathItemRefs map[string]struct{}
4243

@@ -148,6 +149,7 @@ func (loader *Loader) LoadFromDataWithPath(data []byte, location *url.URL) (*T,
148149
func (loader *Loader) loadFromDataWithPathInternal(data []byte, location *url.URL) (*T, error) {
149150
if loader.visitedDocuments == nil {
150151
loader.visitedDocuments = make(map[string]*T)
152+
loader.rootLocation = location.Path
151153
}
152154
uri := location.String()
153155
if doc, ok := loader.visitedDocuments[uri]; ok {
@@ -420,6 +422,11 @@ func (loader *Loader) documentPathForRecursiveRef(current *url.URL, resolvedRef
420422
if loader.rootDir == "" {
421423
return current
422424
}
425+
426+
if resolvedRef == "" {
427+
return &url.URL{Path: loader.rootLocation}
428+
}
429+
423430
return &url.URL{Path: path.Join(loader.rootDir, resolvedRef)}
424431
}
425432

openapi3/loader_recursive_ref_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ func TestLoaderSupportsRecursiveReference(t *testing.T) {
1414
err = doc.Validate(loader.Context)
1515
require.NoError(t, err)
1616
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)
17+
require.Equal(t, "ErrorDetails", doc.Paths["/foo"].Get.Responses.Get(400).Value.Content.Get("application/json").Schema.Value.Title)
18+
require.Equal(t, "ErrorDetails", doc.Paths["/double-ref-foo"].Get.Responses.Get(400).Value.Content.Get("application/json").Schema.Value.Title)
1719
}
1820

1921
func TestIssue447(t *testing.T) {
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
type: object
2+
title: ErrorDetails

openapi3/testdata/recursiveRef/openapi.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ info:
55
paths:
66
/foo:
77
$ref: ./paths/foo.yml
8+
/double-ref-foo:
9+
get:
10+
summary: Double ref response
11+
description: Reference response with double reference.
12+
responses:
13+
"400":
14+
$ref: "#/components/responses/400"
815
components:
916
schemas:
1017
Foo:
@@ -15,3 +22,12 @@ components:
1522
$ref: ./components/Bar.yml
1623
Cat:
1724
$ref: ./components/Cat.yml
25+
Error:
26+
$ref: ./components/models/error.yaml
27+
responses:
28+
"400":
29+
description: 400 Bad Request
30+
content:
31+
application/json:
32+
schema:
33+
$ref: "#/components/schemas/Error"

openapi3/testdata/recursiveRef/openapi.yml.internalized.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,27 @@
99
}
1010
}
1111
},
12+
"responses": {
13+
"400": {
14+
"content": {
15+
"application/json": {
16+
"schema": {
17+
"$ref": "#/components/schemas/Error"
18+
}
19+
}
20+
},
21+
"description": "400 Bad Request"
22+
}
23+
},
1224
"schemas": {
1325
"Bar": {
1426
"example": "bar",
1527
"type": "string"
1628
},
29+
"Error":{
30+
"title":"ErrorDetails",
31+
"type":"object"
32+
},
1733
"Foo": {
1834
"properties": {
1935
"bar": {
@@ -30,6 +46,10 @@
3046
},
3147
"type": "object"
3248
},
49+
"error":{
50+
"title":"ErrorDetails",
51+
"type":"object"
52+
},
3353
"Cat": {
3454
"properties": {
3555
"cat": {
@@ -46,6 +66,17 @@
4666
},
4767
"openapi": "3.0.3",
4868
"paths": {
69+
"/double-ref-foo": {
70+
"get": {
71+
"description": "Reference response with double reference.",
72+
"responses": {
73+
"400": {
74+
"$ref": "#/components/responses/400"
75+
}
76+
},
77+
"summary": "Double ref response"
78+
}
79+
},
4980
"/foo": {
5081
"get": {
5182
"responses": {
@@ -63,6 +94,9 @@
6394
}
6495
},
6596
"description": "OK"
97+
},
98+
"400": {
99+
"$ref": "#/components/responses/400"
66100
}
67101
}
68102
},

openapi3/testdata/recursiveRef/paths/foo.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ get:
1111
properties:
1212
foo2:
1313
$ref: ../openapi.yml#/components/schemas/Foo2
14+
"400":
15+
$ref: "../openapi.yml#/components/responses/400"

0 commit comments

Comments
 (0)