diff --git a/motor/rule_applicator.go b/motor/rule_applicator.go index efa3b4eb..0db38165 100644 --- a/motor/rule_applicator.go +++ b/motor/rule_applicator.go @@ -106,16 +106,17 @@ func ApplyRulesToRuleSet(execution *RuleSetExecution) *RuleSetExecutionResult { config.AllowFileLookup = true } - var specInfo, specInfoUnresolved *datamodel.SpecInfo - var doc libopenapi.Document - var err error + doc := execution.Document - // create a new document. - doc, err = libopenapi.NewDocumentWithConfiguration(execution.Spec, docConfig) + if doc == nil { + var err error + // create a new document. + doc, err = libopenapi.NewDocumentWithConfiguration(execution.Spec, docConfig) - if err != nil { - // Done. - return &RuleSetExecutionResult{Errors: []error{err}} + if err != nil { + // Done. + return &RuleSetExecutionResult{Errors: []error{err}} + } } // build model @@ -127,31 +128,30 @@ func ApplyRulesToRuleSet(execution *RuleSetExecution) *RuleSetExecutionResult { case '2': var docModel *libopenapi.DocumentModel[v2.Swagger] docModel, docModelErrors = doc.BuildV2Model() - if execution.SpecInfo == nil { - specInfo = doc.GetSpecInfo() - specInfoUnresolved, _ = datamodel.ExtractSpecInfo(execution.Spec) - } else { - specInfo = execution.SpecInfo - specInfoUnresolved = execution.SpecInfo - } + if docModel != nil { modelIndex = docModel.Index } case '3': var docModel *libopenapi.DocumentModel[v3.Document] docModel, docModelErrors = doc.BuildV3Model() - if execution.SpecInfo == nil { - specInfo = doc.GetSpecInfo() - specInfoUnresolved, _ = datamodel.ExtractSpecInfo(execution.Spec) - } else { - specInfo = execution.SpecInfo - specInfoUnresolved = execution.SpecInfo - } + if docModel != nil { modelIndex = docModel.Index } } + specInfo := execution.SpecInfo + specInfoUnresolved := execution.SpecInfo + if execution.SpecInfo == nil { + specInfo = doc.GetSpecInfo() + spec := execution.Spec + if spec == nil { + spec, _ = doc.Serialize() + } + specInfoUnresolved, _ = datamodel.ExtractSpecInfo(spec) + } + specUnresolved = specInfoUnresolved.RootNode specResolved = specInfo.RootNode @@ -301,6 +301,7 @@ func runRule(ctx ruleContext) { var nodes []*yaml.Node var err error + if givenPath != "$" { nodes, err = utils.FindNodesWithoutDeserializing(ctx.specNode, givenPath) } else { @@ -381,7 +382,6 @@ func buildResults(ctx ruleContext, ruleAction model.RuleAction, nodes []*yaml.No lock.Unlock() } } else { - // iterate through nodes and supply them one at a time so we don't pollute each run for _, node := range nodes { diff --git a/motor/rule_applicator_test.go b/motor/rule_applicator_test.go index bafab6f3..6ebdab6e 100644 --- a/motor/rule_applicator_test.go +++ b/motor/rule_applicator_test.go @@ -2,13 +2,16 @@ package motor import ( "fmt" + "os" + "testing" + "time" + "github.com/daveshanley/vacuum/model" "github.com/daveshanley/vacuum/rulesets" + "github.com/pb33f/libopenapi" + "github.com/pb33f/libopenapi/datamodel" "github.com/stretchr/testify/assert" "gopkg.in/yaml.v3" - "os" - "testing" - "time" ) func TestApplyRules_PostResponseSuccess(t *testing.T) { @@ -46,6 +49,47 @@ func TestApplyRules_PostResponseSuccess(t *testing.T) { assert.Len(t, results.Results, 0) } +func TestApplyRules_PostResponseSuccessWithDocument(t *testing.T) { + + json := `{ + "documentationUrl": "quobix.com", + "rules": { + "hello-test": { + "description": "this is a test for checking basic mechanics", + "recommended": true, + "type": "style", + "given": "$.paths.*.post.responses", + "then": { + "function": "post-response-success", + "functionOptions" : { + "properties": [ + "200", "201", "202", "204" + ] + } + } + } + } +} +` + rc := CreateRuleComposer() + rs, _ := rc.ComposeRuleSet([]byte(json)) + burgershop, _ := os.ReadFile("../model/test_files/burgershop.openapi.yaml") + + var err error + // create a new document. + docConfig := datamodel.NewClosedDocumentConfiguration() + doc, err := libopenapi.NewDocumentWithConfiguration(burgershop, docConfig) + assert.NoError(t, err) + + rse := &RuleSetExecution{ + RuleSet: rs, + Document: doc, + } + results := ApplyRulesToRuleSet(rse) + + assert.Len(t, results.Results, 0) +} + func TestApplyRules_PostResponseFailure(t *testing.T) { // use a bunch of error codes that won't exist.