-
-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Checks all segments of a path are not empty and kebab case.
- Loading branch information
1 parent
0da18ba
commit ac2452e
Showing
8 changed files
with
171 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// Copyright 2022 Dave Shanley / Quobix | ||
// SPDX-License-Identifier: MIT | ||
|
||
package openapi | ||
|
||
import ( | ||
"fmt" | ||
"github.com/daveshanley/vacuum/model" | ||
"gopkg.in/yaml.v3" | ||
"regexp" | ||
"strings" | ||
) | ||
|
||
// PathsKebabCase Checks to ensure each segment of a path is using kebab case. | ||
type PathsKebabCase struct { | ||
} | ||
|
||
// GetSchema returns a model.RuleFunctionSchema defining the schema of the VerbsInPath rule. | ||
func (vp PathsKebabCase) GetSchema() model.RuleFunctionSchema { | ||
return model.RuleFunctionSchema{Name: "noVerbsInPath"} | ||
} | ||
|
||
// RunRule will execute the PathsKebabCase rule, based on supplied context and a supplied []*yaml.Node slice. | ||
func (vp PathsKebabCase) RunRule(nodes []*yaml.Node, context model.RuleFunctionContext) []model.RuleFunctionResult { | ||
|
||
if len(nodes) <= 0 { | ||
return nil | ||
} | ||
|
||
var results []model.RuleFunctionResult | ||
|
||
ops := context.Index.GetPathsNode() | ||
|
||
var opPath string | ||
|
||
if ops != nil { | ||
for i, op := range ops.Content { | ||
if i%2 == 0 { | ||
opPath = op.Value | ||
continue | ||
} | ||
path := fmt.Sprintf("$.paths.%s", opPath) | ||
notKebab, segments := checkPathCase(opPath) | ||
if notKebab { | ||
results = append(results, model.RuleFunctionResult{ | ||
Message: fmt.Sprintf("Path segments `%s` do not use kebab-case", strings.Join(segments, "`, `")), | ||
StartNode: op, | ||
EndNode: op, | ||
Path: path, | ||
Rule: context.Rule, | ||
}) | ||
} | ||
} | ||
} | ||
return results | ||
} | ||
|
||
var pathKebabCaseRegex, _ = regexp.Compile("^[{}a-z\\d-.]+$") | ||
|
||
func checkPathCase(path string) (bool, []string) { | ||
segs := strings.Split(path, "/")[1:] | ||
var found []string | ||
for _, seg := range segs { | ||
if !pathKebabCaseRegex.MatchString(seg) { | ||
// check if it's a variable, if so, skip | ||
if seg == "" { | ||
found = append(found, "!empty segment!") | ||
continue | ||
} | ||
if seg[0] == '{' && seg[len(seg)-1] == '}' { | ||
continue | ||
} | ||
found = append(found, seg) | ||
} | ||
} | ||
if len(found) > 0 { | ||
return true, found | ||
} | ||
return false, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package openapi | ||
|
||
import ( | ||
"github.com/daveshanley/vacuum/model" | ||
"github.com/pb33f/libopenapi/index" | ||
"github.com/pb33f/libopenapi/utils" | ||
"github.com/stretchr/testify/assert" | ||
"gopkg.in/yaml.v3" | ||
"testing" | ||
) | ||
|
||
func TestPathsKebabCase_GetSchema(t *testing.T) { | ||
def := PathsKebabCase{} | ||
assert.Equal(t, "noVerbsInPath", def.GetSchema().Name) | ||
} | ||
|
||
func TestPathsKebabCase_RunRule(t *testing.T) { | ||
def := PathsKebabCase{} | ||
res := def.RunRule(nil, model.RuleFunctionContext{}) | ||
assert.Len(t, res, 0) | ||
} | ||
|
||
func TestPathsKebabCase_Success(t *testing.T) { | ||
|
||
yml := `openapi: 3.0.0 | ||
paths: | ||
'/woah/slow-down/you-move-too-fast': | ||
get: | ||
summary: not bad | ||
'/youHave/got/to/make/the_morning last': | ||
get: | ||
summary: bad path | ||
'/just-kicking/down/the/cobble-stones': | ||
get: | ||
summary: nice | ||
'/looking~1/{forFun}/AND/feeling_groovy': | ||
get: | ||
summary: this is also doomed | ||
'/ok//ok': | ||
get: | ||
summary: should we complain?` | ||
|
||
path := "$" | ||
|
||
var rootNode yaml.Node | ||
err := yaml.Unmarshal([]byte(yml), &rootNode) | ||
|
||
assert.NoError(t, err) | ||
nodes, _ := utils.FindNodes([]byte(yml), path) | ||
|
||
rule := buildOpenApiTestRuleAction(path, "verbsInPath", "", nil) | ||
ctx := buildOpenApiTestContext(model.CastToRuleAction(rule.Then), nil) | ||
ctx.Rule = &rule | ||
ctx.Index = index.NewSpecIndex(&rootNode) | ||
|
||
def := PathsKebabCase{} | ||
res := def.RunRule(nodes, ctx) | ||
|
||
assert.Len(t, res, 3) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters