Skip to content

Commit 72a1ccb

Browse files
CLOUDP-304958: IPA rule singleton should have update
1 parent 1758c33 commit 72a1ccb

File tree

5 files changed

+165
-2
lines changed

5 files changed

+165
-2
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import testRule from './__helpers__/testRule';
2+
import { DiagnosticSeverity } from '@stoplight/types';
3+
4+
testRule('xgen-IPA-113-singleton-should-have-update-method', [
5+
{
6+
name: 'valid resources',
7+
document: {
8+
paths: {
9+
'/resource/{exampleId}/singletonOne': {
10+
patch: {},
11+
},
12+
'/resource/{exampleId}/singletonTwo': {
13+
put: {},
14+
},
15+
'/resource/{exampleId}/singletonThree': {
16+
patch: {},
17+
put: {},
18+
},
19+
},
20+
},
21+
errors: [],
22+
},
23+
{
24+
name: 'invalid resource',
25+
document: {
26+
paths: {
27+
'/resource/{exampleId}/singletonOne': {
28+
get: {},
29+
},
30+
'/resource/{exampleId}/singletonTwo': {},
31+
},
32+
},
33+
errors: [
34+
{
35+
code: 'xgen-IPA-113-singleton-should-have-update-method',
36+
message:
37+
'Singleton resources should define the Update method. If this is not a singleton resource, please implement all CRUDL methods.',
38+
path: ['paths', '/resource/{exampleId}/singletonOne'],
39+
severity: DiagnosticSeverity.Warning,
40+
},
41+
{
42+
code: 'xgen-IPA-113-singleton-should-have-update-method',
43+
message:
44+
'Singleton resources should define the Update method. If this is not a singleton resource, please implement all CRUDL methods.',
45+
path: ['paths', '/resource/{exampleId}/singletonTwo'],
46+
severity: DiagnosticSeverity.Warning,
47+
},
48+
],
49+
},
50+
{
51+
name: 'invalid resources with exceptions',
52+
document: {
53+
paths: {
54+
'/resource/{exampleId}/singletonOne': {
55+
get: {},
56+
'x-xgen-IPA-exception': {
57+
'xgen-IPA-113-singleton-should-have-update-method': 'reason',
58+
},
59+
},
60+
'/resource/{exampleId}/singletonTwo': {
61+
'x-xgen-IPA-exception': {
62+
'xgen-IPA-113-singleton-should-have-update-method': 'reason',
63+
},
64+
},
65+
},
66+
},
67+
errors: [],
68+
},
69+
]);

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
functions:
55
- IPA113SingletonHasNoId
66
- IPA113SingletonHasNoDeleteMethod
7+
- IPA113SingletonHasUpdateMethod
78

89
rules:
910
xgen-IPA-113-singleton-must-not-have-id:
@@ -24,7 +25,7 @@ rules:
2425
function: 'IPA113SingletonHasNoId'
2526
xgen-IPA-113-singleton-must-not-have-delete-method:
2627
description: |
27-
Singleton resources must not define the Delete standard method
28+
Singleton resources must not define the Delete standard method.
2829
2930
##### Implementation details
3031
Rule checks for the following conditions:
@@ -35,3 +36,16 @@ rules:
3536
given: '$.paths[*]'
3637
then:
3738
function: 'IPA113SingletonHasNoDeleteMethod'
39+
xgen-IPA-113-singleton-should-have-update-method:
40+
description: |
41+
Singleton resources should define the Update method. Validation for the presence of Get method is covered by IPA-104 (see [xgen-IPA-104-resource-has-GET](https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-104-resource-has-GET)).
42+
43+
##### Implementation details
44+
Rule checks for the following conditions:
45+
- Applies only to singleton resources
46+
- Checks that the resource has the PUT and/or PATCH methods defined
47+
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-113-singleton-should-have-update-method'
48+
severity: warn
49+
given: '$.paths[*]'
50+
then:
51+
function: 'IPA113SingletonHasUpdateMethod'

tools/spectral/ipa/rulesets/README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,13 +485,23 @@ Rule checks for the following conditions:
485485
#### xgen-IPA-113-singleton-must-not-have-delete-method
486486

487487
![warn](https://img.shields.io/badge/warning-yellow)
488-
Singleton resources must not define the Delete standard method
488+
Singleton resources must not define the Delete standard method.
489489

490490
##### Implementation details
491491
Rule checks for the following conditions:
492492
- Applies only to singleton resources
493493
- Checks that the resource does not have a DELETE method defined
494494

495+
#### xgen-IPA-113-singleton-should-have-update-method
496+
497+
![warn](https://img.shields.io/badge/warning-yellow)
498+
Singleton resources should define the Update method. Validation for the presence of Get method is covered by IPA-104 (see [xgen-IPA-104-resource-has-GET](https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-104-resource-has-GET)).
499+
500+
##### Implementation details
501+
Rule checks for the following conditions:
502+
- Applies only to singleton resources
503+
- Checks that the resource has the PUT and/or PATCH methods defined
504+
495505

496506

497507
### IPA-123
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import {
2+
getResourcePathItems,
3+
isSingletonResource,
4+
isResourceCollectionIdentifier,
5+
hasPutMethod,
6+
hasPatchMethod,
7+
} from './utils/resourceEvaluation.js';
8+
import { hasException } from './utils/exceptions.js';
9+
import {
10+
collectAdoption,
11+
collectAndReturnViolation,
12+
collectException,
13+
handleInternalError,
14+
} from './utils/collectionUtils.js';
15+
16+
const RULE_NAME = 'xgen-IPA-113-singleton-should-have-update-method';
17+
const ERROR_MESSAGE =
18+
'Singleton resources should define the Update method. If this is not a singleton resource, please implement all CRUDL methods.';
19+
20+
export default (input, opts, { path, documentInventory }) => {
21+
const oas = documentInventory.resolved;
22+
const resourcePath = path[1];
23+
const resourcePathItems = getResourcePathItems(resourcePath, oas.paths);
24+
25+
if (!(isResourceCollectionIdentifier(resourcePath) && isSingletonResource(resourcePathItems))) {
26+
return;
27+
}
28+
29+
if (hasException(input, RULE_NAME)) {
30+
collectException(input, RULE_NAME, path);
31+
return;
32+
}
33+
34+
const errors = checkViolationsAndReturnErrors(input, path);
35+
if (errors.length !== 0) {
36+
return collectAndReturnViolation(path, RULE_NAME, errors);
37+
}
38+
collectAdoption(path, RULE_NAME);
39+
};
40+
41+
function checkViolationsAndReturnErrors(input, path) {
42+
try {
43+
if (!(hasPutMethod(input) || hasPatchMethod(input))) {
44+
return [{ path, message: ERROR_MESSAGE }];
45+
}
46+
return [];
47+
} catch (e) {
48+
handleInternalError(RULE_NAME, path, e);
49+
}
50+
}

tools/spectral/ipa/rulesets/functions/utils/resourceEvaluation.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,26 @@ export function hasDeleteMethod(pathObject) {
112112
return Object.keys(pathObject).includes('delete');
113113
}
114114

115+
/**
116+
* Checks if a path object has a PUT method
117+
*
118+
* @param pathObject the path object to evaluate
119+
* @returns {boolean}
120+
*/
121+
export function hasPutMethod(pathObject) {
122+
return Object.keys(pathObject).includes('put');
123+
}
124+
125+
/**
126+
* Checks if a path object has a PATCH method
127+
*
128+
* @param pathObject the path object to evaluate
129+
* @returns {boolean}
130+
*/
131+
export function hasPatchMethod(pathObject) {
132+
return Object.keys(pathObject).includes('patch');
133+
}
134+
115135
/**
116136
* Get all path items for a resource based on the path for the resource collection
117137
* For example, resource collection path '/resource' may return path items for ['/resource', '/resource{id}', '/resource{id}:customMethod']

0 commit comments

Comments
 (0)