Skip to content

contributes go-swagger/go-swagger#2113 #110

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

Merged
merged 1 commit into from
Nov 23, 2019
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
5 changes: 5 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,8 @@ linters:
- lll
- gochecknoinits
- gochecknoglobals
- funlen
- godox
- gocognit
- whitespace
- wsl
7 changes: 4 additions & 3 deletions expander.go
Original file line number Diff line number Diff line change
Expand Up @@ -452,11 +452,12 @@ func expandPathItem(pathItem *PathItem, resolver *schemaLoader, basePath string)
return err
}
if pathItem.Ref.String() != "" {
var err error
resolver, err = resolver.transitiveResolver(basePath, pathItem.Ref)
if resolver.shouldStopOnError(err) {
transitiveResolver, err := resolver.transitiveResolver(basePath, pathItem.Ref)
if transitiveResolver.shouldStopOnError(err) {
return err
}
basePath = transitiveResolver.updateBasePath(resolver, basePath)
resolver = transitiveResolver
}
pathItem.Ref = Ref{}

Expand Down
9 changes: 9 additions & 0 deletions fixtures/bugs/2113/base.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
swagger: "2.0"
info:
version: "1"
title: "nested $ref fixture"
paths:
/dummy:
$ref: ./schemas/api/api.yaml#/paths/~1dummy
/example:
$ref: ./schemas/api/api.yaml#/paths/~1example
19 changes: 19 additions & 0 deletions fixtures/bugs/2113/schemas/api/api.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
swagger: "2.0"
info:
version: "1"
title: "sub api"
paths:
/dummy:
get:
responses:
200:
description: OK
schema:
$ref: ../dummy/dummy.yaml
/example:
get:
responses:
200:
description: OK
schema:
$ref: ../example/example.yaml
5 changes: 5 additions & 0 deletions fixtures/bugs/2113/schemas/dummy/dummy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
required:
- dummyPayload
properties:
dummyPayload:
type: string
6 changes: 6 additions & 0 deletions fixtures/bugs/2113/schemas/example/example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
$schema: http://json-schema.org/draft-07/schema#
required:
- payload
properties:
payload:
type: string
1 change: 1 addition & 0 deletions ref.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func (r *Ref) IsValidURI(basepaths ...string) bool {
}

if r.HasFullURL {
//#nosec
rr, err := http.Get(v)
if err != nil {
return false
Expand Down
7 changes: 1 addition & 6 deletions schema_loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,7 @@ func (r *schemaLoader) transitiveResolver(basePath string, ref Ref) (*schemaLoad
newOptions := r.options
newOptions.RelativeBase = rootURL.String()
debugLog("setting new root: %s", newOptions.RelativeBase)
resolver, err := defaultSchemaLoader(root, newOptions, r.cache, r.context)
if err != nil {
return nil, err
}

return resolver, nil
return defaultSchemaLoader(root, newOptions, r.cache, r.context)
}

func (r *schemaLoader) updateBasePath(transitive *schemaLoader, basePath string) string {
Expand Down
109 changes: 58 additions & 51 deletions spec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,33 @@ import (
"github.com/go-openapi/spec"
"github.com/go-openapi/swag"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

// mimics what the go-openapi/load does
var (
yamlLoader = swag.YAMLDoc
rex = regexp.MustCompile(`"\$ref":\s*"(.+)"`)
testLoader func(string) (json.RawMessage, error)
)

func loadOrFail(t *testing.T, path string) *spec.Swagger {
raw, erl := yamlLoader(path)
if erl != nil {
t.Logf("can't load fixture %s: %v", path, erl)
t.FailNow()
return nil
func init() {
testLoader = func(path string) (json.RawMessage, error) {
if swag.YAMLMatcher(path) {
return swag.YAMLDoc(path)
}
data, err := swag.LoadFromFileOrHTTP(path)
if err != nil {
return nil, err
}
return json.RawMessage(data), nil
}
}
func loadOrFail(t *testing.T, path string) *spec.Swagger {
raw, err := testLoader(path)
require.NoErrorf(t, err, "can't load fixture %s: %v", path, err)
swspec := new(spec.Swagger)
if err := json.Unmarshal(raw, swspec); err != nil {
t.FailNow()
return nil
}
err = json.Unmarshal(raw, swspec)
require.NoError(t, err)
return swspec
}

Expand All @@ -54,22 +61,17 @@ func Test_Issue1429(t *testing.T) {
defer func() {
spec.PathLoader = prevPathLoader
}()
spec.PathLoader = yamlLoader
spec.PathLoader = testLoader
path := filepath.Join("fixtures", "bugs", "1429", "swagger.yaml")

// load and full expand
sp := loadOrFail(t, path)
err := spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false})
if !assert.NoError(t, err) {
t.FailNow()
return
}
require.NoError(t, err)

// assert well expanded
if !assert.Truef(t, (sp.Paths != nil && sp.Paths.Paths != nil), "expected paths to be available in fixture") {
t.FailNow()
return
}
require.Truef(t, (sp.Paths != nil && sp.Paths.Paths != nil), "expected paths to be available in fixture")

for _, pi := range sp.Paths.Paths {
for _, param := range pi.Get.Parameters {
if assert.NotNilf(t, param.Schema, "expected param schema not to be nil") {
Expand All @@ -96,16 +98,11 @@ func Test_Issue1429(t *testing.T) {
// reload and SkipSchemas: true
sp = loadOrFail(t, path)
err = spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: true})
if !assert.NoError(t, err) {
t.FailNow()
return
}
require.NoError(t, err)

// assert well resolved
if !assert.Truef(t, (sp.Paths != nil && sp.Paths.Paths != nil), "expected paths to be available in fixture") {
t.FailNow()
return
}
require.Truef(t, (sp.Paths != nil && sp.Paths.Paths != nil), "expected paths to be available in fixture")

for _, pi := range sp.Paths.Paths {
for _, param := range pi.Get.Parameters {
if assert.NotNilf(t, param.Schema, "expected param schema not to be nil") {
Expand Down Expand Up @@ -154,20 +151,17 @@ func Test_MoreLocalExpansion(t *testing.T) {
defer func() {
spec.PathLoader = prevPathLoader
}()
spec.PathLoader = yamlLoader
spec.PathLoader = testLoader
path := filepath.Join("fixtures", "local_expansion", "spec2.yaml")

// load and full expand
sp := loadOrFail(t, path)
err := spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false})
if !assert.NoError(t, err) {
t.FailNow()
return
}
require.NoError(t, err)

// asserts all $ref expanded
jazon, _ := json.MarshalIndent(sp, "", " ")
assert.NotContains(t, jazon, `"$ref"`)
//t.Log(string(jazon))
}

func Test_Issue69(t *testing.T) {
Expand All @@ -179,10 +173,8 @@ func Test_Issue69(t *testing.T) {
// load and expand
sp := loadOrFail(t, path)
err := spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false})
if !assert.NoError(t, err) {
t.FailNow()
return
}
require.NoError(t, err)

// asserts all $ref expanded
jazon, _ := json.MarshalIndent(sp, "", " ")

Expand All @@ -202,18 +194,16 @@ func Test_Issue1621(t *testing.T) {
defer func() {
spec.PathLoader = prevPathLoader
}()
spec.PathLoader = yamlLoader
spec.PathLoader = testLoader
path := filepath.Join("fixtures", "bugs", "1621", "fixture-1621.yaml")

// expand with relative path
// load and expand
sp := loadOrFail(t, path)

err := spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false})
if !assert.NoError(t, err) {
t.FailNow()
return
}
require.NoError(t, err)

// asserts all $ref expanded
jazon, _ := json.MarshalIndent(sp, "", " ")
m := rex.FindAllStringSubmatch(string(jazon), -1)
Expand All @@ -228,10 +218,8 @@ func Test_Issue1614(t *testing.T) {
// load and expand
sp := loadOrFail(t, path)
err := spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false})
if !assert.NoError(t, err) {
t.FailNow()
return
}
require.NoError(t, err)

// asserts all $ref expanded
jazon, _ := json.MarshalIndent(sp, "", " ")

Expand All @@ -248,10 +236,8 @@ func Test_Issue1614(t *testing.T) {
// now with option CircularRefAbsolute
sp = loadOrFail(t, path)
err = spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false, AbsoluteCircularRef: true})
if !assert.NoError(t, err) {
t.FailNow()
return
}
require.NoError(t, err)

// asserts all $ref expanded
jazon, _ = json.MarshalIndent(sp, "", " ")

Expand All @@ -267,3 +253,24 @@ func Test_Issue1614(t *testing.T) {
}
}
}

func Test_Issue2113(t *testing.T) {
prevPathLoader := spec.PathLoader
defer func() {
spec.PathLoader = prevPathLoader
}()
spec.PathLoader = testLoader
// this checks expansion with nested specs
path := filepath.Join("fixtures", "bugs", "2113", "base.yaml")

// load and expand
sp := loadOrFail(t, path)
err := spec.ExpandSpec(sp, &spec.ExpandOptions{RelativeBase: path, SkipSchemas: false})
require.NoError(t, err)
// asserts all $ref expanded
jazon, _ := json.MarshalIndent(sp, "", " ")

// assert all $ref match have been expanded
m := rex.FindAllStringSubmatch(string(jazon), -1)
assert.Emptyf(t, m, "expected all $ref to be expanded")
}