Skip to content

Commit

Permalink
adds validation for required properties in definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
casualjim committed Apr 20, 2015
1 parent 45f58ee commit d3cc868
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ For a V1 I want to have this feature set completed:
- [ ] :warning: each security scope in a security definition should be unique (Warning)
- [x] :boom: each path parameter should correspond to a parameter placeholder and vice versa (Error)
- [ ] :warning: each referencable definition must have references (Warning)
- [ ] :boom: each definition property listed in the required array must be defined in the properties of the model (Error)
- [x] :boom: each definition property listed in the required array must be defined in the properties of the model (Error)
- [x] :boom: each parameter should have a unique `name` and `type` combination (Error)
- [x] :boom: each operation should have only 1 parameter of type body (Error)
- [ ] :boom: each reference must point to a valid object (Error)
Expand Down
32 changes: 30 additions & 2 deletions internal/validate/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package validate

import (
"fmt"
"regexp"
"strings"

"github.com/casualjim/go-swagger/errors"
Expand Down Expand Up @@ -171,7 +172,7 @@ func (s *SpecValidator) validatePathParamPresence(fromPath, fromOperation []stri
}
}
if !matched {
res.AddErrors(errors.New(422, "Path param %q is not present in the path", p))
res.AddErrors(errors.New(422, "path param %q is not present in the path", p))
}
}

Expand All @@ -185,7 +186,34 @@ func (s *SpecValidator) validateReferenced() *Result {

func (s *SpecValidator) validateRequiredDefinitions() *Result {
// Each definition property listed in the required array must be defined in the properties of the model
return nil
res := new(Result)
for d, v := range s.spec.Spec().Definitions {
REQUIRED:
for _, pn := range v.Required {
if _, ok := v.Properties[pn]; ok {
continue
}

for pp := range v.PatternProperties {
re := regexp.MustCompile(pp)
if re.MatchString(pn) {
continue REQUIRED
}
}

if v.AdditionalProperties != nil {
if v.AdditionalProperties.Allows {
continue
}
if v.AdditionalProperties.Schema != nil {
continue
}
}

res.AddErrors(errors.New(422, "%q is present in required but not defined as property in defintion %q", pn, d))
}
}
return res
}

func (s *SpecValidator) validateParameters() *Result {
Expand Down
37 changes: 37 additions & 0 deletions internal/validate/spec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,44 @@ func TestValidateReferenced(t *testing.T) {
}

func TestValidateRequiredDefinitions(t *testing.T) {
doc, api := petstore.NewAPI(t)
validator := NewSpecValidator(spec.MustLoadSwagger20Schema(), api.Formats())
validator.spec = doc
res := validator.validateRequiredDefinitions()
assert.Empty(t, res.Errors)

// properties
sw := doc.Spec()
def := sw.Definitions["Tag"]
def.Required = append(def.Required, "type")
sw.Definitions["Tag"] = def
res = validator.validateRequiredDefinitions()
assert.NotEmpty(t, res.Errors)

// pattern properties
def.PatternProperties = make(map[string]spec.Schema)
def.PatternProperties["ty.*"] = *spec.StringProperty()
sw.Definitions["Tag"] = def
res = validator.validateRequiredDefinitions()
assert.Empty(t, res.Errors)

def.PatternProperties = make(map[string]spec.Schema)
def.PatternProperties["^ty.$"] = *spec.StringProperty()
sw.Definitions["Tag"] = def
res = validator.validateRequiredDefinitions()
assert.NotEmpty(t, res.Errors)

// additional properties
def.PatternProperties = nil
def.AdditionalProperties = &spec.SchemaOrBool{Allows: true}
sw.Definitions["Tag"] = def
res = validator.validateRequiredDefinitions()
assert.Empty(t, res.Errors)

def.AdditionalProperties = &spec.SchemaOrBool{Allows: false}
sw.Definitions["Tag"] = def
res = validator.validateRequiredDefinitions()
assert.NotEmpty(t, res.Errors)
}

func TestValidateParameters(t *testing.T) {
Expand Down

0 comments on commit d3cc868

Please sign in to comment.