Skip to content
Merged
4 changes: 2 additions & 2 deletions tools/spectral/ipa/__tests__/IPA104ValidOperationID.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ testRule('xgen-IPA-104-valid-operation-id', [
{
code: 'xgen-IPA-104-valid-operation-id',
message:
'Invalid OperationID. The Operation ID must start with the verb “get” and should be followed by a noun or compound noun. The noun(s) should be the collection identifiers from the resource identifier in singular form.',
'Invalid OperationID. ',
path: ['paths', '/api/atlas/v2/groups/{groupId}/accessList/{entryValue}/status', 'get'],
severity: DiagnosticSeverity.Warning,
},
{
code: 'xgen-IPA-104-valid-operation-id',
message:
'Invalid OperationID. The Operation ID must start with the verb “get” and should be followed by a noun or compound noun. The noun(s) should be the collection identifiers from the resource identifier in singular form.',
'Invalid OperationID. ',
path: ['paths', '/api/atlas/v2/groups/{groupId}/dataFederation/{tenantName}/limits/{limitName}', 'get'],
severity: DiagnosticSeverity.Warning,
},
Expand Down
4 changes: 2 additions & 2 deletions tools/spectral/ipa/__tests__/IPA105ValidOperationID.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ testRule('xgen-IPA-105-valid-operation-id', [
{
code: 'xgen-IPA-105-valid-operation-id',
message:
'Invalid OperationID. The Operation ID must start with the verb “list” and should be followed by a noun or compound noun. The noun(s) should be the collection identifiers from the resource identifier in singular form, where the last noun is in plural form.',
'Invalid OperationID. ',
path: ['paths', '/api/atlas/v2/groups/{groupId}/databaseUsers/{username}/certs', 'get'],
severity: DiagnosticSeverity.Warning,
},
{
code: 'xgen-IPA-105-valid-operation-id',
message:
'Invalid OperationID. The Operation ID must start with the verb “list” and should be followed by a noun or compound noun. The noun(s) should be the collection identifiers from the resource identifier in singular form, where the last noun is in plural form.',
'Invalid OperationID. ',
path: ['paths', '/api/atlas/v2/orgs/{orgId}/events', 'get'],
severity: DiagnosticSeverity.Warning,
},
Expand Down
4 changes: 2 additions & 2 deletions tools/spectral/ipa/__tests__/IPA106ValidOperationID.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ testRule('xgen-IPA-106-valid-operation-id', [
{
code: 'xgen-IPA-106-valid-operation-id',
message:
'Invalid OperationID. The Operation ID must start with the verb “create” and should be followed by a noun or compound noun. The noun(s) in the Operation ID should be the collection identifiers from the resource identifier in singular form. ',
'Invalid OperationID. ',
path: ['paths', '/api/atlas/v2/groups/{groupId}/access', 'post'],
severity: DiagnosticSeverity.Warning,
},
{
code: 'xgen-IPA-106-valid-operation-id',
message:
'Invalid OperationID. The Operation ID must start with the verb “create” and should be followed by a noun or compound noun. The noun(s) in the Operation ID should be the collection identifiers from the resource identifier in singular form. ',
'Invalid OperationID. ',
path: ['paths', '/api/atlas/v2/groups/{groupId}/invites', 'post'],
severity: DiagnosticSeverity.Warning,
},
Expand Down
4 changes: 2 additions & 2 deletions tools/spectral/ipa/__tests__/IPA107ValidOperationID.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ testRule('xgen-IPA-107-valid-operation-id', [
{
code: 'xgen-IPA-107-valid-operation-id',
message:
'Invalid OperationID. The Operation ID must start with the verb “update” and should be followed by a noun or compound noun. The noun(s) in the Operation ID should be the collection identifiers from the resource identifier in singular form. For singleton resources - the last noun may be in plural form.',
'Invalid OperationID. ',
path: ['paths', '/api/atlas/v2/groups/{groupId}/limits/{limitName}', 'patch'],
severity: DiagnosticSeverity.Warning,
},
{
code: 'xgen-IPA-107-valid-operation-id',
message:
'Invalid OperationID. The Operation ID must start with the verb “update” and should be followed by a noun or compound noun. The noun(s) in the Operation ID should be the collection identifiers from the resource identifier in singular form. For singleton resources - the last noun may be in plural form.',
'Invalid OperationID. ',
path: ['paths', '/api/atlas/v2/groups/{groupId}/settings', 'put'],
severity: DiagnosticSeverity.Warning,
},
Expand Down
6 changes: 2 additions & 4 deletions tools/spectral/ipa/__tests__/IPA108ValidOperationID.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,13 @@ testRule('xgen-IPA-108-valid-operation-id', [
errors: [
{
code: 'xgen-IPA-108-valid-operation-id',
message:
'Invalid OperationID. The Operation ID must start with the verb “delete” and should be followed by a noun or compound noun. The noun(s) in the Operation ID should be the collection identifiers from the resource identifier in singular form. ',
message: 'Invalid OperationID. ',
path: ['paths', '/api/atlas/v2/groups/{groupId}/apiKeys/{apiUserId}', 'delete'],
severity: DiagnosticSeverity.Warning,
},
{
code: 'xgen-IPA-108-valid-operation-id',
message:
'Invalid OperationID. The Operation ID must start with the verb “delete” and should be followed by a noun or compound noun. The noun(s) in the Operation ID should be the collection identifiers from the resource identifier in singular form. ',
message: 'Invalid OperationID. ',
path: ['paths', '/api/atlas/v2/groups/{groupId}', 'delete'],
severity: DiagnosticSeverity.Warning,
},
Expand Down
75 changes: 75 additions & 0 deletions tools/spectral/ipa/__tests__/IPA109ValidOperationID.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import testRule from './__helpers__/testRule';

// TODO: add tests for xgen-custom-method extension - CLOUDP-306294
// TOOD: enable tests for invalid methods (after rules are upgraded to warning) - CLOUDP-329722

testRule('xgen-IPA-109-valid-operation-id', [
{
name: 'valid methods',
document: {
paths: {
'/groups/{groupId}/clusters/{clusterName}:pause': {
post: {
operationId: 'pauseGroupCluster',
},
},
'/groups/{groupId}/clusters/{clusterName}:addNode': {
post: {
operationId: 'addGroupClusterNode',
},
},
},
},
errors: [],
},
// This test will be enable when the xgen-IPA-109-valid-operation-id is set to warning severity - CLOUDP-329722
/* {
name: 'invalid methods',
document: {
paths: {
'/api/atlas/v2/groups/{groupId}/clusters:search': {
post: {
operationId: 'searchClusters',
},
},
'/api/atlas/v2/groups/{groupId}:migrate': {
post: {
operationId: 'migrateProjectToAnotherOrg',
},
},
},
},
errors: [
{
code: 'xgen-IPA-109-valid-operation-id',
message:
'Invalid OperationID. ',
path: ['paths', '/api/atlas/v2/groups/{groupId}/clusters:search'],
severity: DiagnosticSeverity.Warning,
},
{
code: 'xgen-IPA-109-valid-operation-id',
message:
'Invalid OperationID. ',
path: ['paths', '/api/atlas/v2/groups/{groupId}:migrate'],
severity: DiagnosticSeverity.Warning,
},
],
}, */
{
name: 'invalid methods with exceptions',
document: {
paths: {
'/api/atlas/v2/orgs/{orgId}/users/{userId}:addRole': {
post: {
operationId: 'addOrgRole',
'x-xgen-IPA-exception': {
'xgen-IPA-109-valid-operation-id': 'Reason',
},
},
},
},
},
errors: [],
},
]);
20 changes: 20 additions & 0 deletions tools/spectral/ipa/rulesets/IPA-109.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ functions:
- IPA109EachCustomMethodMustBeGetOrPost
- IPA109EachCustomMethodMustUseCamelCase
- IPA109CustomMethodIdentifierFormat
- IPA109ValidOperationID

rules:
xgen-IPA-109-custom-method-must-be-GET-or-POST:
Expand Down Expand Up @@ -56,3 +57,22 @@ rules:
given: '$.paths[*]'
then:
function: 'IPA109CustomMethodIdentifierFormat'
xgen-IPA-109-valid-operation-id:
description: |
The Operation ID must start with the custom method verb (the custom method path section delimited by the colon (:) character) and should be followed by a noun or compound noun.
If the custom Operation ID has a verb + noun, the Operation ID should end with the noun.
The noun(s) in the Operation ID should be the collection identifiers from the resource identifier.
The noun(s) in the Operation ID should be the collection identifiers from the resource identifier in singular form, where the last noun:
- Is in plural form if the method applies to a collection of resources
- Is in singular form if the method applies to a single resource

##### Implementation details
Rule checks for the following conditions:
- Applies only to paths containing custom method identifiers (with colon format)
- Generates the expected OperationId given the resource identifier and the method name portion following the colon
- Confirms that the existing operationId is compliant with generated IPA Compliant OperationId
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-109-valid-operation-id'
severity: off
given: '$.paths[*]'
then:
function: 'IPA109ValidOperationID'
16 changes: 16 additions & 0 deletions tools/spectral/ipa/rulesets/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,22 @@ Rule checks for the following conditions:
- Fails if multiple colons appear in the path
- Fails if other than an alphabetical character or a closing curly brace appears before a colon

#### xgen-IPA-109-valid-operation-id

`off`
The Operation ID must start with the custom method verb (the custom method path section delimited by the colon (:) character) and should be followed by a noun or compound noun.
If the custom Operation ID has a verb + noun, the Operation ID should end with the noun.
The noun(s) in the Operation ID should be the collection identifiers from the resource identifier.
The noun(s) in the Operation ID should be the collection identifiers from the resource identifier in singular form, where the last noun:
- Is in plural form if the method applies to a collection of resources
- Is in singular form if the method applies to a single resource

##### Implementation details
Rule checks for the following conditions:
- Applies only to paths containing custom method identifiers (with colon format)
- Generates the expected OperationId given the resource identifier and the method name portion following the colon
- Confirms that the existing operationId is compliant with generated IPA Compliant OperationId



### IPA-110
Expand Down
46 changes: 46 additions & 0 deletions tools/spectral/ipa/rulesets/functions/IPA109ValidOperationID.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { hasException } from './utils/exceptions.js';
import { collectAdoption, collectException, collectAndReturnViolation } from './utils/collectionUtils.js';
import { isCustomMethodIdentifier, getCustomMethodName, stripCustomMethodName } from './utils/resourceEvaluation.js';
import { generateOperationID } from './utils/operationIdGeneration.js';

const RULE_NAME = 'xgen-IPA-109-valid-operation-id';
const ERROR_MESSAGE = 'Invalid OperationID.';

export default (input, _, { path }) => {
let resourcePath = path[1];
const methodName = getCustomMethodName(resourcePath);

if (!isCustomMethodIdentifier(resourcePath)) {
return;
}

// TODO detect custom method extension - CLOUDP-306294

let obj;
if (input.post) {
obj = input.post;
} else if (input.get) {
obj = input.get;
} else {
return;
}

if (hasException(obj, RULE_NAME)) {
collectException(obj, RULE_NAME, path);
return;
}

const operationId = obj.operationId;
const expectedOperationID = generateOperationID(methodName, stripCustomMethodName(resourcePath));
if (expectedOperationID !== operationId) {
const errors = [
{
path,
message: `${ERROR_MESSAGE} Found ${operationId}, expected ${expectedOperationID}.`,
},
];
return collectAndReturnViolation(path, RULE_NAME, errors);
}

collectAdoption(path, RULE_NAME);
};
Loading