Skip to content

Commit

Permalink
Addressed #230 and #261
Browse files Browse the repository at this point in the history
Any reference errors found in the index are rendered by vacuum, so now the rule looks both at orphans, and all index reference errors.

Signed-off-by: Dave Shanley <dave@quobix.com>
  • Loading branch information
daveshanley committed May 1, 2023
1 parent 24ab97a commit f5a20b0
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 95 deletions.
14 changes: 14 additions & 0 deletions functions/openapi/unused_component.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,19 @@ func (uc UnusedComponent) RunRule(nodes []*yaml.Node, context model.RuleFunction
})
}

// Check for reverse references. This is where a component is referenced, but it does not exist.
refErrors := context.Index.GetReferenceIndexErrors()
for i := range refErrors {
if rErr, ok := refErrors[i].(*index.IndexingError); ok {
results = append(results, model.RuleFunctionResult{
Message: rErr.Err.Error(),
StartNode: rErr.Node,
EndNode: rErr.Node,
Path: rErr.Path,
Rule: context.Rule,
})
}
}

return results
}
189 changes: 95 additions & 94 deletions functions/openapi/unused_component_test.go
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
package openapi

import (
"github.com/daveshanley/vacuum/model"
"github.com/pb33f/libopenapi/datamodel"
"github.com/pb33f/libopenapi/index"
"github.com/pb33f/libopenapi/utils"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
"github.com/daveshanley/vacuum/model"
"github.com/pb33f/libopenapi/datamodel"
"github.com/pb33f/libopenapi/index"
"github.com/pb33f/libopenapi/utils"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
)

func TestUnusedComponent_GetSchema(t *testing.T) {
def := UnusedComponent{}
assert.Equal(t, "unused_component", def.GetSchema().Name)
def := UnusedComponent{}
assert.Equal(t, "unused_component", def.GetSchema().Name)
}

func TestUnusedComponent_RunRule(t *testing.T) {
def := UnusedComponent{}
res := def.RunRule(nil, model.RuleFunctionContext{})
assert.Len(t, res, 0)
def := UnusedComponent{}
res := def.RunRule(nil, model.RuleFunctionContext{})
assert.Len(t, res, 0)
}

func TestUnusedComponent_RunRule_Success(t *testing.T) {

yml := `paths:
yml := `paths:
/naughty/{puppy}:
parameters:
- $ref: '#/components/parameters/Chewy'
Expand All @@ -46,28 +46,28 @@ components:
in: query
name: chewy`

path := "$"
path := "$"

var rootNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)
var rootNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)

nodes, _ := utils.FindNodes([]byte(yml), path)
nodes, _ := utils.FindNodes([]byte(yml), path)

rule := buildOpenApiTestRuleAction(path, "unused_component", "", nil)
ctx := buildOpenApiTestContext(model.CastToRuleAction(rule.Then), nil)
config := index.CreateOpenAPIIndexConfig()
ctx.Index = index.NewSpecIndexWithConfig(&rootNode, config)
rule := buildOpenApiTestRuleAction(path, "unused_component", "", nil)
ctx := buildOpenApiTestContext(model.CastToRuleAction(rule.Then), nil)
config := index.CreateOpenAPIIndexConfig()
ctx.Index = index.NewSpecIndexWithConfig(&rootNode, config)

def := UnusedComponent{}
res := def.RunRule(nodes, ctx)
def := UnusedComponent{}
res := def.RunRule(nodes, ctx)

assert.Len(t, res, 0)
assert.Len(t, res, 0)
}

func TestUnusedComponent_RunRule_SuccessSwaggerSecurity(t *testing.T) {

yml := `swagger: 2.0
yml := `swagger: 2.0
securityDefinitions:
basicAuth:
type: basic
Expand All @@ -85,30 +85,31 @@ paths:
security:
- sessionAuth: []`

path := "$"
path := "$"

var rootNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)
var rootNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)

nodes, _ := utils.FindNodes([]byte(yml), path)
nodes, _ := utils.FindNodes([]byte(yml), path)

rule := buildOpenApiTestRuleAction(path, "unused_component", "", nil)
ctx := buildOpenApiTestContext(model.CastToRuleAction(rule.Then), nil)
config := index.CreateOpenAPIIndexConfig()
ctx.Index = index.NewSpecIndexWithConfig(&rootNode, config)
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
ctx.SpecInfo = info
rule := buildOpenApiTestRuleAction(path, "unused_component", "", nil)
ctx := buildOpenApiTestContext(model.CastToRuleAction(rule.Then), nil)
config := index.CreateOpenAPIIndexConfig()
ctx.Index = index.NewSpecIndexWithConfig(&rootNode, config)
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
ctx.SpecInfo = info
ctx.Rule = &rule

def := UnusedComponent{}
res := def.RunRule(nodes, ctx)
def := UnusedComponent{}
res := def.RunRule(nodes, ctx)

assert.Len(t, res, 0)
assert.Len(t, res, 0)
}

func TestUnusedComponent_RunRule_SuccessOpenAPISecurity(t *testing.T) {

yml := `openapi: 3.0.1
yml := `openapi: 3.0.1
info:
description: A test spec with a security def that is not a ref!
security:
Expand All @@ -117,30 +118,30 @@ components:
securitySchemes:
SomeSecurity:
description: A secure way to do things and stuff.`
path := "$"
path := "$"

var rootNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)
var rootNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)

nodes, _ := utils.FindNodes([]byte(yml), path)
nodes, _ := utils.FindNodes([]byte(yml), path)

rule := buildOpenApiTestRuleAction(path, "unused_component", "", nil)
ctx := buildOpenApiTestContext(model.CastToRuleAction(rule.Then), nil)
config := index.CreateOpenAPIIndexConfig()
ctx.Index = index.NewSpecIndexWithConfig(&rootNode, config)
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
ctx.SpecInfo = info
rule := buildOpenApiTestRuleAction(path, "unused_component", "", nil)
ctx := buildOpenApiTestContext(model.CastToRuleAction(rule.Then), nil)
config := index.CreateOpenAPIIndexConfig()
ctx.Index = index.NewSpecIndexWithConfig(&rootNode, config)
info, _ := datamodel.ExtractSpecInfo([]byte(yml))
ctx.SpecInfo = info

def := UnusedComponent{}
res := def.RunRule(nodes, ctx)
def := UnusedComponent{}
res := def.RunRule(nodes, ctx)

assert.Len(t, res, 0)
assert.Len(t, res, 0)
}

func TestUnusedComponent_RunRule_Success_Fail_TwoMissing_Two_Undefined(t *testing.T) {

yml := `parameters:
yml := `parameters:
Chewy:
description: chewy
in: query
Expand All @@ -165,28 +166,28 @@ components:
Kitty:
$ref: '#/components/schemas/Puppy' `

path := "$"
path := "$"

var rootNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)
var rootNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)

nodes, _ := utils.FindNodes([]byte(yml), path)
nodes, _ := utils.FindNodes([]byte(yml), path)

rule := buildOpenApiTestRuleAction(path, "unused_component", "", nil)
ctx := buildOpenApiTestContext(model.CastToRuleAction(rule.Then), nil)
config := index.CreateOpenAPIIndexConfig()
ctx.Index = index.NewSpecIndexWithConfig(&rootNode, config)
rule := buildOpenApiTestRuleAction(path, "unused_component", "", nil)
ctx := buildOpenApiTestContext(model.CastToRuleAction(rule.Then), nil)
config := index.CreateOpenAPIIndexConfig()
ctx.Index = index.NewSpecIndexWithConfig(&rootNode, config)

def := UnusedComponent{}
res := def.RunRule(nodes, ctx)
def := UnusedComponent{}
res := def.RunRule(nodes, ctx)

assert.Len(t, res, 2)
assert.Len(t, res, 2)
}

func TestUnusedComponent_RunRule_Success_Fail_Four_Undefined(t *testing.T) {

yml := `paths:
yml := `paths:
/naughty/{puppy}:
parameters:
- $ref: '#/components/parameters/Chewy'
Expand Down Expand Up @@ -222,28 +223,28 @@ components:
in: query
name: chewy`

path := "$"
path := "$"

var rootNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)
var rootNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)

nodes, _ := utils.FindNodes([]byte(yml), path)
nodes, _ := utils.FindNodes([]byte(yml), path)

rule := buildOpenApiTestRuleAction(path, "unused_component", "", nil)
ctx := buildOpenApiTestContext(model.CastToRuleAction(rule.Then), nil)
config := index.CreateOpenAPIIndexConfig()
ctx.Index = index.NewSpecIndexWithConfig(&rootNode, config)
rule := buildOpenApiTestRuleAction(path, "unused_component", "", nil)
ctx := buildOpenApiTestContext(model.CastToRuleAction(rule.Then), nil)
config := index.CreateOpenAPIIndexConfig()
ctx.Index = index.NewSpecIndexWithConfig(&rootNode, config)

def := UnusedComponent{}
res := def.RunRule(nodes, ctx)
def := UnusedComponent{}
res := def.RunRule(nodes, ctx)

assert.Len(t, res, 4)
assert.Len(t, res, 4)
}

func TestUnusedComponent_RunRule_Success_PolymorphicCheck(t *testing.T) {

yml := `paths:
yml := `paths:
/naughty/{puppy}:
get:
responses:
Expand Down Expand Up @@ -280,21 +281,21 @@ components:
type: string
description: bunny`

path := "$"
path := "$"

var rootNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)
var rootNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)

nodes, _ := utils.FindNodes([]byte(yml), path)
nodes, _ := utils.FindNodes([]byte(yml), path)

rule := buildOpenApiTestRuleAction(path, "unused_component", "", nil)
ctx := buildOpenApiTestContext(model.CastToRuleAction(rule.Then), nil)
config := index.CreateOpenAPIIndexConfig()
ctx.Index = index.NewSpecIndexWithConfig(&rootNode, config)
rule := buildOpenApiTestRuleAction(path, "unused_component", "", nil)
ctx := buildOpenApiTestContext(model.CastToRuleAction(rule.Then), nil)
config := index.CreateOpenAPIIndexConfig()
ctx.Index = index.NewSpecIndexWithConfig(&rootNode, config)

def := UnusedComponent{}
res := def.RunRule(nodes, ctx)
def := UnusedComponent{}
res := def.RunRule(nodes, ctx)

assert.Len(t, res, 0)
assert.Len(t, res, 0)
}
2 changes: 1 addition & 1 deletion motor/rule_applicator.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ func ApplyRulesToRuleSet(execution *RuleSetExecution) *RuleSetExecutionResult {

// create new configurations
config := index.CreateClosedAPIIndexConfig()
config.AllowFileLookup = true
docConfig := datamodel.NewClosedDocumentConfiguration()

if execution.Base != "" {
Expand All @@ -96,7 +97,6 @@ func ApplyRulesToRuleSet(execution *RuleSetExecution) *RuleSetExecutionResult {
config.BasePath = execution.Base
docConfig.BasePath = execution.Base
}
config.AllowFileLookup = true
config.AllowRemoteLookup = true
}

Expand Down

0 comments on commit f5a20b0

Please sign in to comment.