Skip to content

Commit 839f2ee

Browse files
CLOUDP-307341: Include singleton in IPA 107 rules
1 parent b402dad commit 839f2ee

8 files changed

+179
-15
lines changed

tools/spectral/ipa/__tests__/IPA107UpdateMethodRequestBodyIsGetResponse.test.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,32 @@ testRule('xgen-IPA-107-update-method-request-body-is-get-method-response', [
402402
},
403403
},
404404
},
405+
'/resource/{id}/singleton': {
406+
get: {
407+
responses: {
408+
200: {
409+
content: {
410+
'application/vnd.atlas.2023-01-01+json': {
411+
schema: {
412+
$ref: '#/components/schemas/SchemaOne',
413+
},
414+
},
415+
},
416+
},
417+
},
418+
},
419+
patch: {
420+
requestBody: {
421+
content: {
422+
'application/vnd.atlas.2023-01-01+json': {
423+
schema: {
424+
$ref: '#/components/schemas/SchemaThree',
425+
},
426+
},
427+
},
428+
},
429+
},
430+
},
405431
},
406432
},
407433
errors: [
@@ -517,6 +543,20 @@ testRule('xgen-IPA-107-update-method-request-body-is-get-method-response', [
517543
],
518544
severity: DiagnosticSeverity.Warning,
519545
},
546+
{
547+
code: 'xgen-IPA-107-update-method-request-body-is-get-method-response',
548+
message:
549+
'The request body schema properties of the Update method must match the response body schema properties of the Get method.',
550+
path: [
551+
'paths',
552+
'/resource/{id}/singleton',
553+
'patch',
554+
'requestBody',
555+
'content',
556+
'application/vnd.atlas.2023-01-01+json',
557+
],
558+
severity: DiagnosticSeverity.Warning,
559+
},
520560
],
521561
},
522562
{

tools/spectral/ipa/__tests__/IPA107UpdateMethodRequestHasNoReadonlyFields.test.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,30 @@ testRule('xgen-IPA-107-update-method-request-has-no-readonly-fields', [
151151
},
152152
},
153153
},
154+
'/resource/{id}/singleton': {
155+
patch: {
156+
requestBody: {
157+
content: {
158+
'application/vnd.atlas.2023-01-01+json': {
159+
schema: {
160+
$ref: '#/components/schemas/SchemaWithReadOnly',
161+
},
162+
},
163+
},
164+
},
165+
},
166+
put: {
167+
requestBody: {
168+
content: {
169+
'application/vnd.atlas.2023-01-01+json': {
170+
schema: {
171+
$ref: '#/components/schemas/SchemaWithReadOnly',
172+
},
173+
},
174+
},
175+
},
176+
},
177+
},
154178
},
155179
},
156180
errors: [
@@ -182,6 +206,34 @@ testRule('xgen-IPA-107-update-method-request-has-no-readonly-fields', [
182206
path: ['paths', '/resource/{id}', 'put', 'requestBody', 'content', 'application/vnd.atlas.2024-01-01+json'],
183207
severity: DiagnosticSeverity.Warning,
184208
},
209+
{
210+
code: 'xgen-IPA-107-update-method-request-has-no-readonly-fields',
211+
message:
212+
'The Update method request object must not include input fields (readOnly properties). Found readOnly property at: id. ',
213+
path: [
214+
'paths',
215+
'/resource/{id}/singleton',
216+
'patch',
217+
'requestBody',
218+
'content',
219+
'application/vnd.atlas.2023-01-01+json',
220+
],
221+
severity: DiagnosticSeverity.Warning,
222+
},
223+
{
224+
code: 'xgen-IPA-107-update-method-request-has-no-readonly-fields',
225+
message:
226+
'The Update method request object must not include input fields (readOnly properties). Found readOnly property at: id. ',
227+
path: [
228+
'paths',
229+
'/resource/{id}/singleton',
230+
'put',
231+
'requestBody',
232+
'content',
233+
'application/vnd.atlas.2023-01-01+json',
234+
],
235+
severity: DiagnosticSeverity.Warning,
236+
},
185237
],
186238
},
187239
{

tools/spectral/ipa/__tests__/IPA107UpdateMethodResponseIsGetMethodResponse.test.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,34 @@ testRule('xgen-IPA-107-update-method-response-is-get-method-response', [
312312
},
313313
},
314314
},
315+
'/resourceFour/{id}/singleton': {
316+
get: {
317+
responses: {
318+
200: {
319+
content: {
320+
'application/vnd.atlas.2024-01-05+json': {
321+
schema: {
322+
$ref: '#/components/schemas/ResourceSchema',
323+
},
324+
},
325+
},
326+
},
327+
},
328+
},
329+
patch: {
330+
responses: {
331+
200: {
332+
content: {
333+
'application/vnd.atlas.2024-01-05+json': {
334+
schema: {
335+
$ref: '#/components/schemas/OtherSchema',
336+
},
337+
},
338+
},
339+
},
340+
},
341+
},
342+
},
315343
},
316344
components: componentSchemas,
317345
},
@@ -375,6 +403,20 @@ testRule('xgen-IPA-107-update-method-response-is-get-method-response', [
375403
],
376404
severity: DiagnosticSeverity.Warning,
377405
},
406+
{
407+
code: 'xgen-IPA-107-update-method-response-is-get-method-response',
408+
message: 'The schema in the Update method response must be the same schema as the response of the Get method.',
409+
path: [
410+
'paths',
411+
'/resourceFour/{id}/singleton',
412+
'patch',
413+
'responses',
414+
'200',
415+
'content',
416+
'application/vnd.atlas.2024-01-05+json',
417+
],
418+
severity: DiagnosticSeverity.Warning,
419+
},
378420
],
379421
},
380422
{

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ rules:
1515
1616
##### Implementation details
1717
18-
Validation checks the PATCH/PUT methods for single resource paths and singleton resources.
18+
Validation checks the PATCH/PUT methods for single resource paths and [singleton resources](https://go/ipa/113).
1919
2020
- Query parameters `envelope` and `pretty` are exempt from this rule
2121
- Operation objects with `x-xgen-IPA-exception` for this rule are excluded from validation
@@ -46,7 +46,7 @@ rules:
4646
4747
##### Implementation details
4848
Rule checks for the following conditions:
49-
- Applies only to single resource paths with JSON content types
49+
- Applies only to single resource paths and singleton resources with JSON content types
5050
- Ignores singleton resources and responses without a schema
5151
- Validation ignores resources without a Get method
5252
- Fails if the Get method doesn't have a schema reference or if the schemas don't match
@@ -63,7 +63,7 @@ rules:
6363
6464
##### Implementation details
6565
Rule checks for the following conditions:
66-
- Applies only to Update methods on single resource paths
66+
- Applies only to Update methods on single resource paths or singleton resources
6767
- Applies only to JSON content types
6868
- Searches through the request schema to find any properties marked with readOnly attribute
6969
- Fails if any readOnly properties are found in the request schema
@@ -79,7 +79,7 @@ rules:
7979
8080
##### Implementation details
8181
82-
Validation checks the PATCH/PUT methods for single resource paths.
82+
Validation checks the PATCH/PUT methods for single resource paths and singleton resources.
8383
- Validation ignores resources without a Get method.
8484
- `readOnly:true` properties of Get method response will be ignored.
8585
- `writeOnly:true` properties of Update method request will be ignored.

tools/spectral/ipa/rulesets/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ Rules are based on [http://go/ipa/IPA-107](http://go/ipa/IPA-107).
284284
![warn](https://img.shields.io/badge/warning-yellow)
285285
Update operations must not accept query parameters.
286286
##### Implementation details
287-
Validation checks the PATCH/PUT methods for single resource paths and singleton resources.
287+
Validation checks the PATCH/PUT methods for single resource paths and [singleton resources](https://go/ipa/113).
288288

289289
- Query parameters `envelope` and `pretty` are exempt from this rule
290290
- Operation objects with `x-xgen-IPA-exception` for this rule are excluded from validation
@@ -301,7 +301,7 @@ Validation checks the PATCH/PUT methods for single resource paths and [singleton
301301
![warn](https://img.shields.io/badge/warning-yellow)
302302
The response body of the Update method should consist of the same resource object returned by the Get method.
303303
##### Implementation details Rule checks for the following conditions:
304-
- Applies only to single resource paths with JSON content types
304+
- Applies only to single resource paths and singleton resources with JSON content types
305305
- Ignores singleton resources and responses without a schema
306306
- Validation ignores resources without a Get method
307307
- Fails if the Get method doesn't have a schema reference or if the schemas don't match
@@ -313,7 +313,7 @@ Update method Request object must not include fields with readOnly:true.
313313

314314
##### Implementation details
315315
Rule checks for the following conditions:
316-
- Applies only to Update methods on single resource paths
316+
- Applies only to Update methods on single resource paths or singleton resources
317317
- Applies only to JSON content types
318318
- Searches through the request schema to find any properties marked with readOnly attribute
319319
- Fails if any readOnly properties are found in the request schema
@@ -325,7 +325,7 @@ The request body must contain the resource being updated, i.e. the resource or p
325325

326326
##### Implementation details
327327

328-
Validation checks the PATCH/PUT methods for single resource paths.
328+
Validation checks the PATCH/PUT methods for single resource paths and singleton resources.
329329
- Validation ignores resources without a Get method.
330330
- `readOnly:true` properties of Get method response will be ignored.
331331
- `writeOnly:true` properties of Update method request will be ignored.

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { isSingleResourceIdentifier } from './utils/resourceEvaluation.js';
1+
import {
2+
getResourcePathItems,
3+
isResourceCollectionIdentifier,
4+
isSingleResourceIdentifier,
5+
isSingletonResource,
6+
} from './utils/resourceEvaluation.js';
27
import { resolveObject } from './utils/componentUtils.js';
38
import { hasException } from './utils/exceptions.js';
49
import { collectAdoption, collectAndReturnViolation, collectException } from './utils/collectionUtils.js';
@@ -20,9 +25,14 @@ export default (input, _, { path, documentInventory }) => {
2025
const oas = documentInventory.resolved;
2126
const unresolvedOas = documentInventory.unresolved;
2227
const resourcePath = path[1];
23-
let mediaType = input;
28+
const mediaType = input;
29+
const resourcePathItems = getResourcePathItems(resourcePath, oas.paths);
2430

25-
if (!isSingleResourceIdentifier(resourcePath) || !mediaType.endsWith('json')) {
31+
if (
32+
!input.endsWith('json') ||
33+
(!isSingleResourceIdentifier(resourcePath) &&
34+
!(isResourceCollectionIdentifier(resourcePath) && isSingletonResource(resourcePathItems)))
35+
) {
2636
return;
2737
}
2838

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { isSingleResourceIdentifier } from './utils/resourceEvaluation.js';
1+
import {
2+
getResourcePathItems,
3+
isResourceCollectionIdentifier,
4+
isSingleResourceIdentifier,
5+
isSingletonResource,
6+
} from './utils/resourceEvaluation.js';
27
import { resolveObject } from './utils/componentUtils.js';
38
import { hasException } from './utils/exceptions.js';
49
import { collectAdoption, collectAndReturnViolation, collectException } from './utils/collectionUtils.js';
@@ -17,8 +22,13 @@ const ERROR_MESSAGE = 'The Update method request object must not include input f
1722
export default (input, _, { path, documentInventory }) => {
1823
const resourcePath = path[1];
1924
const oas = documentInventory.resolved;
25+
const resourcePathItems = getResourcePathItems(resourcePath, oas.paths);
2026

21-
if (!isSingleResourceIdentifier(resourcePath) || !input.endsWith('json')) {
27+
if (
28+
!input.endsWith('json') ||
29+
(!isSingleResourceIdentifier(resourcePath) &&
30+
!(isResourceCollectionIdentifier(resourcePath) && isSingletonResource(resourcePathItems)))
31+
) {
2232
return;
2333
}
2434

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { isSingleResourceIdentifier } from './utils/resourceEvaluation.js';
1+
import {
2+
getResourcePathItems,
3+
isResourceCollectionIdentifier,
4+
isSingleResourceIdentifier,
5+
isSingletonResource,
6+
} from './utils/resourceEvaluation.js';
27
import { resolveObject } from './utils/componentUtils.js';
38
import { hasException } from './utils/exceptions.js';
49
import {
@@ -24,8 +29,13 @@ export default (input, _, { path, documentInventory }) => {
2429
const oas = documentInventory.unresolved;
2530
const resourcePath = path[1];
2631
const mediaType = input;
32+
const resourcePathItems = getResourcePathItems(resourcePath, oas.paths);
2733

28-
if (!mediaType.endsWith('json') || !isSingleResourceIdentifier(resourcePath)) {
34+
if (
35+
!mediaType.endsWith('json') ||
36+
(!isSingleResourceIdentifier(resourcePath) &&
37+
!(isResourceCollectionIdentifier(resourcePath) && isSingletonResource(resourcePathItems)))
38+
) {
2939
return;
3040
}
3141

0 commit comments

Comments
 (0)