Skip to content

Commit

Permalink
fix: ensureAllExpectedParamsInPathAreDefined now iterates over the co…
Browse files Browse the repository at this point in the history
…rrect set of maps for all path params
  • Loading branch information
mehdi-sol authored and daveshanley committed Jan 30, 2024
1 parent 62d8842 commit 6e6e034
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 31 deletions.
45 changes: 14 additions & 31 deletions functions/openapi/path_parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,20 +208,6 @@ func (pp PathParameters) RunRule(nodes []*yaml.Node, context model.RuleFunctionC
continue
}
if isVerb(r) {
if len(topLevelParams) <= 0 {
if verbLevelParams[r] == nil {
for pe := range pathElements {
err := fmt.Sprintf("`%s` must define parameter `%s` as expected by path `%s`",
strings.ToUpper(r), pe, currentPath)
res := model.BuildFunctionResultString(err)
res.StartNode = startNode
res.EndNode = endNode
res.Path = fmt.Sprintf("$.paths['%s'].%s", currentPath, r)
res.Rule = context.Rule
results = append(results, res)
}
}
}
pp.ensureAllExpectedParamsInPathAreDefined(currentPath, allPathParams,
pathElements, &results, startNode, endNode, context, r)
}
Expand Down Expand Up @@ -291,25 +277,22 @@ func (pp PathParameters) ensureAllDefinedPathParamsAreUsedInPath(path string, al
func (pp PathParameters) ensureAllExpectedParamsInPathAreDefined(path string, allPathParams map[string]map[string][]string,
pathElements map[string]bool, results *[]model.RuleFunctionResult, startNode, endNode *yaml.Node,
context model.RuleFunctionContext, verb string) {
var top map[string][]string

var topParams map[string][]string
var verbParams map[string][]string
if allPathParams != nil {
top = allPathParams["top"]
topParams = allPathParams["top"]
verbParams = allPathParams[verb]
}
for k, e := range allPathParams {
if k == "top" {
continue
}
for p := range pathElements {
if !pp.segmentExistsInPathParams(p, e, top) {
err := fmt.Sprintf("`%s` must define parameter `%s` as expected by path `%s`", strings.ToUpper(verb), p, path)
res := model.BuildFunctionResultString(err)
res.StartNode = startNode
res.EndNode = endNode
res.Path = fmt.Sprintf("$.paths['%s']", path)
res.Rule = context.Rule
*results = append(*results, res)
}
// For each expected path parameter, check the top and verb-level defined parameters
for p := range pathElements {
if !pp.segmentExistsInPathParams(p, verbParams, topParams) {
err := fmt.Sprintf("`%s` must define parameter `%s` as expected by path `%s`", strings.ToUpper(verb), p, path)
res := model.BuildFunctionResultString(err)
res.StartNode = startNode
res.EndNode = endNode
res.Path = fmt.Sprintf("$.paths['%s']", path)
res.Rule = context.Rule
*results = append(*results, res)
}
}
}
Expand Down
66 changes: 66 additions & 0 deletions functions/openapi/path_parameters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,72 @@ func TestPathParameters_RunRule(t *testing.T) {
assert.Len(t, res, 0)
}

func TestPathParameters_RunRule_AllParamsInTop(t *testing.T) {

yml := `paths:
/pizza/{type}/{topping}:
parameters:
- name: type
in: path
get:
operationId: get_pizza`

path := "$"

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

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

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

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

assert.Len(t, res, 1)
assert.Equal(t, "`GET` must define parameter `topping` as expected by path `/pizza/{type}/{topping}`", res[0].Message)
}

func TestPathParameters_RunRule_VerbsWithDifferentParams(t *testing.T) {

yml := `paths:
/pizza/{type}/{topping}:
parameters:
- name: type
in: path
get:
parameters:
- name: topping
in: path
operationId: get_pizza
post:
operationId: make_pizza
`

path := "$"

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

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

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

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

assert.Len(t, res, 1)
assert.Equal(t, "`POST` must define parameter `topping` as expected by path `/pizza/{type}/{topping}`", res[0].Message)
}

func TestPathParameters_RunRule_DuplicatePathCheck(t *testing.T) {

yml := `paths:
Expand Down

0 comments on commit 6e6e034

Please sign in to comment.