diff --git a/datamodel/low/2.0/definitions_test.go b/datamodel/low/2.0/definitions_test.go new file mode 100644 index 0000000..5d35893 --- /dev/null +++ b/datamodel/low/2.0/definitions_test.go @@ -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) + +} diff --git a/datamodel/low/2.0/header_test.go b/datamodel/low/2.0/header_test.go new file mode 100644 index 0000000..c7d8156 --- /dev/null +++ b/datamodel/low/2.0/header_test.go @@ -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) + +} diff --git a/datamodel/low/2.0/items_test.go b/datamodel/low/2.0/items_test.go new file mode 100644 index 0000000..5e56e74 --- /dev/null +++ b/datamodel/low/2.0/items_test.go @@ -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) +} diff --git a/datamodel/low/2.0/operation_test.go b/datamodel/low/2.0/operation_test.go new file mode 100644 index 0000000..868934a --- /dev/null +++ b/datamodel/low/2.0/operation_test.go @@ -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) + +} diff --git a/datamodel/low/2.0/path_item_test.go b/datamodel/low/2.0/path_item_test.go new file mode 100644 index 0000000..7a99a7c --- /dev/null +++ b/datamodel/low/2.0/path_item_test.go @@ -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) + +} diff --git a/datamodel/low/2.0/paths_test.go b/datamodel/low/2.0/paths_test.go new file mode 100644 index 0000000..a314ad3 --- /dev/null +++ b/datamodel/low/2.0/paths_test.go @@ -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) + +} diff --git a/datamodel/low/2.0/response_test.go b/datamodel/low/2.0/response_test.go new file mode 100644 index 0000000..50d66ea --- /dev/null +++ b/datamodel/low/2.0/response_test.go @@ -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) + +} diff --git a/datamodel/low/2.0/responses_test.go b/datamodel/low/2.0/responses_test.go new file mode 100644 index 0000000..306b5db --- /dev/null +++ b/datamodel/low/2.0/responses_test.go @@ -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) + +} diff --git a/datamodel/low/2.0/security_scheme_test.go b/datamodel/low/2.0/security_scheme_test.go new file mode 100644 index 0000000..0d63ab6 --- /dev/null +++ b/datamodel/low/2.0/security_scheme_test.go @@ -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) + +} diff --git a/datamodel/low/2.0/swagger.go b/datamodel/low/2.0/swagger.go index 6849264..49ad139 100644 --- a/datamodel/low/2.0/swagger.go +++ b/datamodel/low/2.0/swagger.go @@ -52,10 +52,7 @@ func CreateDocument(info *datamodel.SpecInfo) (*Swagger, []error) { var errors []error // build out swagger scalar variables. - bErr := low.BuildModel(info.RootNode, &doc) - if bErr != nil { - errors = append(errors, bErr) - } + _ = low.BuildModel(info.RootNode, &doc) // extract externalDocs extDocs, err := low.ExtractObject[*base.ExternalDoc](base.ExternalDocsLabel, info.RootNode, idx) diff --git a/datamodel/low/2.0/swagger_test.go b/datamodel/low/2.0/swagger_test.go index 4caea35..bb912b9 100644 --- a/datamodel/low/2.0/swagger_test.go +++ b/datamodel/low/2.0/swagger_test.go @@ -4,153 +4,328 @@ package v2 import ( - "fmt" - "github.com/pb33f/libopenapi/datamodel" - "github.com/stretchr/testify/assert" - "io/ioutil" - "testing" + "fmt" + "github.com/pb33f/libopenapi/datamodel" + "github.com/stretchr/testify/assert" + "io/ioutil" + "testing" ) var doc *Swagger func initTest() { - if doc != nil { - return - } - data, _ := ioutil.ReadFile("../../../test_specs/petstorev2-complete.yaml") - info, _ := datamodel.ExtractSpecInfo(data) - var err []error - doc, err = CreateDocument(info) - wait := true - for wait { - select { - case <-info.JsonParsingChannel: - wait = false - } - } - if err != nil { - fmt.Print(err) - panic(err) - } + if doc != nil { + return + } + data, _ := ioutil.ReadFile("../../../test_specs/petstorev2-complete.yaml") + info, _ := datamodel.ExtractSpecInfo(data) + var err []error + doc, err = CreateDocument(info) + wait := true + for wait { + select { + case <-info.JsonParsingChannel: + wait = false + } + } + if err != nil { + fmt.Print(err) + panic(err) + } } func BenchmarkCreateDocument(b *testing.B) { - data, _ := ioutil.ReadFile("../../../test_specs/petstorev2-complete.yaml") - info, _ := datamodel.ExtractSpecInfo(data) - for i := 0; i < b.N; i++ { - doc, _ = CreateDocument(info) - } + data, _ := ioutil.ReadFile("../../../test_specs/petstorev2-complete.yaml") + info, _ := datamodel.ExtractSpecInfo(data) + for i := 0; i < b.N; i++ { + doc, _ = CreateDocument(info) + } } func TestCreateDocument(t *testing.T) { - initTest() - assert.Equal(t, "2.0", doc.SpecInfo.Version) - assert.Equal(t, "1.0.6", doc.Info.Value.Version.Value) - assert.Equal(t, "petstore.swagger.io", doc.Host.Value) - assert.Equal(t, "/v2", doc.BasePath.Value) - assert.Len(t, doc.Parameters.Value.Definitions, 1) - assert.Len(t, doc.Tags.Value, 3) - assert.Len(t, doc.Schemes.Value, 2) - assert.Len(t, doc.Definitions.Value.Schemas, 6) - assert.Len(t, doc.SecurityDefinitions.Value.Definitions, 2) - assert.Len(t, doc.Paths.Value.PathItems, 15) - assert.Len(t, doc.Responses.Value.Definitions, 2) - assert.Equal(t, "http://swagger.io", doc.ExternalDocs.Value.URL.Value) - assert.Equal(t, true, doc.FindExtension("x-pet").Value) - assert.Equal(t, true, doc.FindExtension("X-Pet").Value) + initTest() + assert.Equal(t, "2.0", doc.SpecInfo.Version) + assert.Equal(t, "1.0.6", doc.Info.Value.Version.Value) + assert.Equal(t, "petstore.swagger.io", doc.Host.Value) + assert.Equal(t, "/v2", doc.BasePath.Value) + assert.Len(t, doc.Parameters.Value.Definitions, 1) + assert.Len(t, doc.Tags.Value, 3) + assert.Len(t, doc.Schemes.Value, 2) + assert.Len(t, doc.Definitions.Value.Schemas, 6) + assert.Len(t, doc.SecurityDefinitions.Value.Definitions, 2) + assert.Len(t, doc.Paths.Value.PathItems, 15) + assert.Len(t, doc.Responses.Value.Definitions, 2) + assert.Equal(t, "http://swagger.io", doc.ExternalDocs.Value.URL.Value) + assert.Equal(t, true, doc.FindExtension("x-pet").Value) + assert.Equal(t, true, doc.FindExtension("X-Pet").Value) } func TestCreateDocument_Info(t *testing.T) { - initTest() - assert.Equal(t, "Swagger Petstore", doc.Info.Value.Title.Value) - assert.Equal(t, "apiteam@swagger.io", doc.Info.Value.Contact.Value.Email.Value) - assert.Equal(t, "Apache 2.0", doc.Info.Value.License.Value.Name.Value) + initTest() + assert.Equal(t, "Swagger Petstore", doc.Info.Value.Title.Value) + assert.Equal(t, "apiteam@swagger.io", doc.Info.Value.Contact.Value.Email.Value) + assert.Equal(t, "Apache 2.0", doc.Info.Value.License.Value.Name.Value) } func TestCreateDocument_Parameters(t *testing.T) { - initTest() - simpleParam := doc.Parameters.Value.FindParameter("simpleParam") - assert.NotNil(t, simpleParam) - assert.Equal(t, "simple", simpleParam.Value.Name.Value) - assert.Equal(t, "nuggets", simpleParam.Value.FindExtension("x-chicken").Value) + initTest() + simpleParam := doc.Parameters.Value.FindParameter("simpleParam") + assert.NotNil(t, simpleParam) + assert.Equal(t, "simple", simpleParam.Value.Name.Value) + assert.Equal(t, "nuggets", simpleParam.Value.FindExtension("x-chicken").Value) } func TestCreateDocument_Tags(t *testing.T) { - initTest() - assert.Equal(t, "pet", doc.Tags.Value[0].Value.Name.Value) - assert.Equal(t, "http://swagger.io", doc.Tags.Value[0].Value.ExternalDocs.Value.URL.Value) - assert.Equal(t, "store", doc.Tags.Value[1].Value.Name.Value) - assert.Equal(t, "user", doc.Tags.Value[2].Value.Name.Value) - assert.Equal(t, "http://swagger.io", doc.Tags.Value[2].Value.ExternalDocs.Value.URL.Value) + initTest() + assert.Equal(t, "pet", doc.Tags.Value[0].Value.Name.Value) + assert.Equal(t, "http://swagger.io", doc.Tags.Value[0].Value.ExternalDocs.Value.URL.Value) + assert.Equal(t, "store", doc.Tags.Value[1].Value.Name.Value) + assert.Equal(t, "user", doc.Tags.Value[2].Value.Name.Value) + assert.Equal(t, "http://swagger.io", doc.Tags.Value[2].Value.ExternalDocs.Value.URL.Value) } func TestCreateDocument_SecurityDefinitions(t *testing.T) { - initTest() - apiKey := doc.SecurityDefinitions.Value.FindSecurityDefinition("api_key") - assert.Equal(t, "apiKey", apiKey.Value.Type.Value) - petStoreAuth := doc.SecurityDefinitions.Value.FindSecurityDefinition("petstore_auth") - assert.Equal(t, "oauth2", petStoreAuth.Value.Type.Value) - assert.Equal(t, "implicit", petStoreAuth.Value.Flow.Value) - assert.Len(t, petStoreAuth.Value.Scopes.Value.Values, 2) - assert.Equal(t, "read your pets", petStoreAuth.Value.Scopes.Value.FindScope("read:pets").Value) + initTest() + apiKey := doc.SecurityDefinitions.Value.FindSecurityDefinition("api_key") + assert.Equal(t, "apiKey", apiKey.Value.Type.Value) + petStoreAuth := doc.SecurityDefinitions.Value.FindSecurityDefinition("petstore_auth") + assert.Equal(t, "oauth2", petStoreAuth.Value.Type.Value) + assert.Equal(t, "implicit", petStoreAuth.Value.Flow.Value) + assert.Len(t, petStoreAuth.Value.Scopes.Value.Values, 2) + assert.Equal(t, "read your pets", petStoreAuth.Value.Scopes.Value.FindScope("read:pets").Value) } func TestCreateDocument_Definitions(t *testing.T) { - initTest() - apiResp := doc.Definitions.Value.FindSchema("ApiResponse").Value.Schema() - assert.NotNil(t, apiResp) - assert.Len(t, apiResp.Properties.Value, 3) - assert.Equal(t, "integer", apiResp.FindProperty("code").Value.Schema().Type.Value) + initTest() + apiResp := doc.Definitions.Value.FindSchema("ApiResponse").Value.Schema() + assert.NotNil(t, apiResp) + assert.Len(t, apiResp.Properties.Value, 3) + assert.Equal(t, "integer", apiResp.FindProperty("code").Value.Schema().Type.Value) - pet := doc.Definitions.Value.FindSchema("Pet").Value.Schema() - assert.NotNil(t, pet) - assert.Len(t, pet.Required.Value, 2) + pet := doc.Definitions.Value.FindSchema("Pet").Value.Schema() + assert.NotNil(t, pet) + assert.Len(t, pet.Required.Value, 2) - // perform a deep inline lookup on a schema to ensure chains work - assert.Equal(t, "Category", pet.FindProperty("category").Value.Schema().XML.Value.Name.Value) + // perform a deep inline lookup on a schema to ensure chains work + assert.Equal(t, "Category", pet.FindProperty("category").Value.Schema().XML.Value.Name.Value) - // check enums - assert.Len(t, pet.FindProperty("status").Value.Schema().Enum.Value, 3) + // check enums + assert.Len(t, pet.FindProperty("status").Value.Schema().Enum.Value, 3) } func TestCreateDocument_ResponseDefinitions(t *testing.T) { - initTest() - apiResp := doc.Responses.Value.FindResponse("200") - assert.NotNil(t, apiResp) - assert.Equal(t, "OK", apiResp.Value.Description.Value) - assert.Equal(t, "morning", apiResp.Value.FindExtension("x-coffee").Value) + initTest() + apiResp := doc.Responses.Value.FindResponse("200") + assert.NotNil(t, apiResp) + assert.Equal(t, "OK", apiResp.Value.Description.Value) + assert.Equal(t, "morning", apiResp.Value.FindExtension("x-coffee").Value) - header := apiResp.Value.FindHeader("noHeader") - assert.NotNil(t, header) - assert.True(t, header.Value.FindExtension("x-empty").Value.(bool)) + header := apiResp.Value.FindHeader("noHeader") + assert.NotNil(t, header) + assert.True(t, header.Value.FindExtension("x-empty").Value.(bool)) - header = apiResp.Value.FindHeader("myHeader") - if k, ok := header.Value.Items.Value.Default.Value.(map[string]interface{}); ok { - assert.Equal(t, "here", k["something"]) - } else { - panic("should not fail.") - } - if k, ok := header.Value.Items.Value.Items.Value.Default.Value.([]interface{}); ok { - assert.Len(t, k, 2) - assert.Equal(t, "two", k[1]) - } else { - panic("should not fail.") - } + header = apiResp.Value.FindHeader("myHeader") + if k, ok := header.Value.Items.Value.Default.Value.(map[string]interface{}); ok { + assert.Equal(t, "here", k["something"]) + } else { + panic("should not fail.") + } + if k, ok := header.Value.Items.Value.Items.Value.Default.Value.([]interface{}); ok { + assert.Len(t, k, 2) + assert.Equal(t, "two", k[1]) + } else { + panic("should not fail.") + } - header = apiResp.Value.FindHeader("yourHeader") - assert.Equal(t, "somethingSimple", header.Value.Items.Value.Default.Value) + header = apiResp.Value.FindHeader("yourHeader") + assert.Equal(t, "somethingSimple", header.Value.Items.Value.Default.Value) } func TestCreateDocument_Paths(t *testing.T) { - initTest() - uploadImage := doc.Paths.Value.FindPath("/pet/{petId}/uploadImage").Value - assert.NotNil(t, uploadImage) - assert.Nil(t, doc.Paths.Value.FindPath("/nothing-nowhere-nohow")) - assert.Equal(t, "man", uploadImage.FindExtension("x-potato").Value) - assert.Equal(t, "fresh", doc.Paths.Value.FindExtension("x-minty").Value) - assert.Equal(t, "successful operation", - uploadImage.Post.Value.Responses.Value.FindResponseByCode("200").Value.Description.Value) + initTest() + uploadImage := doc.Paths.Value.FindPath("/pet/{petId}/uploadImage").Value + assert.NotNil(t, uploadImage) + assert.Nil(t, doc.Paths.Value.FindPath("/nothing-nowhere-nohow")) + assert.Equal(t, "man", uploadImage.FindExtension("x-potato").Value) + assert.Equal(t, "fresh", doc.Paths.Value.FindExtension("x-minty").Value) + assert.Equal(t, "successful operation", + uploadImage.Post.Value.Responses.Value.FindResponseByCode("200").Value.Description.Value) } +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) +} diff --git a/datamodel/model_utils.go b/datamodel/model_utils.go index cce4a0f..5cbd7a7 100644 --- a/datamodel/model_utils.go +++ b/datamodel/model_utils.go @@ -91,7 +91,10 @@ func ExtractSpecInfo(spec []byte) (*SpecInfo, error) { // check for specific keys if openAPI3 != nil { specVersion.SpecType = utils.OpenApi3 - version, majorVersion := parseVersionTypeData(openAPI3.Value) + version, majorVersion, versionError := parseVersionTypeData(openAPI3.Value) + if versionError != nil { + return nil, versionError + } // parse JSON go parseJSON(spec, specVersion) @@ -106,7 +109,10 @@ func ExtractSpecInfo(spec []byte) (*SpecInfo, error) { } if openAPI2 != nil { specVersion.SpecType = utils.OpenApi2 - version, majorVersion := parseVersionTypeData(openAPI2.Value) + version, majorVersion, versionError := parseVersionTypeData(openAPI2.Value) + if versionError != nil { + return nil, versionError + } // parse JSON go parseJSON(spec, specVersion) @@ -121,7 +127,10 @@ func ExtractSpecInfo(spec []byte) (*SpecInfo, error) { } if asyncAPI != nil { specVersion.SpecType = utils.AsyncApi - version, majorVersion := parseVersionTypeData(asyncAPI.Value) + version, majorVersion, versionErr := parseVersionTypeData(asyncAPI.Value) + if versionErr != nil { + return nil, versionErr + } // parse JSON go parseJSON(spec, specVersion) @@ -148,9 +157,12 @@ func ExtractSpecInfo(spec []byte) (*SpecInfo, error) { return specVersion, nil } -func parseVersionTypeData(d interface{}) (string, int) { +func parseVersionTypeData(d interface{}) (string, int, error) { 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