Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions tools/spectral/ipa/__tests__/IPA104ValidOperationID.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
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-104-valid-operation-id', [
{
name: 'valid methods',
document: {
paths: {
'/groups/{groupId}/cluster/{clusterName}': {
get: {
operationId: 'getGroupCluster',
},
},
},
},
errors: [],
},
// This test will be enable when the xgen-IPA-104-valid-operation-id is set to warning severity - CLOUDP-329722
/* {
name: 'invalid methods',
document: {
paths: {
'/api/atlas/v2/groups/{groupId}/accessList/{entryValue}/status': {
get: {
operationId: 'getProjectIpAccessListStatus',
},
},
'/api/atlas/v2/groups/{groupId}/dataFederation/{tenantName}/limits/{limitName}': {
get: {
operationId: 'returnFederatedDatabaseQueryLimit',
},
},
},
},
errors: [
{
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.',
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.',
path: ['paths', '/api/atlas/v2/groups/{groupId}/dataFederation/{tenantName}/limits/{limitName}', 'get'],
severity: DiagnosticSeverity.Warning,
},
],
}, */
{
name: 'invalid methods with exceptions',
document: {
paths: {
'/api/atlas/v2/groups/{groupId}/clusters/{clusterName}/index ': {
get: {
operationId: 'getRollingIndex',
'x-xgen-IPA-exception': {
'xgen-IPA-104-valid-operation-id': 'Reason',
},
},
},
},
},
errors: [],
},
]);
70 changes: 70 additions & 0 deletions tools/spectral/ipa/__tests__/IPA105ValidOperationID.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
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-105-valid-operation-id', [
{
name: 'valid methods',
document: {
paths: {
'/groups/{groupId}/clusters': {
get: {
operationId: 'listGroupClusters',
},
},
},
},
errors: [],
},
// This test will be enable when the xgen-IPA-105-valid-operation-id is set to warning severity - CLOUDP-329722
/* {
name: 'invalid methods',
document: {
paths: {
'/api/atlas/v2/orgs/{orgId}/teams/{teamId}/users': {
get: {
operationId: 'listTeamUsers',
},
},
'/api/atlas/v2/orgs/{orgId}/events': {
get: {
operationId: 'listOrganizationEvents',
},
},
},
},
errors: [
{
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.',
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.',
path: ['paths', '/api/atlas/v2/orgs/{orgId}/events', 'get'],
severity: DiagnosticSeverity.Warning,
},
],
}, */
{
name: 'invalid methods with exceptions',
document: {
paths: {
'/api/atlas/v2/groups/{groupId}/clusters/{clusterName}/outageSimulation': {
get: {
operationId: 'getOutageSimulation',
'x-xgen-IPA-exception': {
'xgen-IPA-105-valid-operation-id': 'Reason',
},
},
},
},
},
errors: [],
},
]);
19 changes: 19 additions & 0 deletions tools/spectral/ipa/rulesets/IPA-104.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ functions:
- IPA104GetResponseCodeShouldBe200OK
- IPA104GetMethodResponseHasNoInputFields
- IPA104GetMethodHasNoRequestBody
- IPA104ValidOperationID

aliases:
GetOperationObject:
Expand Down Expand Up @@ -97,3 +98,21 @@ rules:
given: '#GetOperationObject'
then:
function: 'IPA104GetMethodHasNoRequestBody'
xgen-IPA-104-valid-operation-id:
description: |
The Operation ID must start with the verb “get” 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.
If the resource is a singleton resource, the last noun may be the plural form of the collection identifier.

##### Implementation details
Rule checks for the following conditions:
- Applies only to GET methods on single resources or singleton resources
- Generates the expected OperationId given the resource identifier
- Confirms that the existing operationId is compliant with generated IPA Compliant OperationId
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-104-valid-operation-id'
severity: off
given: '#GetOperationObject'
then:
function: 'IPA104ValidOperationID'
functionOptions:
methodName: 'get'
19 changes: 19 additions & 0 deletions tools/spectral/ipa/rulesets/IPA-105.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ functions:
- IPA105ListMethodHasNoRequestBody
- IPA105EachResourceHasListMethod
- IPA105ListMethodResponseIsGetMethodResponse
- IPA105ValidOperationID

aliases:
GetOperationObject:
Expand Down Expand Up @@ -77,3 +78,21 @@ rules:
then:
field: '@key'
function: 'IPA105ListMethodResponseIsGetMethodResponse'
xgen-IPA-105-valid-operation-id:
description: |
The Operation ID must start with the verb “list” 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, where the last noun is in plural form.

##### Implementation details
Rule checks for the following conditions:
- Applies only to GET methods on resource collection paths
- Ignores singleton resources
- Generates the expected OperationId given the resource identifier
- Confirms that the existing operationId is compliant with generated IPA Compliant OperationId
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-105-valid-operation-id'
severity: off
given: '#GetOperationObject'
then:
function: 'IPA105ValidOperationID'
functionOptions:
methodName: 'list'
26 changes: 26 additions & 0 deletions tools/spectral/ipa/rulesets/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,19 @@ Rule checks for the following conditions:
- Applies only to GET methods on single resources or singleton resources
- Verifies that the operation object does not contain a requestBody property

#### xgen-IPA-104-valid-operation-id

`off`
The Operation ID must start with the verb “get” 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.
If the resource is a singleton resource, the last noun may be the plural form of the collection identifier.

##### Implementation details
Rule checks for the following conditions:
- Applies only to GET methods on single resources or singleton resources
- Generates the expected OperationId given the resource identifier
- Confirms that the existing operationId is compliant with generated IPA Compliant OperationId



### IPA-105
Expand Down Expand Up @@ -193,6 +206,19 @@ The response body of the List method should consist of the same resource object
- Fails if the Get method doesn't have a schema reference or if the schemas don't match
- Validation ignores resources without a Get method
- Paths with `x-xgen-IPA-exception` for this rule are excluded from validation
#### xgen-IPA-105-valid-operation-id

`off`
The Operation ID must start with the verb “list” 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, where the last noun is in plural form.

##### Implementation details
Rule checks for the following conditions:
- Applies only to GET methods on resource collection paths
- Ignores singleton resources
- Generates the expected OperationId given the resource identifier
- Confirms that the existing operationId is compliant with generated IPA Compliant OperationId



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

const RULE_NAME = 'xgen-IPA-104-valid-operation-id';
const ERROR_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.';

export default (input, { methodName }, { path, documentInventory }) => {
const resourcePath = path[1];
const oas = documentInventory.resolved;
const resourcePaths = getResourcePathItems(resourcePath, oas.paths);

if (
isCustomMethodIdentifier(resourcePath) ||
(!isSingleResourceIdentifier(resourcePath) &&
!(isResourceCollectionIdentifier(resourcePath) && isSingletonResource(resourcePaths)))
) {
return;
}

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

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

return collectAdoption(path, RULE_NAME);
};
44 changes: 44 additions & 0 deletions tools/spectral/ipa/rulesets/functions/IPA105ValidOperationID.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { hasException } from './utils/exceptions.js';
import { collectAdoption, collectAndReturnViolation, collectException } from './utils/collectionUtils.js';
import {
getResourcePathItems,
isCustomMethodIdentifier,
isResourceCollectionIdentifier,
isSingletonResource,
} from './utils/resourceEvaluation.js';
import { generateOperationID } from './utils/operationIdGeneration.js';

const RULE_NAME = 'xgen-IPA-105-valid-operation-id';
const ERROR_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.';

export default (input, { methodName }, { path, documentInventory }) => {
const resourcePath = path[1];
const oas = documentInventory.resolved;

if (
isCustomMethodIdentifier(resourcePath) ||
!isResourceCollectionIdentifier(resourcePath) ||
isSingletonResource(getResourcePathItems(resourcePath, oas.paths))
) {
return;
}

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

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

return collectAdoption(path, RULE_NAME);
};
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ export default (input, { methodName }, { path, documentInventory }) => {

const expectedOperationID = generateOperationID(methodName, resourcePath);
if (expectedOperationID !== input.operationId) {
console.log(
`${input.operationId}, ${expectedOperationID}, ${resourcePath}, ${input.deprecated ? 'TRUE' : 'FALSE'}, ${(resourcePath, input['x-xgen-owner-team'])}`
);
const errors = [
{
path,
Expand Down
Loading