Skip to content

Commit 120daa6

Browse files
CLOUDP-271995: Adds rule for update method must not have query param
1 parent 4f349b6 commit 120daa6

File tree

5 files changed

+112
-7
lines changed

5 files changed

+112
-7
lines changed

tools/spectral/ipa/ipa-spectral.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ extends:
44
- ./rulesets/IPA-104.yaml
55
- ./rulesets/IPA-105.yaml
66
- ./rulesets/IPA-106.yaml
7+
- ./rulesets/IPA-107.yaml
78
- ./rulesets/IPA-108.yaml
89
- ./rulesets/IPA-109.yaml
910
- ./rulesets/IPA-113.yaml

tools/spectral/ipa/rulesets/IPA-106.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ rules:
2828
given: '$.paths[*].post'
2929
then:
3030
function: 'createMethodShouldNotHaveQueryParameters'
31+
ignoredValues: [ 'pretty', 'envelope' ]
3132
xgen-IPA-106-create-method-request-body-is-get-method-response:
3233
description: >-
3334
Request body content of the Create method and response content of the Get method should refer to the same resource. http://go/ipa/106
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# IPA-107: Update
2+
# http://go/ipa/107
3+
4+
functions:
5+
- updateMethodMustNotHaveQueryParams
6+
7+
rules:
8+
xgen-IPA-107-put-must-not-have-query-params:
9+
description: >-
10+
Update operations must not accept query parameters. http://go/ipa/107
11+
message: '{{error}} http://go/ipa/107'
12+
severity: warn
13+
given: '$.paths[*].put'
14+
then:
15+
function: 'updateMethodMustNotHaveQueryParams'
16+
functionOptions:
17+
ignoredValues: [ 'pretty', 'envelope' ]
18+
xgen-IPA-107-patch-must-not-have-query-params:
19+
description: >-
20+
Update operations must not accept query parameters. http://go/ipa/107
21+
message: '{{error}} http://go/ipa/107'
22+
severity: warn
23+
given: '$.paths[*].patch'
24+
then:
25+
function: 'updateMethodMustNotHaveQueryParams'
26+
functionOptions:
27+
ignoredValues: [ 'pretty', 'envelope' ]

tools/spectral/ipa/rulesets/functions/createMethodShouldNotHaveQueryParameters.js

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,14 @@ import {
1515
const RULE_NAME = 'xgen-IPA-106-create-method-should-not-have-query-parameters';
1616
const ERROR_MESSAGE = 'Create operations should not have query parameters.';
1717

18-
const ignoredParameters = ['envelope', 'pretty'];
19-
20-
export default (input, _, { path, documentInventory }) => {
18+
/**
19+
* Create operations should not have query parameters.
20+
*
21+
* @param {object} input - The create operation object
22+
* @param {{ignoredValues: string[]}} opts - Array of ignored query parameters
23+
* @param {object} context - The context object containing the path and document
24+
*/
25+
export default (input, opts, { path, documentInventory }) => {
2126
const resourcePath = path[1];
2227
const oas = documentInventory.resolved;
2328
const resourcePaths = getResourcePathItems(resourcePath, oas.paths);
@@ -37,21 +42,23 @@ export default (input, _, { path, documentInventory }) => {
3742
return;
3843
}
3944

40-
const errors = checkViolationsAndReturnErrors(postMethod.parameters, path);
45+
const errors = checkViolationsAndReturnErrors(postMethod.parameters, path, opts);
4146
if (errors.length !== 0) {
4247
return collectAndReturnViolation(path, RULE_NAME, errors);
4348
}
4449
collectAdoption(path, RULE_NAME);
4550
};
4651

47-
function checkViolationsAndReturnErrors(postMethodParameters, path) {
52+
function checkViolationsAndReturnErrors(postMethodParameters, path, opts) {
4853
const errors = [];
4954
try {
55+
const ignoredValues = opts?.ignoredValues || [];
56+
5057
for (const parameter of postMethodParameters) {
51-
if (parameter.in === 'query' && !ignoredParameters.includes(parameter.name)) {
58+
if (parameter.in === 'query' && !ignoredValues.includes(parameter.name)) {
5259
errors.push({
5360
path: path,
54-
message: `Input parameter [${parameter.name}]: ${ERROR_MESSAGE}`,
61+
message: `${ERROR_MESSAGE}. Found [${parameter.name}] `,
5562
});
5663
}
5764
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { hasException } from './utils/exceptions.js';
2+
import {
3+
collectAdoption,
4+
collectAndReturnViolation,
5+
collectException,
6+
handleInternalError,
7+
} from './utils/collectionUtils.js';
8+
import {
9+
getResourcePathItems,
10+
isResourceCollectionIdentifier,
11+
isSingleResourceIdentifier,
12+
isSingletonResource,
13+
} from './utils/resourceEvaluation.js';
14+
15+
const ERROR_MESSAGE = 'Update operations must not have query parameters.';
16+
17+
/**
18+
* Update operations must not have query parameters.
19+
*
20+
* @param {object} input - The update operation object
21+
* @param {{ignoredValues: string[]}} opts - Array of ignored query parameters
22+
* @param {object} context - The context object containing the path, document and rule
23+
*/
24+
export default (input, opts, { path, documentInventory, rule }) => {
25+
const resourcePath = path[1];
26+
const oas = documentInventory.resolved;
27+
const resourcePathItems = getResourcePathItems(resourcePath, oas.paths);
28+
29+
if (
30+
!isSingleResourceIdentifier(resourcePath) ||
31+
(isResourceCollectionIdentifier(resourcePath) && !isSingletonResource(resourcePathItems))
32+
) {
33+
return;
34+
}
35+
36+
if (!input.parameters || input.parameters.length === 0) {
37+
return;
38+
}
39+
40+
if (hasException(input, rule)) {
41+
collectException(input, rule, path);
42+
return;
43+
}
44+
45+
const errors = checkViolationsAndReturnErrors(input.parameters, path, rule, opts);
46+
if (errors.length !== 0) {
47+
return collectAndReturnViolation(path, rule, errors);
48+
}
49+
collectAdoption(path, rule);
50+
};
51+
52+
function checkViolationsAndReturnErrors(postMethodParameters, path, rule, opts) {
53+
const errors = [];
54+
try {
55+
const ignoredValues = opts?.ignoredValues || [];
56+
57+
for (const parameter of postMethodParameters) {
58+
if (parameter.in === 'query' && !ignoredValues.includes(parameter.name)) {
59+
errors.push({
60+
path: path,
61+
message: `${ERROR_MESSAGE}. Found [${parameter.name}] `,
62+
});
63+
}
64+
}
65+
return errors;
66+
} catch (e) {
67+
handleInternalError(rule, path, e);
68+
}
69+
}

0 commit comments

Comments
 (0)