Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix second level relative ref in property resolving #622

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions openapi3/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,10 @@ func (loader *Loader) resolveSchemaRef(doc *T, component *SchemaRef, documentPat
func (loader *Loader) getResolvedRefPath(ref string, resolved *SchemaRef, cur, found *url.URL) string {
if referencedFilename := strings.Split(ref, "#")[0]; referencedFilename == "" {
if cur != nil {
if loader.rootDir != "" && strings.HasPrefix(cur.Path, loader.rootDir) {
return cur.Path[len(loader.rootDir)+1:]
}

return path.Base(cur.Path)
}
return ""
Expand Down
11 changes: 11 additions & 0 deletions openapi3/loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,17 @@ 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 TestLoadWithReferenceInReferenceInProperty(t *testing.T) {
loader := NewLoader()
loader.IsExternalRefsAllowed = true
doc, err := loader.LoadFromFile("testdata/refInRefInProperty/openapi.yaml")
require.NoError(t, err)
require.NotNil(t, doc)
err = doc.Validate(loader.Context)
require.NoError(t, err)
require.Equal(t, "Problem details", doc.Paths["/api/test/ref/in/ref/in/property"].Post.Responses["401"].Value.Content["application/json"].Schema.Value.Properties["error"].Value.Title)
}

func TestLoadFileWithExternalSchemaRef(t *testing.T) {
loader := NewLoader()
loader.IsExternalRefsAllowed = true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
{
"title": "Problem details",
"description": "Common data object for describing an error details",
"type": "object",
"additionalProperties": false,
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"description": "Unique error code",
"minLength": 1,
"example": "unauthorized",
"x-docs-examples": [
"validation-error",
"unauthorized",
"forbidden",
"internal-server-error",
"wrong-basket",
"not-found"
]
},
"title": {
"type": "string",
"description": "Human readable error message",
"minLength": 1,
"example": "Your request parameters didn't validate",
"x-docs-examples": [
"Your request parameters didn't validate",
"Requested resource is not available",
"Internal server error"
]
},
"status": {
"type": "integer",
"description": "HTTP status code",
"maximum": 599,
"minimum": 100,
"example": 200,
"x-docs-examples": [
"200",
"201",
"400",
"503"
]
},
"detail": {
"type": "string",
"description": "Human readable error description. Only for human",
"example": "Basket must have more then 1 item",
"x-docs-examples": [
"Basket must have more then 1 item"
]
},
"invalid-params": {
"type": "array",
"description": "Param list with errors",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"reason"
],
"properties": {
"name": {
"type": "string",
"description": "field name",
"minLength": 1,
"example": "age",
"x-docs-examples": [
"age",
"color"
]
},
"reason": {
"type": "string",
"description": "Field validation error text",
"minLength": 1,
"example": "must be a positive integer",
"x-docs-examples": [
"must be a positive integer",
"must be 'green', 'red' or 'blue'"
]
}
}
}
}
}
}
66 changes: 66 additions & 0 deletions openapi3/testdata/refInRefInProperty/components/errors.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
components:
schemas:
Error:
type: object
description: Error info in problem-details-0.0.1 format
properties:
error:
$ref: "../common-data-objects/problem-details-0.0.1.schema.json"

responses:
400:
description: ""
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
examples:
json:
$ref: "#/components/examples/BadRequest"
401:
description: ""
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
examples:
json:
$ref: "#/components/examples/Unauthorized"
500:
description: ""
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
examples:
json:
$ref: "#/components/examples/InternalServerError"

examples:
BadRequest:
summary: Wrong format
value:
error:
type: validation-error
title: Your request parameters didn't validate.
status: 400
invalid-params:
- name: age
reason: must be a positive integer
- name: color
reason: must be 'green', 'red' or 'blue'
Unauthorized:
summary: Not authenticated
value:
error:
type: unauthorized
title: The request has not been applied because it lacks valid authentication credentials
for the target resource.
status: 401
InternalServerError:
summary: Not handled internal server error
value:
error:
type: internal-server-error
title: Internal server error.
status: 500
29 changes: 29 additions & 0 deletions openapi3/testdata/refInRefInProperty/openapi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
openapi: 3.0.3

info:
title: "Reference in reference in property example"
version: "1.0.0"
paths:
/api/test/ref/in/ref/in/property:
post:
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
file:
type: array
items:
type: string
format: binary
required: true
responses:
200:
description: "Files are saved successfully"
400:
$ref: "./components/errors.yaml#/components/responses/400"
401:
$ref: "./components/errors.yaml#/components/responses/401"
500:
$ref: "./components/errors.yaml#/components/responses/500"