Skip to content

Commit 6e6e034

Browse files
Mehdi Soleimannejaddaveshanley
Mehdi Soleimannejad
authored andcommitted
fix: ensureAllExpectedParamsInPathAreDefined now iterates over the correct set of maps for all path params
1 parent 62d8842 commit 6e6e034

File tree

2 files changed

+80
-31
lines changed

2 files changed

+80
-31
lines changed

functions/openapi/path_parameters.go

+14-31
Original file line numberDiff line numberDiff line change
@@ -208,20 +208,6 @@ func (pp PathParameters) RunRule(nodes []*yaml.Node, context model.RuleFunctionC
208208
continue
209209
}
210210
if isVerb(r) {
211-
if len(topLevelParams) <= 0 {
212-
if verbLevelParams[r] == nil {
213-
for pe := range pathElements {
214-
err := fmt.Sprintf("`%s` must define parameter `%s` as expected by path `%s`",
215-
strings.ToUpper(r), pe, currentPath)
216-
res := model.BuildFunctionResultString(err)
217-
res.StartNode = startNode
218-
res.EndNode = endNode
219-
res.Path = fmt.Sprintf("$.paths['%s'].%s", currentPath, r)
220-
res.Rule = context.Rule
221-
results = append(results, res)
222-
}
223-
}
224-
}
225211
pp.ensureAllExpectedParamsInPathAreDefined(currentPath, allPathParams,
226212
pathElements, &results, startNode, endNode, context, r)
227213
}
@@ -291,25 +277,22 @@ func (pp PathParameters) ensureAllDefinedPathParamsAreUsedInPath(path string, al
291277
func (pp PathParameters) ensureAllExpectedParamsInPathAreDefined(path string, allPathParams map[string]map[string][]string,
292278
pathElements map[string]bool, results *[]model.RuleFunctionResult, startNode, endNode *yaml.Node,
293279
context model.RuleFunctionContext, verb string) {
294-
var top map[string][]string
295-
280+
var topParams map[string][]string
281+
var verbParams map[string][]string
296282
if allPathParams != nil {
297-
top = allPathParams["top"]
283+
topParams = allPathParams["top"]
284+
verbParams = allPathParams[verb]
298285
}
299-
for k, e := range allPathParams {
300-
if k == "top" {
301-
continue
302-
}
303-
for p := range pathElements {
304-
if !pp.segmentExistsInPathParams(p, e, top) {
305-
err := fmt.Sprintf("`%s` must define parameter `%s` as expected by path `%s`", strings.ToUpper(verb), p, path)
306-
res := model.BuildFunctionResultString(err)
307-
res.StartNode = startNode
308-
res.EndNode = endNode
309-
res.Path = fmt.Sprintf("$.paths['%s']", path)
310-
res.Rule = context.Rule
311-
*results = append(*results, res)
312-
}
286+
// For each expected path parameter, check the top and verb-level defined parameters
287+
for p := range pathElements {
288+
if !pp.segmentExistsInPathParams(p, verbParams, topParams) {
289+
err := fmt.Sprintf("`%s` must define parameter `%s` as expected by path `%s`", strings.ToUpper(verb), p, path)
290+
res := model.BuildFunctionResultString(err)
291+
res.StartNode = startNode
292+
res.EndNode = endNode
293+
res.Path = fmt.Sprintf("$.paths['%s']", path)
294+
res.Rule = context.Rule
295+
*results = append(*results, res)
313296
}
314297
}
315298
}

functions/openapi/path_parameters_test.go

+66
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,72 @@ func TestPathParameters_RunRule(t *testing.T) {
2020
assert.Len(t, res, 0)
2121
}
2222

23+
func TestPathParameters_RunRule_AllParamsInTop(t *testing.T) {
24+
25+
yml := `paths:
26+
/pizza/{type}/{topping}:
27+
parameters:
28+
- name: type
29+
in: path
30+
get:
31+
operationId: get_pizza`
32+
33+
path := "$"
34+
35+
var rootNode yaml.Node
36+
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
37+
assert.NoError(t, mErr)
38+
39+
nodes, _ := utils.FindNodes([]byte(yml), path)
40+
41+
rule := buildOpenApiTestRuleAction(path, "path_parameters", "", nil)
42+
ctx := buildOpenApiTestContext(model.CastToRuleAction(rule.Then), nil)
43+
config := index.CreateOpenAPIIndexConfig()
44+
ctx.Index = index.NewSpecIndexWithConfig(&rootNode, config)
45+
46+
def := PathParameters{}
47+
res := def.RunRule(nodes, ctx)
48+
49+
assert.Len(t, res, 1)
50+
assert.Equal(t, "`GET` must define parameter `topping` as expected by path `/pizza/{type}/{topping}`", res[0].Message)
51+
}
52+
53+
func TestPathParameters_RunRule_VerbsWithDifferentParams(t *testing.T) {
54+
55+
yml := `paths:
56+
/pizza/{type}/{topping}:
57+
parameters:
58+
- name: type
59+
in: path
60+
get:
61+
parameters:
62+
- name: topping
63+
in: path
64+
operationId: get_pizza
65+
post:
66+
operationId: make_pizza
67+
`
68+
69+
path := "$"
70+
71+
var rootNode yaml.Node
72+
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
73+
assert.NoError(t, mErr)
74+
75+
nodes, _ := utils.FindNodes([]byte(yml), path)
76+
77+
rule := buildOpenApiTestRuleAction(path, "path_parameters", "", nil)
78+
ctx := buildOpenApiTestContext(model.CastToRuleAction(rule.Then), nil)
79+
config := index.CreateOpenAPIIndexConfig()
80+
ctx.Index = index.NewSpecIndexWithConfig(&rootNode, config)
81+
82+
def := PathParameters{}
83+
res := def.RunRule(nodes, ctx)
84+
85+
assert.Len(t, res, 1)
86+
assert.Equal(t, "`POST` must define parameter `topping` as expected by path `/pizza/{type}/{topping}`", res[0].Message)
87+
}
88+
2389
func TestPathParameters_RunRule_DuplicatePathCheck(t *testing.T) {
2490

2591
yml := `paths:

0 commit comments

Comments
 (0)