Skip to content

Commit a05e03e

Browse files
CLOUDP-304940: IPA 106: Create : The response body should be the same resource of the Get method (#544)
1 parent cd4e085 commit a05e03e

File tree

6 files changed

+478
-5
lines changed

6 files changed

+478
-5
lines changed
Lines changed: 350 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,350 @@
1+
import testRule from './__helpers__/testRule';
2+
import { DiagnosticSeverity } from '@stoplight/types';
3+
4+
const componentSchemas = {
5+
schemas: {
6+
ResourceSchema: {
7+
type: 'object',
8+
properties: {
9+
id: { type: 'string', readOnly: true },
10+
name: { type: 'string' },
11+
description: { type: 'string' },
12+
createdAt: { type: 'string', readOnly: true },
13+
},
14+
},
15+
OtherSchema: {
16+
type: 'object',
17+
properties: {
18+
id: { type: 'string' },
19+
name: { type: 'string' },
20+
},
21+
},
22+
},
23+
};
24+
25+
testRule('xgen-IPA-106-create-method-response-is-get-method-response', [
26+
{
27+
name: 'valid create requests',
28+
document: {
29+
paths: {
30+
'/resources': {
31+
post: {
32+
responses: {
33+
201: {
34+
content: {
35+
'application/vnd.atlas.2024-08-05+json': {
36+
schema: {
37+
$ref: '#/components/schemas/ResourceSchema',
38+
},
39+
},
40+
},
41+
},
42+
},
43+
},
44+
},
45+
'/resources/{id}': {
46+
get: {
47+
responses: {
48+
200: {
49+
content: {
50+
'application/vnd.atlas.2024-08-05+json': {
51+
schema: {
52+
$ref: '#/components/schemas/ResourceSchema',
53+
},
54+
},
55+
},
56+
},
57+
},
58+
},
59+
},
60+
// Multiple versions
61+
'/versionedResources': {
62+
post: {
63+
responses: {
64+
201: {
65+
content: {
66+
'application/vnd.atlas.2024-08-05+json': {
67+
schema: {
68+
$ref: '#/components/schemas/ResourceSchema',
69+
},
70+
},
71+
'application/vnd.atlas.2024-01-05+json': {
72+
schema: {
73+
$ref: '#/components/schemas/ResourceSchema',
74+
},
75+
},
76+
},
77+
},
78+
},
79+
},
80+
},
81+
'/versionedResources/{id}': {
82+
get: {
83+
responses: {
84+
200: {
85+
content: {
86+
'application/vnd.atlas.2024-08-05+json': {
87+
schema: {
88+
$ref: '#/components/schemas/ResourceSchema',
89+
},
90+
},
91+
'application/vnd.atlas.2024-01-05+json': {
92+
schema: {
93+
$ref: '#/components/schemas/ResourceSchema',
94+
},
95+
},
96+
},
97+
},
98+
},
99+
},
100+
},
101+
},
102+
components: componentSchemas,
103+
},
104+
errors: [],
105+
},
106+
{
107+
name: 'rule ignores inapplicable cases',
108+
document: {
109+
paths: {
110+
// Path not ending in collection
111+
'/not/a/collection/resource': {
112+
post: {
113+
requestBody: {
114+
content: {
115+
'application/vnd.atlas.2024-08-05+json': {
116+
schema: {
117+
type: 'object',
118+
properties: {
119+
name: { type: 'string' },
120+
},
121+
},
122+
},
123+
},
124+
},
125+
},
126+
},
127+
// Version mismatch but will be ignored
128+
'/versionMismatchResources': {
129+
post: {
130+
requestBody: {
131+
content: {
132+
'application/vnd.atlas.2024-01-05+json': {
133+
schema: {
134+
$ref: '#/components/schemas/ResourceSchema',
135+
},
136+
},
137+
},
138+
},
139+
},
140+
},
141+
'/versionMismatchResources/{id}': {
142+
get: {
143+
responses: {
144+
200: {
145+
content: {
146+
'application/vnd.atlas.2024-08-05+json': {
147+
schema: {
148+
$ref: '#/components/schemas/ResourceSchema',
149+
},
150+
},
151+
},
152+
},
153+
},
154+
},
155+
},
156+
},
157+
components: componentSchemas,
158+
},
159+
errors: [],
160+
},
161+
{
162+
name: 'invalid create requests',
163+
document: {
164+
paths: {
165+
// Get without schema
166+
'/resourcesOne': {
167+
post: {
168+
responses: {
169+
201: {
170+
content: {
171+
'application/vnd.atlas.2024-01-05+json': {
172+
schema: {
173+
$ref: '#/components/schemas/ResourceSchema',
174+
},
175+
},
176+
},
177+
},
178+
},
179+
},
180+
},
181+
'/resourcesOne/{id}': {
182+
get: {
183+
responses: {
184+
200: {
185+
content: {
186+
'application/vnd.atlas.2024-01-05+json': {},
187+
},
188+
},
189+
},
190+
},
191+
},
192+
// Get without schema ref
193+
'/resourcesTwo': {
194+
post: {
195+
responses: {
196+
201: {
197+
content: {
198+
'application/vnd.atlas.2024-01-05+json': {
199+
schema: {
200+
$ref: '#/components/schemas/ResourceSchema',
201+
},
202+
},
203+
},
204+
},
205+
},
206+
},
207+
},
208+
'/resourcesTwo/{id}': {
209+
get: {
210+
responses: {
211+
200: {
212+
content: {
213+
'application/vnd.atlas.2024-01-05+json': {
214+
schema: {
215+
type: 'string',
216+
},
217+
},
218+
},
219+
},
220+
},
221+
},
222+
},
223+
},
224+
components: componentSchemas,
225+
},
226+
errors: [
227+
{
228+
code: 'xgen-IPA-106-create-method-response-is-get-method-response',
229+
message:
230+
'Could not validate that the Create method returns the same resource object as the Get method. The Get method does not have a schema.',
231+
path: [
232+
'paths',
233+
'/resourcesOne',
234+
'post',
235+
'responses',
236+
'201',
237+
'content',
238+
'application/vnd.atlas.2024-01-05+json',
239+
],
240+
severity: DiagnosticSeverity.Warning,
241+
},
242+
{
243+
code: 'xgen-IPA-106-create-method-response-is-get-method-response',
244+
message:
245+
'Could not validate that the Create method returns the same resource object as the Get method. The Get method does not have a schema reference.',
246+
path: [
247+
'paths',
248+
'/resourcesTwo',
249+
'post',
250+
'responses',
251+
'201',
252+
'content',
253+
'application/vnd.atlas.2024-01-05+json',
254+
],
255+
severity: DiagnosticSeverity.Warning,
256+
},
257+
],
258+
},
259+
{
260+
name: 'invalid with version mismatch',
261+
document: {
262+
paths: {
263+
'/resources': {
264+
post: {
265+
responses: {
266+
201: {
267+
content: {
268+
'application/vnd.atlas.2024-08-05+json': {
269+
schema: {
270+
$ref: '#/components/schemas/ResourceSchema',
271+
},
272+
},
273+
},
274+
},
275+
},
276+
},
277+
},
278+
'/resources/{id}': {
279+
get: {
280+
responses: {
281+
200: {
282+
content: {
283+
'application/vnd.atlas.2024-01-05+json': {
284+
schema: {
285+
$ref: '#/components/schemas/OtherSchema',
286+
},
287+
},
288+
},
289+
},
290+
},
291+
},
292+
},
293+
},
294+
components: componentSchemas,
295+
},
296+
errors: [
297+
{
298+
code: 'xgen-IPA-106-create-method-response-is-get-method-response',
299+
message: 'The schema in the Create method response must be the same schema as the response of the Get method.',
300+
path: ['paths', '/resources', 'post', 'responses', '201', 'content', 'application/vnd.atlas.2024-08-05+json'],
301+
severity: DiagnosticSeverity.Warning,
302+
},
303+
],
304+
},
305+
{
306+
name: 'invalid with exception',
307+
document: {
308+
paths: {
309+
'/resources': {
310+
post: {
311+
responses: {
312+
201: {
313+
content: {
314+
'application/vnd.atlas.2024-08-05+json': {
315+
'x-xgen-IPA-exception': {
316+
'xgen-IPA-106-create-method-response-is-get-method-response': 'Exception reason',
317+
},
318+
schema: {
319+
type: 'object',
320+
properties: {
321+
completelyDifferent: { type: 'boolean' },
322+
},
323+
},
324+
},
325+
},
326+
},
327+
},
328+
},
329+
},
330+
'/resources/{id}': {
331+
get: {
332+
responses: {
333+
200: {
334+
content: {
335+
'application/vnd.atlas.2024-08-05+json': {
336+
schema: {
337+
$ref: '#/components/schemas/ResourceSchema',
338+
},
339+
},
340+
},
341+
},
342+
},
343+
},
344+
},
345+
},
346+
components: componentSchemas,
347+
},
348+
errors: [],
349+
},
350+
]);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ rules:
3636
3737
##### Implementation details
3838
39-
Validation checks that the List method response contains items property with reference to the same schema as the Get method response.
39+
Validation checks that the List method 200 OK response contains items property with reference to the same schema as the Get method response.
4040
4141
- Validation applies to List methods for resource collections only
4242
- Validation applies to json response content only
@@ -46,7 +46,7 @@ rules:
4646
- Paths with `x-xgen-IPA-exception` for this rule are excluded from validation
4747
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-105-list-method-response-is-get-method-response'
4848
severity: warn
49-
given: '$.paths[*].get.responses[*].content'
49+
given: '$.paths[*].get.responses.200.content'
5050
then:
5151
field: '@key'
5252
function: 'listMethodResponseIsGetMethodResponse'

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ functions:
77
- createMethodRequestBodyIsGetResponse
88
- createMethodRequestHasNoReadonlyFields
99
- createMethodResponseCodeIs201Created
10+
- createMethodResponseIsGetMethodResponse
1011

1112
rules:
1213
xgen-IPA-106-create-method-request-body-is-request-suffixed-object:
@@ -76,3 +77,22 @@ rules:
7677
given: '$.paths[*].post'
7778
then:
7879
function: 'createMethodResponseCodeIs201Created'
80+
xgen-IPA-106-create-method-response-is-get-method-response:
81+
description: >-
82+
The response body of the Create method should consist of the same resource object returned by the Get method.
83+
84+
##### Implementation details
85+
86+
Validation checks that the Create method 201 Created response contains reference to the same schema as the Get method response.
87+
88+
- Validation applies to Create methods for resource collections only
89+
- Validation applies to json response content only
90+
- Validation ignores responses without schema
91+
- Validation ignores resources without a Get method
92+
- Paths with `x-xgen-IPA-exception` for this rule are excluded from validation
93+
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-106-create-method-response-is-get-method-response'
94+
severity: warn
95+
given: '$.paths[*].post.responses.201.content'
96+
then:
97+
field: '@key'
98+
function: 'createMethodResponseIsGetMethodResponse'

0 commit comments

Comments
 (0)