100% test coverage for v2 model

Swagger is now forever baked. thank god.
This commit is contained in:
Dave Shanley
2022-09-05 14:22:45 -04:00
parent d57b9ca482
commit 0c5574d597
12 changed files with 786 additions and 117 deletions

View File

@@ -0,0 +1,88 @@
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
// SPDX-License-Identifier: MIT
package v2
import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
)
func TestDefinitions_Schemas_Build_Error(t *testing.T) {
yml := `gonna:
$ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n Definitions
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}
func TestDefinitions_Parameters_Build_Error(t *testing.T) {
yml := `gonna:
$ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n ParameterDefinitions
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}
func TestDefinitions_Responses_Build_Error(t *testing.T) {
yml := `gonna:
$ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n ResponsesDefinitions
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}
func TestDefinitions_Security_Build_Error(t *testing.T) {
yml := `gonna:
$ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n SecurityDefinitions
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}

View File

@@ -0,0 +1,31 @@
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
// SPDX-License-Identifier: MIT
package v2
import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
)
func TestHeader_Build(t *testing.T) {
yml := `items:
$ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n Header
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}

View File

@@ -0,0 +1,30 @@
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
// SPDX-License-Identifier: MIT
package v2
import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
)
func TestItems_Build(t *testing.T) {
yml := `items:
$ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n Items
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}

View File

@@ -0,0 +1,88 @@
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
// SPDX-License-Identifier: MIT
package v2
import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
)
func TestOperation_Build_ExternalDocs(t *testing.T) {
yml := `externalDocs:
$ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n Operation
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}
func TestOperation_Build_Params(t *testing.T) {
yml := `parameters:
$ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n Operation
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}
func TestOperation_Build_Responses(t *testing.T) {
yml := `responses:
$ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n Operation
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}
func TestOperation_Build_Security(t *testing.T) {
yml := `security:
$ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n Operation
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}

View File

@@ -0,0 +1,50 @@
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
// SPDX-License-Identifier: MIT
package v2
import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
)
func TestPathItem_Build_Params(t *testing.T) {
yml := `parameters:
$ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n PathItem
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}
func TestPathItem_Build_MethodFail(t *testing.T) {
yml := `post:
$ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n PathItem
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}

View File

@@ -0,0 +1,31 @@
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
// SPDX-License-Identifier: MIT
package v2
import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
)
func TestPaths_Build(t *testing.T) {
yml := `"/fresh/code":
$ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n Paths
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}

View File

@@ -0,0 +1,69 @@
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
// SPDX-License-Identifier: MIT
package v2
import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
)
func TestResponse_Build_Schema(t *testing.T) {
yml := `schema:
$ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n Response
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}
func TestResponse_Build_Examples(t *testing.T) {
yml := `examples:
$ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n Response
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}
func TestResponse_Build_Headers(t *testing.T) {
yml := `headers:
$ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n Response
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}

View File

@@ -0,0 +1,67 @@
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
// SPDX-License-Identifier: MIT
package v2
import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
)
func TestResponses_Build_Response(t *testing.T) {
yml := `$ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n Responses
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}
func TestResponses_Build_Response_Default(t *testing.T) {
yml := `default:
$ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n Responses
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}
func TestResponses_Build_WrongType(t *testing.T) {
yml := `- $ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n Responses
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}

View File

@@ -0,0 +1,31 @@
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
// SPDX-License-Identifier: MIT
package v2
import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
)
func TestSecurityScheme_Build(t *testing.T) {
yml := `scopes:
$ref: break`
var idxNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &idxNode)
assert.NoError(t, mErr)
idx := index.NewSpecIndex(&idxNode)
var n SecurityScheme
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
assert.Error(t, err)
}

View File

@@ -52,10 +52,7 @@ func CreateDocument(info *datamodel.SpecInfo) (*Swagger, []error) {
var errors []error var errors []error
// build out swagger scalar variables. // build out swagger scalar variables.
bErr := low.BuildModel(info.RootNode, &doc) _ = low.BuildModel(info.RootNode, &doc)
if bErr != nil {
errors = append(errors, bErr)
}
// extract externalDocs // extract externalDocs
extDocs, err := low.ExtractObject[*base.ExternalDoc](base.ExternalDocsLabel, info.RootNode, idx) extDocs, err := low.ExtractObject[*base.ExternalDoc](base.ExternalDocsLabel, info.RootNode, idx)

View File

@@ -154,3 +154,178 @@ func TestCreateDocument_Paths(t *testing.T) {
} }
func TestCreateDocument_Bad(t *testing.T) {
yml := `swagger:
$ref: bork`
info, err := datamodel.ExtractSpecInfo([]byte(yml))
assert.Nil(t, info)
assert.Error(t, err)
}
func TestCreateDocument_ExternalDocsBad(t *testing.T) {
yml := `externalDocs:
$ref: bork`
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
var err []error
doc, err = CreateDocument(info)
wait := true
for wait {
select {
case <-info.JsonParsingChannel:
wait = false
}
}
assert.Len(t, err, 1)
}
func TestCreateDocument_TagsBad(t *testing.T) {
yml := `tags:
$ref: bork`
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
var err []error
doc, err = CreateDocument(info)
wait := true
for wait {
select {
case <-info.JsonParsingChannel:
wait = false
}
}
assert.Len(t, err, 1)
}
func TestCreateDocument_PathsBad(t *testing.T) {
yml := `paths:
"/hey":
post:
responses:
"200":
$ref: bork`
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
var err []error
doc, err = CreateDocument(info)
wait := true
for wait {
select {
case <-info.JsonParsingChannel:
wait = false
}
}
assert.Len(t, err, 1)
}
func TestCreateDocument_SecurityBad(t *testing.T) {
yml := `security:
$ref: `
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
var err []error
doc, err = CreateDocument(info)
wait := true
for wait {
select {
case <-info.JsonParsingChannel:
wait = false
}
}
assert.Len(t, err, 1)
}
func TestCreateDocument_SecurityDefinitionsBad(t *testing.T) {
yml := `securityDefinitions:
$ref: `
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
var err []error
doc, err = CreateDocument(info)
wait := true
for wait {
select {
case <-info.JsonParsingChannel:
wait = false
}
}
assert.Len(t, err, 1)
}
func TestCreateDocument_ResponsesBad(t *testing.T) {
yml := `responses:
$ref: `
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
var err []error
doc, err = CreateDocument(info)
wait := true
for wait {
select {
case <-info.JsonParsingChannel:
wait = false
}
}
assert.Len(t, err, 1)
}
func TestCreateDocument_ParametersBad(t *testing.T) {
yml := `parameters:
$ref: `
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
var err []error
doc, err = CreateDocument(info)
wait := true
for wait {
select {
case <-info.JsonParsingChannel:
wait = false
}
}
assert.Len(t, err, 1)
}
func TestCreateDocument_DefinitionsBad(t *testing.T) {
yml := `definitions:
$ref: `
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
var err []error
doc, err = CreateDocument(info)
wait := true
for wait {
select {
case <-info.JsonParsingChannel:
wait = false
}
}
assert.Len(t, err, 1)
}
func TestCreateDocument_InfoBad(t *testing.T) {
yml := `info:
$ref: `
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
var err []error
doc, err = CreateDocument(info)
wait := true
for wait {
select {
case <-info.JsonParsingChannel:
wait = false
}
}
assert.Len(t, err, 1)
}

View File

@@ -91,7 +91,10 @@ func ExtractSpecInfo(spec []byte) (*SpecInfo, error) {
// check for specific keys // check for specific keys
if openAPI3 != nil { if openAPI3 != nil {
specVersion.SpecType = utils.OpenApi3 specVersion.SpecType = utils.OpenApi3
version, majorVersion := parseVersionTypeData(openAPI3.Value) version, majorVersion, versionError := parseVersionTypeData(openAPI3.Value)
if versionError != nil {
return nil, versionError
}
// parse JSON // parse JSON
go parseJSON(spec, specVersion) go parseJSON(spec, specVersion)
@@ -106,7 +109,10 @@ func ExtractSpecInfo(spec []byte) (*SpecInfo, error) {
} }
if openAPI2 != nil { if openAPI2 != nil {
specVersion.SpecType = utils.OpenApi2 specVersion.SpecType = utils.OpenApi2
version, majorVersion := parseVersionTypeData(openAPI2.Value) version, majorVersion, versionError := parseVersionTypeData(openAPI2.Value)
if versionError != nil {
return nil, versionError
}
// parse JSON // parse JSON
go parseJSON(spec, specVersion) go parseJSON(spec, specVersion)
@@ -121,7 +127,10 @@ func ExtractSpecInfo(spec []byte) (*SpecInfo, error) {
} }
if asyncAPI != nil { if asyncAPI != nil {
specVersion.SpecType = utils.AsyncApi specVersion.SpecType = utils.AsyncApi
version, majorVersion := parseVersionTypeData(asyncAPI.Value) version, majorVersion, versionErr := parseVersionTypeData(asyncAPI.Value)
if versionErr != nil {
return nil, versionErr
}
// parse JSON // parse JSON
go parseJSON(spec, specVersion) go parseJSON(spec, specVersion)
@@ -148,9 +157,12 @@ func ExtractSpecInfo(spec []byte) (*SpecInfo, error) {
return specVersion, nil return specVersion, nil
} }
func parseVersionTypeData(d interface{}) (string, int) { func parseVersionTypeData(d interface{}) (string, int, error) {
r := []rune(strings.TrimSpace(fmt.Sprintf("%v", d))) r := []rune(strings.TrimSpace(fmt.Sprintf("%v", d)))
return string(r), int(r[0]) - '0' if len(r) <= 0 {
return "", 0, fmt.Errorf("unable to extract version from: %v", d)
}
return string(r), int(r[0]) - '0', nil
} }
// AreValuesCorrectlyTyped will look through an array of unknown values and check they match // AreValuesCorrectlyTyped will look through an array of unknown values and check they match