Skip to content

Commit 7ba7b40

Browse files
CLOUDP-302985: Add rule xgen-IPA-104-get-method-no-request-body (#494)
1 parent a86815c commit 7ba7b40

File tree

4 files changed

+151
-0
lines changed

4 files changed

+151
-0
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import testRule from './__helpers__/testRule';
2+
import { DiagnosticSeverity } from '@stoplight/types';
3+
4+
testRule('xgen-IPA-104-get-method-no-request-body', [
5+
{
6+
name: 'valid GET without body',
7+
document: {
8+
paths: {
9+
'/resource/{id}': {
10+
get: {
11+
responses: {
12+
200: {},
13+
},
14+
},
15+
},
16+
'/resource/{id}/singleton': {
17+
get: {
18+
responses: {
19+
200: {},
20+
},
21+
},
22+
},
23+
},
24+
},
25+
errors: [],
26+
},
27+
{
28+
name: 'invalid GET with body',
29+
document: {
30+
paths: {
31+
'/resource/{id}': {
32+
get: {
33+
responses: {
34+
200: {},
35+
},
36+
requestBody: {
37+
content: {
38+
'application/vnd.atlas.2024-08-05+json': {
39+
schema: { type: 'object' },
40+
},
41+
},
42+
},
43+
},
44+
},
45+
'/resource/{id}/singleton': {
46+
get: {
47+
requestBody: {
48+
content: {
49+
'application/vnd.atlas.2024-08-05+json': {
50+
schema: { type: 'object' },
51+
},
52+
},
53+
},
54+
responses: {
55+
200: {},
56+
},
57+
},
58+
},
59+
},
60+
},
61+
errors: [
62+
{
63+
code: 'xgen-IPA-104-get-method-no-request-body',
64+
message: 'The Get method must not include a request body. http://go/ipa/104',
65+
path: ['paths', '/resource/{id}', 'get'],
66+
severity: DiagnosticSeverity.Warning,
67+
},
68+
{
69+
code: 'xgen-IPA-104-get-method-no-request-body',
70+
message: 'The Get method must not include a request body. http://go/ipa/104',
71+
path: ['paths', '/resource/{id}/singleton', 'get'],
72+
severity: DiagnosticSeverity.Warning,
73+
},
74+
],
75+
},
76+
{
77+
name: 'invalid with exception',
78+
document: {
79+
paths: {
80+
'/resource/{id}': {
81+
get: {
82+
'x-xgen-IPA-exception': {
83+
'xgen-IPA-104-get-method-no-request-body': 'reason',
84+
},
85+
requestBody: {
86+
content: {
87+
'application/json': {
88+
schema: { type: 'object' },
89+
},
90+
},
91+
},
92+
},
93+
},
94+
},
95+
},
96+
errors: [],
97+
},
98+
]);

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ functions:
66
- getMethodReturnsSingleResource
77
- getMethodReturnsResponseSuffixedObject
88
- getResponseCodeShouldBe200OK
9+
- getMethodHasNoRequestBody
910

1011
rules:
1112
xgen-IPA-104-resource-has-GET:
@@ -38,3 +39,10 @@ rules:
3839
then:
3940
field: '@key'
4041
function: 'getMethodReturnsResponseSuffixedObject'
42+
xgen-IPA-104-get-method-no-request-body:
43+
description: 'The Get method request must not include a body. http://go/ipa/104'
44+
message: '{{error}} http://go/ipa/104'
45+
severity: warn
46+
given: '$.paths[*].get'
47+
then:
48+
function: 'getMethodHasNoRequestBody'

tools/spectral/ipa/rulesets/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ For rule definitions, see [IPA-104.yaml](https://github.com/mongodb/openapi/blob
3434
| xgen-IPA-104-get-method-returns-single-resource | The purpose of the Get method is to return data from a single resource. http://go/ipa/104 | warn |
3535
| xgen-IPA-104-get-method-response-code-is-200 | The Get method must return a 200 OK response. http://go/ipa/104 | warn |
3636
| xgen-IPA-104-get-method-returns-response-suffixed-object | The Get method of a resource should return a "Response" suffixed object. http://go/ipa/104 | warn |
37+
| xgen-IPA-104-get-method-no-request-body | The Get method request must not include a body. http://go/ipa/104 | warn |
3738

3839
### IPA-106
3940

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { hasException } from './utils/exceptions.js';
2+
import { collectAdoption, collectAndReturnViolation, collectException } from './utils/collectionUtils.js';
3+
import {
4+
getResourcePathItems,
5+
isResourceCollectionIdentifier,
6+
isSingleResourceIdentifier,
7+
isSingletonResource,
8+
} from './utils/resourceEvaluation.js';
9+
10+
const RULE_NAME = 'xgen-IPA-104-get-method-no-request-body';
11+
const ERROR_MESSAGE = 'The Get method must not include a request body.';
12+
13+
export default (input, _, { path, documentInventory }) => {
14+
const resourcePath = path[1];
15+
const oas = documentInventory.resolved;
16+
17+
if (
18+
!isSingleResourceIdentifier(resourcePath) &&
19+
!(
20+
isResourceCollectionIdentifier(resourcePath) && isSingletonResource(getResourcePathItems(resourcePath, oas.paths))
21+
)
22+
) {
23+
return;
24+
}
25+
26+
if (hasException(input, RULE_NAME)) {
27+
collectException(input, RULE_NAME, path);
28+
return;
29+
}
30+
31+
const errors = checkViolationsAndReturnErrors(input, path);
32+
33+
if (errors.length !== 0) {
34+
return collectAndReturnViolation(path, RULE_NAME, errors);
35+
}
36+
collectAdoption(path, RULE_NAME);
37+
};
38+
39+
function checkViolationsAndReturnErrors(getOperationObject, path) {
40+
if (getOperationObject.requestBody) {
41+
return [{ path, message: ERROR_MESSAGE }];
42+
}
43+
return [];
44+
}

0 commit comments

Comments
 (0)