From e78211049021d40b8bd479de216acf4c5489da9c Mon Sep 17 00:00:00 2001 From: Lovisa Berggren Date: Fri, 21 Mar 2025 12:28:36 +0000 Subject: [PATCH 1/4] CLOUDP-304965: IPA rule for descriptions --- .../__tests__/IPA117HasDescription.test.js | 391 ++++++++++++++++++ tools/spectral/ipa/rulesets/IPA-117.yaml | 31 ++ .../functions/IPA117HasDescription.js | 35 ++ 3 files changed, 457 insertions(+) create mode 100644 tools/spectral/ipa/__tests__/IPA117HasDescription.test.js create mode 100644 tools/spectral/ipa/rulesets/IPA-117.yaml create mode 100644 tools/spectral/ipa/rulesets/functions/IPA117HasDescription.js diff --git a/tools/spectral/ipa/__tests__/IPA117HasDescription.test.js b/tools/spectral/ipa/__tests__/IPA117HasDescription.test.js new file mode 100644 index 0000000000..9d16e5a4d6 --- /dev/null +++ b/tools/spectral/ipa/__tests__/IPA117HasDescription.test.js @@ -0,0 +1,391 @@ +import testRule from './__helpers__/testRule'; +import { DiagnosticSeverity } from '@stoplight/types'; + +testRule('xgen-IPA-117-description', [ + { + name: 'valid components', + document: { + info: { + description: 'description', + }, + tags: [ + { + name: 'Tag', + description: 'description', + }, + ], + paths: { + '/resource': { + get: { + description: 'description', + parameters: { + id: { + description: 'description', + }, + }, + }, + // Ignores non-operations + 'x-extension': {}, + }, + }, + components: { + schemas: { + Schema: { + properties: { + id: { + description: 'description', + }, + }, + }, + }, + parameters: { + parameter: { + description: 'description', + }, + }, + }, + }, + errors: [], + }, + { + name: 'invalid components', + document: { + info: {}, + tags: [ + { + name: 'Tag', + }, + ], + paths: { + '/resource': { + get: { + parameters: { + id: {}, + }, + }, + }, + }, + components: { + schemas: { + Schema: { + properties: { + id: {}, + }, + }, + }, + parameters: { + parameter: {}, + }, + }, + }, + errors: [ + { + code: 'xgen-IPA-117-description', + message: + 'Description not found. API producers must provide descriptions for Properties, Operations and Parameters.', + path: ['info'], + severity: DiagnosticSeverity.Warning, + }, + { + code: 'xgen-IPA-117-description', + message: + 'Description not found. API producers must provide descriptions for Properties, Operations and Parameters.', + path: ['tags', '0'], + severity: DiagnosticSeverity.Warning, + }, + { + code: 'xgen-IPA-117-description', + message: + 'Description not found. API producers must provide descriptions for Properties, Operations and Parameters.', + path: ['paths', '/resource', 'get'], + severity: DiagnosticSeverity.Warning, + }, + { + code: 'xgen-IPA-117-description', + message: + 'Description not found. API producers must provide descriptions for Properties, Operations and Parameters.', + path: ['paths', '/resource', 'get', 'parameters', 'id'], + severity: DiagnosticSeverity.Warning, + }, + { + code: 'xgen-IPA-117-description', + message: + 'Description not found. API producers must provide descriptions for Properties, Operations and Parameters.', + path: ['components', 'schemas', 'Schema', 'properties', 'id'], + severity: DiagnosticSeverity.Warning, + }, + { + code: 'xgen-IPA-117-description', + message: + 'Description not found. API producers must provide descriptions for Properties, Operations and Parameters.', + path: ['components', 'parameters', 'parameter'], + severity: DiagnosticSeverity.Warning, + }, + ], + }, + { + name: 'invalid array schema', + document: { + components: { + schemas: { + ArraySchema: { + type: 'array', + items: { + properties: { + id: {}, + }, + }, + }, + }, + }, + }, + errors: [ + { + code: 'xgen-IPA-117-description', + message: + 'Description not found. API producers must provide descriptions for Properties, Operations and Parameters.', + path: ['components', 'schemas', 'ArraySchema', 'items', 'properties', 'id'], + severity: DiagnosticSeverity.Warning, + }, + ], + }, + { + name: 'invalid nested schema', + document: { + components: { + schemas: { + NestedSchema: { + properties: { + name: { + properties: { + first: {}, + last: {}, + }, + }, + }, + }, + }, + }, + }, + errors: [ + { + code: 'xgen-IPA-117-description', + message: + 'Description not found. API producers must provide descriptions for Properties, Operations and Parameters.', + path: ['components', 'schemas', 'NestedSchema', 'properties', 'name'], + severity: DiagnosticSeverity.Warning, + }, + { + code: 'xgen-IPA-117-description', + message: + 'Description not found. API producers must provide descriptions for Properties, Operations and Parameters.', + path: ['components', 'schemas', 'NestedSchema', 'properties', 'name', 'properties', 'first'], + severity: DiagnosticSeverity.Warning, + }, + { + code: 'xgen-IPA-117-description', + message: + 'Description not found. API producers must provide descriptions for Properties, Operations and Parameters.', + path: ['components', 'schemas', 'NestedSchema', 'properties', 'name', 'properties', 'last'], + severity: DiagnosticSeverity.Warning, + }, + ], + }, + { + name: 'invalid paginated schema', + document: { + components: { + schemas: { + PaginatedSchema: { + properties: { + results: { + type: 'array', + items: { + properties: { + first: {}, + last: {}, + }, + }, + }, + }, + }, + }, + }, + }, + errors: [ + { + code: 'xgen-IPA-117-description', + message: + 'Description not found. API producers must provide descriptions for Properties, Operations and Parameters.', + path: ['components', 'schemas', 'PaginatedSchema', 'properties', 'results'], + severity: DiagnosticSeverity.Warning, + }, + { + code: 'xgen-IPA-117-description', + message: + 'Description not found. API producers must provide descriptions for Properties, Operations and Parameters.', + path: ['components', 'schemas', 'PaginatedSchema', 'properties', 'results', 'items', 'properties', 'first'], + severity: DiagnosticSeverity.Warning, + }, + { + code: 'xgen-IPA-117-description', + message: + 'Description not found. API producers must provide descriptions for Properties, Operations and Parameters.', + path: ['components', 'schemas', 'PaginatedSchema', 'properties', 'results', 'items', 'properties', 'last'], + severity: DiagnosticSeverity.Warning, + }, + ], + }, + { + name: 'invalid inline schemas', + document: { + paths: { + '/resource': { + post: { + description: 'description', + responses: { + 201: { + content: { + 'application/vnd.atlas.2024-01-01+json': { + schema: { + properties: { + id: {}, + }, + }, + }, + }, + }, + }, + requestBody: { + content: { + 'application/vnd.atlas.2024-01-01+json': { + schema: { + properties: { + id: {}, + }, + }, + }, + 'application/vnd.atlas.2025-01-01+json': { + schema: { + properties: { + id: {}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + errors: [ + { + code: 'xgen-IPA-117-description', + message: + 'Description not found. API producers must provide descriptions for Properties, Operations and Parameters.', + path: [ + 'paths', + '/resource', + 'post', + 'responses', + '201', + 'content', + 'application/vnd.atlas.2024-01-01+json', + 'schema', + 'properties', + 'id', + ], + severity: DiagnosticSeverity.Warning, + }, + { + code: 'xgen-IPA-117-description', + message: + 'Description not found. API producers must provide descriptions for Properties, Operations and Parameters.', + path: [ + 'paths', + '/resource', + 'post', + 'requestBody', + 'content', + 'application/vnd.atlas.2024-01-01+json', + 'schema', + 'properties', + 'id', + ], + severity: DiagnosticSeverity.Warning, + }, + { + code: 'xgen-IPA-117-description', + message: + 'Description not found. API producers must provide descriptions for Properties, Operations and Parameters.', + path: [ + 'paths', + '/resource', + 'post', + 'requestBody', + 'content', + 'application/vnd.atlas.2025-01-01+json', + 'schema', + 'properties', + 'id', + ], + severity: DiagnosticSeverity.Warning, + }, + ], + }, + { + name: 'invalid components with exceptions', + document: { + info: { + 'x-xgen-IPA-exception': { + 'xgen-IPA-117-description': 'reason', + }, + }, + tags: [ + { + name: 'Tag', + 'x-xgen-IPA-exception': { + 'xgen-IPA-117-description': 'reason', + }, + }, + ], + paths: { + '/resource': { + get: { + 'x-xgen-IPA-exception': { + 'xgen-IPA-117-description': 'reason', + }, + parameters: { + id: { + 'x-xgen-IPA-exception': { + 'xgen-IPA-117-description': 'reason', + }, + }, + }, + }, + }, + }, + components: { + schemas: { + Schema: { + properties: { + id: { + 'x-xgen-IPA-exception': { + 'xgen-IPA-117-description': 'reason', + }, + }, + }, + }, + }, + parameters: { + parameter: { + 'x-xgen-IPA-exception': { + 'xgen-IPA-117-description': 'reason', + }, + }, + }, + }, + }, + errors: [], + }, +]); diff --git a/tools/spectral/ipa/rulesets/IPA-117.yaml b/tools/spectral/ipa/rulesets/IPA-117.yaml new file mode 100644 index 0000000000..74aae887ee --- /dev/null +++ b/tools/spectral/ipa/rulesets/IPA-117.yaml @@ -0,0 +1,31 @@ +# IPA-117: Documentation +# http://go/ipa/117 + +functions: + - IPA117HasDescription + +rules: + xgen-IPA-117-description: + description: | + API producers must provide descriptions for Properties, Operations and Parameters. + + ##### Implementation details + Rule checks for description property in the following components: + - Info object + - Tags + - Operation objects + - Inline schema properties for operation object requests and responses + - Parameter objects (in operations and components) + - Schema properties + message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-117-description' + severity: warn + given: + - '$.info' + - '$.tags[*]' + - '$.paths[*][get,put,post,delete,options,head,patch,trace]' + - '$.paths[*][get,put,post,delete,options,head,patch,trace].parameters[*]' + - '$.paths[*][get,put,post,delete,options,head,patch,trace]..content..properties[*]' + - '$.components.schemas..properties[*]' + - '$.components.parameters[*]' + then: + function: 'IPA117HasDescription' diff --git a/tools/spectral/ipa/rulesets/functions/IPA117HasDescription.js b/tools/spectral/ipa/rulesets/functions/IPA117HasDescription.js new file mode 100644 index 0000000000..bd75b77430 --- /dev/null +++ b/tools/spectral/ipa/rulesets/functions/IPA117HasDescription.js @@ -0,0 +1,35 @@ +import { hasException } from './utils/exceptions.js'; +import { + collectAdoption, + collectAndReturnViolation, + collectException, + handleInternalError, +} from './utils/collectionUtils.js'; + +const RULE_NAME = 'xgen-IPA-117-description'; +const ERROR_MESSAGE = + 'Description not found. API producers must provide descriptions for Properties, Operations and Parameters.'; + +export default (input, opts, { path }) => { + if (hasException(input, RULE_NAME)) { + collectException(input, RULE_NAME, path); + return; + } + + const errors = checkViolationsAndReturnErrors(input, path); + if (errors.length !== 0) { + return collectAndReturnViolation(path, RULE_NAME, errors); + } + collectAdoption(path, RULE_NAME); +}; + +function checkViolationsAndReturnErrors(input, path) { + try { + if (!Object.keys(input).includes('description') || input['description'] === '') { + return [{ path, message: ERROR_MESSAGE }]; + } + return []; + } catch (e) { + handleInternalError(RULE_NAME, path, e); + } +} From ffd940603305f8d0b750338dc3c86925a7ddbb24 Mon Sep 17 00:00:00 2001 From: Lovisa Berggren Date: Fri, 21 Mar 2025 13:42:16 +0000 Subject: [PATCH 2/4] CLOUDP-304965: Fix --- tools/spectral/ipa/rulesets/functions/IPA117HasDescription.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/spectral/ipa/rulesets/functions/IPA117HasDescription.js b/tools/spectral/ipa/rulesets/functions/IPA117HasDescription.js index bd75b77430..4b986f9c5d 100644 --- a/tools/spectral/ipa/rulesets/functions/IPA117HasDescription.js +++ b/tools/spectral/ipa/rulesets/functions/IPA117HasDescription.js @@ -25,7 +25,7 @@ export default (input, opts, { path }) => { function checkViolationsAndReturnErrors(input, path) { try { - if (!Object.keys(input).includes('description') || input['description'] === '') { + if (!input['description']) { return [{ path, message: ERROR_MESSAGE }]; } return []; From f743afbb8040519b7ee3b9d826799e2be1ff3a43 Mon Sep 17 00:00:00 2001 From: Lovisa Berggren Date: Fri, 21 Mar 2025 13:46:38 +0000 Subject: [PATCH 3/4] CLOUDP-304965: Fix --- .../__tests__/IPA117HasDescription.test.js | 25 +++++++++++++++++++ tools/spectral/ipa/rulesets/IPA-117.yaml | 1 + 2 files changed, 26 insertions(+) diff --git a/tools/spectral/ipa/__tests__/IPA117HasDescription.test.js b/tools/spectral/ipa/__tests__/IPA117HasDescription.test.js index 9d16e5a4d6..397f2902fd 100644 --- a/tools/spectral/ipa/__tests__/IPA117HasDescription.test.js +++ b/tools/spectral/ipa/__tests__/IPA117HasDescription.test.js @@ -123,6 +123,31 @@ testRule('xgen-IPA-117-description', [ }, ], }, + { + name: 'invalid empty description', + document: { + components: { + schemas: { + Schema: { + properties: { + id: { + description: '', + }, + }, + }, + }, + }, + }, + errors: [ + { + code: 'xgen-IPA-117-description', + message: + 'Description not found. API producers must provide descriptions for Properties, Operations and Parameters.', + path: ['components', 'schemas', 'Schema', 'properties', 'id'], + severity: DiagnosticSeverity.Warning, + }, + ], + }, { name: 'invalid array schema', document: { diff --git a/tools/spectral/ipa/rulesets/IPA-117.yaml b/tools/spectral/ipa/rulesets/IPA-117.yaml index 74aae887ee..cab084d98a 100644 --- a/tools/spectral/ipa/rulesets/IPA-117.yaml +++ b/tools/spectral/ipa/rulesets/IPA-117.yaml @@ -17,6 +17,7 @@ rules: - Inline schema properties for operation object requests and responses - Parameter objects (in operations and components) - Schema properties + The rule also fails if the description is an empty string. message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-117-description' severity: warn given: From aa0d15e5fe1e86ffad07c4fbc12a77144b208774 Mon Sep 17 00:00:00 2001 From: Lovisa Berggren Date: Fri, 21 Mar 2025 15:16:40 +0000 Subject: [PATCH 4/4] CLOUDP-304965: Fix docs --- tools/spectral/ipa/ipa-spectral.yaml | 1 + tools/spectral/ipa/rulesets/README.md | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/tools/spectral/ipa/ipa-spectral.yaml b/tools/spectral/ipa/ipa-spectral.yaml index 15891a2f41..bd08e8b16c 100644 --- a/tools/spectral/ipa/ipa-spectral.yaml +++ b/tools/spectral/ipa/ipa-spectral.yaml @@ -9,6 +9,7 @@ extends: - ./rulesets/IPA-109.yaml - ./rulesets/IPA-112.yaml - ./rulesets/IPA-113.yaml + - ./rulesets/IPA-117.yaml - ./rulesets/IPA-123.yaml - ./rulesets/IPA-125.yaml diff --git a/tools/spectral/ipa/rulesets/README.md b/tools/spectral/ipa/rulesets/README.md index 962f8d4d32..522a423127 100644 --- a/tools/spectral/ipa/rulesets/README.md +++ b/tools/spectral/ipa/rulesets/README.md @@ -505,6 +505,27 @@ Rule checks for the following conditions: +### IPA-117 + +Rules are based on [http://go/ipa/IPA-117](http://go/ipa/IPA-117). + +#### xgen-IPA-117-description + + ![warn](https://img.shields.io/badge/warning-yellow) +API producers must provide descriptions for Properties, Operations and Parameters. + +##### Implementation details +Rule checks for description property in the following components: + - Info object + - Tags + - Operation objects + - Inline schema properties for operation object requests and responses + - Parameter objects (in operations and components) + - Schema properties +The rule also fails if the description is an empty string. + + + ### IPA-123 Rules are based on [http://go/ipa/IPA-123](http://go/ipa/IPA-123).