Skip to content

Commit de5a876

Browse files
committed
fix: path-parameters-defined rule false positive
1 parent 829eb2a commit de5a876

File tree

2 files changed

+155
-0
lines changed

2 files changed

+155
-0
lines changed

.changeset/rotten-news-battle.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@redocly/openapi-core": patch
3+
---
4+
5+
Fixed false positive reports for path parameters in callback operations by the `path-parameters-defined` rule.

packages/core/src/rules/common/__tests__/path-params-defined.test.ts

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,4 +200,154 @@ describe('Oas3 path-params-defined', () => {
200200

201201
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);
202202
});
203+
204+
it('should not report on undefined params in callback for next operation in same path item', async () => {
205+
const document = parseYamlToDocument(
206+
outdent`
207+
openapi: 3.1.1
208+
paths:
209+
/projects/{projectId}:
210+
post:
211+
operationId: createProject
212+
parameters:
213+
- name: projectId
214+
in: path
215+
required: true
216+
schema:
217+
type: string
218+
callbacks:
219+
onEvent:
220+
'{$request.body#/callbackUrl}':
221+
post:
222+
summary: Callback endpoint
223+
responses:
224+
'200':
225+
description: OK
226+
requestBody:
227+
content:
228+
application/json:
229+
schema:
230+
type: object
231+
properties:
232+
callbackUrl:
233+
type: string
234+
responses:
235+
'201':
236+
description: Created
237+
238+
patch:
239+
operationId: updateProject
240+
parameters:
241+
- name: projectId
242+
in: path
243+
required: true
244+
schema:
245+
type: string
246+
responses:
247+
'200':
248+
description: OK
249+
`,
250+
'foobar.yaml'
251+
);
252+
253+
const results = await lintDocument({
254+
externalRefResolver: new BaseResolver(),
255+
document,
256+
config: await createConfig({ rules: { 'path-params-defined': 'error' } }),
257+
});
258+
259+
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);
260+
});
261+
262+
it('should fail on undefined or missing params in callback', async () => {
263+
const document = parseYamlToDocument(
264+
outdent`
265+
openapi: 3.1.1
266+
paths:
267+
/projects/{projectId}:
268+
post:
269+
operationId: createProject
270+
parameters:
271+
- name: projectId
272+
in: path
273+
required: true
274+
schema:
275+
type: string
276+
callbacks:
277+
onEvent:
278+
'{$request.body#/callbackUrl/{missingId}}':
279+
post:
280+
parameters:
281+
- name: notDefinedId
282+
in: path
283+
required: true
284+
schema:
285+
type: string
286+
responses:
287+
'200':
288+
description: OK
289+
requestBody:
290+
content:
291+
application/json:
292+
schema:
293+
type: object
294+
properties:
295+
callbackUrl:
296+
type: string
297+
responses:
298+
'201':
299+
description: Created
300+
301+
patch:
302+
operationId: updateProject
303+
parameters:
304+
- name: projectId
305+
in: path
306+
required: true
307+
schema:
308+
type: string
309+
responses:
310+
'200':
311+
description: OK
312+
`,
313+
'foobar.yaml'
314+
);
315+
316+
const results = await lintDocument({
317+
externalRefResolver: new BaseResolver(),
318+
document,
319+
config: await createConfig({ rules: { 'path-params-defined': 'error' } }),
320+
});
321+
322+
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
323+
[
324+
{
325+
"location": [
326+
{
327+
"pointer": "#/paths/~1projects~1{projectId}/post/callbacks/onEvent/{$request.body#~1callbackUrl~1{missingId}}/post/parameters/0/name",
328+
"reportOnKey": false,
329+
"source": "foobar.yaml",
330+
},
331+
],
332+
"message": "Path parameter \`notDefinedId\` is not used in the path \`{$request.body#/callbackUrl/{missingId}}\`.",
333+
"ruleId": "path-params-defined",
334+
"severity": "error",
335+
"suggest": [],
336+
},
337+
{
338+
"location": [
339+
{
340+
"pointer": "#/paths/~1projects~1{projectId}/post/callbacks/onEvent/{$request.body#~1callbackUrl~1{missingId}}/post/parameters",
341+
"reportOnKey": true,
342+
"source": "foobar.yaml",
343+
},
344+
],
345+
"message": "The operation does not define the path parameter \`{missingId}\` expected by path \`{$request.body#/callbackUrl/{missingId}}\`.",
346+
"ruleId": "path-params-defined",
347+
"severity": "error",
348+
"suggest": [],
349+
},
350+
]
351+
`);
352+
});
203353
});

0 commit comments

Comments
 (0)