270 lines
7.7 KiB
Go
270 lines
7.7 KiB
Go
// Copyright 2015 go-swagger maintainers
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package spec_test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/go-openapi/spec"
|
|
"github.com/go-openapi/swag"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
// mimics what the go-openapi/load does
|
|
var (
|
|
yamlLoader = swag.YAMLDoc
|
|
rex = regexp.MustCompile(`"\$ref":\s*"(.+)"`)
|
|
)
|
|
|
|
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
|
|
}
|
|
swspec := new(spec.Swagger)
|
|
if err := json.Unmarshal(raw, swspec); err != nil {
|
|
t.FailNow()
|
|
return nil
|
|
}
|
|
return swspec
|
|
}
|
|
|
|
// Test unitary fixture for dev and bug fixing
|
|
func Test_Issue1429(t *testing.T) {
|
|
prevPathLoader := spec.PathLoader
|
|
defer func() {
|
|
spec.PathLoader = prevPathLoader
|
|
}()
|
|
spec.PathLoader = yamlLoader
|
|
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
|
|
}
|
|
|
|
// assert well expanded
|
|
if !assert.Truef(t, (sp.Paths != nil && sp.Paths.Paths != nil), "expected paths to be available in fixture") {
|
|
t.FailNow()
|
|
return
|
|
}
|
|
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") {
|
|
// all param fixtures are body param with schema
|
|
// all $ref expanded
|
|
assert.Equal(t, "", param.Schema.Ref.String())
|
|
}
|
|
}
|
|
for code, response := range pi.Get.Responses.StatusCodeResponses {
|
|
// all response fixtures are with StatusCodeResponses, but 200
|
|
if code == 200 {
|
|
assert.Nilf(t, response.Schema, "expected response schema to be nil")
|
|
continue
|
|
}
|
|
if assert.NotNilf(t, response.Schema, "expected response schema not to be nil") {
|
|
assert.Equal(t, "", response.Schema.Ref.String())
|
|
}
|
|
}
|
|
}
|
|
for _, def := range sp.Definitions {
|
|
assert.Equal(t, "", def.Ref.String())
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// assert well resolved
|
|
if !assert.Truef(t, (sp.Paths != nil && sp.Paths.Paths != nil), "expected paths to be available in fixture") {
|
|
t.FailNow()
|
|
return
|
|
}
|
|
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") {
|
|
// all param fixtures are body param with schema
|
|
if param.Name == "plainRequest" {
|
|
// this one is expanded
|
|
assert.Equal(t, "", param.Schema.Ref.String())
|
|
continue
|
|
}
|
|
if param.Name == "nestedBody" {
|
|
// this one is local
|
|
assert.True(t, strings.HasPrefix(param.Schema.Ref.String(), "#/definitions/"))
|
|
continue
|
|
}
|
|
if param.Name == "remoteRequest" {
|
|
assert.Contains(t, param.Schema.Ref.String(), "remote/remote.yaml#/")
|
|
continue
|
|
}
|
|
assert.Contains(t, param.Schema.Ref.String(), "responses.yaml#/")
|
|
}
|
|
}
|
|
for code, response := range pi.Get.Responses.StatusCodeResponses {
|
|
// all response fixtures are with StatusCodeResponses, but 200
|
|
if code == 200 {
|
|
assert.Nilf(t, response.Schema, "expected response schema to be nil")
|
|
continue
|
|
}
|
|
if code == 204 {
|
|
assert.Contains(t, response.Schema.Ref.String(), "remote/remote.yaml#/")
|
|
continue
|
|
}
|
|
if code == 404 {
|
|
assert.Equal(t, "", response.Schema.Ref.String())
|
|
continue
|
|
}
|
|
assert.Containsf(t, response.Schema.Ref.String(), "responses.yaml#/", "expected remote ref at resp. %d", code)
|
|
}
|
|
}
|
|
for _, def := range sp.Definitions {
|
|
assert.Contains(t, def.Ref.String(), "responses.yaml#/")
|
|
}
|
|
}
|
|
|
|
func Test_MoreLocalExpansion(t *testing.T) {
|
|
prevPathLoader := spec.PathLoader
|
|
defer func() {
|
|
spec.PathLoader = prevPathLoader
|
|
}()
|
|
spec.PathLoader = yamlLoader
|
|
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
|
|
}
|
|
// asserts all $ref expanded
|
|
jazon, _ := json.MarshalIndent(sp, "", " ")
|
|
assert.NotContains(t, jazon, `"$ref"`)
|
|
//t.Log(string(jazon))
|
|
}
|
|
|
|
func Test_Issue69(t *testing.T) {
|
|
// this checks expansion for the dapperbox spec (circular ref issues)
|
|
|
|
path := filepath.Join("fixtures", "bugs", "69", "dapperbox.json")
|
|
|
|
// 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
|
|
}
|
|
// asserts all $ref expanded
|
|
jazon, _ := json.MarshalIndent(sp, "", " ")
|
|
|
|
// assert all $ref maches "$ref": "#/definitions/something"
|
|
m := rex.FindAllStringSubmatch(string(jazon), -1)
|
|
if assert.NotNil(t, m) {
|
|
for _, matched := range m {
|
|
subMatch := matched[1]
|
|
assert.True(t, strings.HasPrefix(subMatch, "#/definitions/"),
|
|
"expected $ref to be inlined, got: %s", matched[0])
|
|
}
|
|
}
|
|
}
|
|
|
|
func Test_Issue1621(t *testing.T) {
|
|
prevPathLoader := spec.PathLoader
|
|
defer func() {
|
|
spec.PathLoader = prevPathLoader
|
|
}()
|
|
spec.PathLoader = yamlLoader
|
|
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
|
|
}
|
|
// asserts all $ref expanded
|
|
jazon, _ := json.MarshalIndent(sp, "", " ")
|
|
m := rex.FindAllStringSubmatch(string(jazon), -1)
|
|
assert.Nil(t, m)
|
|
}
|
|
|
|
func Test_Issue1614(t *testing.T) {
|
|
|
|
path := filepath.Join("fixtures", "bugs", "1614", "gitea.json")
|
|
|
|
// 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
|
|
}
|
|
// asserts all $ref expanded
|
|
jazon, _ := json.MarshalIndent(sp, "", " ")
|
|
|
|
// assert all $ref maches "$ref": "#/definitions/something"
|
|
m := rex.FindAllStringSubmatch(string(jazon), -1)
|
|
if assert.NotNil(t, m) {
|
|
for _, matched := range m {
|
|
subMatch := matched[1]
|
|
assert.True(t, strings.HasPrefix(subMatch, "#/definitions/"),
|
|
"expected $ref to be inlined, got: %s", matched[0])
|
|
}
|
|
}
|
|
|
|
// 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
|
|
}
|
|
// asserts all $ref expanded
|
|
jazon, _ = json.MarshalIndent(sp, "", " ")
|
|
|
|
// assert all $ref maches "$ref": "{file path}#/definitions/something"
|
|
refPath, _ := os.Getwd()
|
|
refPath = filepath.Join(refPath, path)
|
|
m = rex.FindAllStringSubmatch(string(jazon), -1)
|
|
if assert.NotNil(t, m) {
|
|
for _, matched := range m {
|
|
subMatch := matched[1]
|
|
assert.True(t, strings.HasPrefix(subMatch, refPath+"#/definitions/"),
|
|
"expected $ref to be inlined, got: %s", matched[0])
|
|
}
|
|
}
|
|
}
|