From 36a078d08ce0e7040fe5a1f53e86be7543a04ef0 Mon Sep 17 00:00:00 2001 From: Yeliz Henden Date: Thu, 13 Mar 2025 09:47:16 +0000 Subject: [PATCH] CLOUDP-304939: IPA 106: Create : A Request object must include only input fields (consider resource collection URIs only) --- ...teMethodRequestHasNoReadonlyFields.test.js | 47 ++++++++++--------- .../createMethodRequestHasNoReadonlyFields.js | 12 ++++- 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/tools/spectral/ipa/__tests__/createMethodRequestHasNoReadonlyFields.test.js b/tools/spectral/ipa/__tests__/createMethodRequestHasNoReadonlyFields.test.js index 657e1937d1..7e73746b7e 100644 --- a/tools/spectral/ipa/__tests__/createMethodRequestHasNoReadonlyFields.test.js +++ b/tools/spectral/ipa/__tests__/createMethodRequestHasNoReadonlyFields.test.js @@ -72,7 +72,7 @@ testRule('xgen-IPA-106-create-method-request-has-no-readonly-fields', [ document: { components: componentSchemas, paths: { - '/valid-resource': { + '/resource': { post: { requestBody: { content: { @@ -90,6 +90,9 @@ testRule('xgen-IPA-106-create-method-request-has-no-readonly-fields', [ }, }, }, + '/resource/{id}': { + get: {}, + }, }, }, errors: [], @@ -121,7 +124,7 @@ testRule('xgen-IPA-106-create-method-request-has-no-readonly-fields', [ document: { components: componentSchemas, paths: { - '/invalid-resource': { + '/resource': { post: { requestBody: { content: { @@ -140,6 +143,9 @@ testRule('xgen-IPA-106-create-method-request-has-no-readonly-fields', [ }, }, }, + '/resource/{id}': { + get: {}, + }, }, }, errors: [ @@ -147,14 +153,14 @@ testRule('xgen-IPA-106-create-method-request-has-no-readonly-fields', [ code: 'xgen-IPA-106-create-method-request-has-no-readonly-fields', message: 'The Create method request object must not include input fields (readOnly properties). Found readOnly property at: id. http://go/ipa/106', - path: ['paths', '/invalid-resource', 'post', 'requestBody', 'content', 'application/vnd.atlas.2023-01-01+json'], + path: ['paths', '/resource', 'post', 'requestBody', 'content', 'application/vnd.atlas.2023-01-01+json'], severity: DiagnosticSeverity.Warning, }, { code: 'xgen-IPA-106-create-method-request-has-no-readonly-fields', message: 'The Create method request object must not include input fields (readOnly properties). Found readOnly property at one of the inline schemas. http://go/ipa/106', - path: ['paths', '/invalid-resource', 'post', 'requestBody', 'content', 'application/vnd.atlas.2024-01-01+json'], + path: ['paths', '/resource', 'post', 'requestBody', 'content', 'application/vnd.atlas.2024-01-01+json'], severity: DiagnosticSeverity.Warning, }, ], @@ -164,7 +170,7 @@ testRule('xgen-IPA-106-create-method-request-has-no-readonly-fields', [ document: { components: componentSchemas, paths: { - '/nested-invalid-resource': { + '/resource': { post: { requestBody: { content: { @@ -177,6 +183,9 @@ testRule('xgen-IPA-106-create-method-request-has-no-readonly-fields', [ }, }, }, + '/resource/{id}': { + get: {}, + }, }, }, errors: [ @@ -184,14 +193,7 @@ testRule('xgen-IPA-106-create-method-request-has-no-readonly-fields', [ code: 'xgen-IPA-106-create-method-request-has-no-readonly-fields', message: 'The Create method request object must not include input fields (readOnly properties). Found readOnly property at: user.userId. http://go/ipa/106', - path: [ - 'paths', - '/nested-invalid-resource', - 'post', - 'requestBody', - 'content', - 'application/vnd.atlas.2023-01-01+json', - ], + path: ['paths', '/resource', 'post', 'requestBody', 'content', 'application/vnd.atlas.2023-01-01+json'], severity: DiagnosticSeverity.Warning, }, ], @@ -201,7 +203,7 @@ testRule('xgen-IPA-106-create-method-request-has-no-readonly-fields', [ document: { components: componentSchemas, paths: { - '/array-invalid-resource': { + '/resource': { post: { requestBody: { content: { @@ -214,6 +216,9 @@ testRule('xgen-IPA-106-create-method-request-has-no-readonly-fields', [ }, }, }, + '/resource/{id}': { + get: {}, + }, }, }, errors: [ @@ -221,14 +226,7 @@ testRule('xgen-IPA-106-create-method-request-has-no-readonly-fields', [ code: 'xgen-IPA-106-create-method-request-has-no-readonly-fields', message: 'The Create method request object must not include input fields (readOnly properties). Found readOnly property at: items.items.itemId. http://go/ipa/106', - path: [ - 'paths', - '/array-invalid-resource', - 'post', - 'requestBody', - 'content', - 'application/vnd.atlas.2023-01-01+json', - ], + path: ['paths', '/resource', 'post', 'requestBody', 'content', 'application/vnd.atlas.2023-01-01+json'], severity: DiagnosticSeverity.Warning, }, ], @@ -238,7 +236,7 @@ testRule('xgen-IPA-106-create-method-request-has-no-readonly-fields', [ document: { components: componentSchemas, paths: { - '/excepted-resource': { + '/resource': { post: { requestBody: { content: { @@ -254,6 +252,9 @@ testRule('xgen-IPA-106-create-method-request-has-no-readonly-fields', [ }, }, }, + '/resource/{id}': { + get: {}, + }, }, }, errors: [], diff --git a/tools/spectral/ipa/rulesets/functions/createMethodRequestHasNoReadonlyFields.js b/tools/spectral/ipa/rulesets/functions/createMethodRequestHasNoReadonlyFields.js index 6bcdfd541e..4c955b8607 100644 --- a/tools/spectral/ipa/rulesets/functions/createMethodRequestHasNoReadonlyFields.js +++ b/tools/spectral/ipa/rulesets/functions/createMethodRequestHasNoReadonlyFields.js @@ -1,4 +1,9 @@ -import { isCustomMethodIdentifier } from './utils/resourceEvaluation.js'; +import { + getResourcePathItems, + isCustomMethodIdentifier, + isResourceCollectionIdentifier, + isSingletonResource, +} from './utils/resourceEvaluation.js'; import { resolveObject } from './utils/componentUtils.js'; import { hasException } from './utils/exceptions.js'; import { collectAdoption, collectAndReturnViolation, collectException } from './utils/collectionUtils.js'; @@ -10,9 +15,12 @@ const ERROR_MESSAGE = 'The Create method request object must not include input f export default (input, _, { path, documentInventory }) => { const resourcePath = path[1]; const oas = documentInventory.resolved; + const resourcePaths = getResourcePathItems(resourcePath, oas.paths); let mediaType = input; - if (isCustomMethodIdentifier(resourcePath) || !mediaType.endsWith('json')) { + const isResourceCollection = isResourceCollectionIdentifier(resourcePath) && !isSingletonResource(resourcePaths); + + if (isCustomMethodIdentifier(resourcePath) || !isResourceCollection || !mediaType.endsWith('json')) { return; }