Skip to content

Commit 395dcdd

Browse files
feat(ipa): new rules for operation summaries starting with specific words (#903)
1 parent 31550b0 commit 395dcdd

File tree

6 files changed

+356
-2
lines changed

6 files changed

+356
-2
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import testRule from './__helpers__/testRule';
2+
import { DiagnosticSeverity } from '@stoplight/types';
3+
4+
testRule('xgen-IPA-117-create-operation-summary-starts-with', [
5+
{
6+
name: 'valid summary',
7+
document: {
8+
paths: {
9+
'/resource': {
10+
post: {
11+
summary: 'Create One Resource',
12+
},
13+
},
14+
'/projects/{id}/users': {
15+
post: {
16+
summary: 'Add One User to One Project',
17+
},
18+
},
19+
'/projects/{id}/users:invite': {
20+
// Ignores custom method
21+
post: {
22+
summary: 'Invite One User to One Project',
23+
},
24+
},
25+
'/projects/{id}/users/invite': {
26+
// Ignores legacy custom method
27+
post: {
28+
summary: 'Invite One User to One Project',
29+
'x-xgen-method-verb-override': {
30+
customMethod: true,
31+
},
32+
},
33+
},
34+
},
35+
},
36+
errors: [],
37+
},
38+
{
39+
name: 'invalid summaries',
40+
document: {
41+
paths: {
42+
'/resource': {
43+
post: {
44+
summary: 'Creating One Resource',
45+
},
46+
},
47+
'/projects/{id}/users': {
48+
post: {
49+
summary: 'Adds One User to One Project',
50+
},
51+
},
52+
},
53+
},
54+
errors: [
55+
{
56+
code: 'xgen-IPA-117-create-operation-summary-starts-with',
57+
message: 'Operation summary must start with one of the words [Create,Add].',
58+
path: ['paths', '/resource', 'post'],
59+
severity: DiagnosticSeverity.Warning,
60+
},
61+
{
62+
code: 'xgen-IPA-117-create-operation-summary-starts-with',
63+
message: 'Operation summary must start with one of the words [Create,Add].',
64+
path: ['paths', '/projects/{id}/users', 'post'],
65+
severity: DiagnosticSeverity.Warning,
66+
},
67+
],
68+
},
69+
{
70+
name: 'invalid summary with exceptions',
71+
document: {
72+
paths: {
73+
'/resource': {
74+
post: {
75+
summary: 'Creating One Resource',
76+
'x-xgen-IPA-exception': {
77+
'xgen-IPA-117-create-operation-summary-starts-with': 'reason',
78+
},
79+
},
80+
},
81+
'/projects/{id}/users': {
82+
post: {
83+
summary: 'Adds One User to One Project',
84+
'x-xgen-IPA-exception': {
85+
'xgen-IPA-117-create-operation-summary-starts-with': 'reason',
86+
},
87+
},
88+
},
89+
},
90+
},
91+
errors: [],
92+
},
93+
]);
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import testRule from './__helpers__/testRule';
2+
import { DiagnosticSeverity } from '@stoplight/types';
3+
4+
testRule('xgen-IPA-117-delete-operation-summary-starts-with', [
5+
{
6+
name: 'valid summary',
7+
document: {
8+
paths: {
9+
'/resource': {
10+
delete: {
11+
summary: 'Delete One Resource',
12+
},
13+
},
14+
'/projects/{id}/users': {
15+
delete: {
16+
summary: 'Remove One User from One Project',
17+
},
18+
},
19+
},
20+
},
21+
errors: [],
22+
},
23+
{
24+
name: 'invalid summaries',
25+
document: {
26+
paths: {
27+
'/resource': {
28+
delete: {
29+
summary: 'Destroy One Resource',
30+
},
31+
},
32+
'/projects/{id}/users': {
33+
delete: {
34+
summary: 'Deletes One User from One Project',
35+
},
36+
},
37+
},
38+
},
39+
errors: [
40+
{
41+
code: 'xgen-IPA-117-delete-operation-summary-starts-with',
42+
message: 'Operation summary must start with one of the words [Delete,Remove].',
43+
path: ['paths', '/resource', 'delete'],
44+
severity: DiagnosticSeverity.Warning,
45+
},
46+
{
47+
code: 'xgen-IPA-117-delete-operation-summary-starts-with',
48+
message: 'Operation summary must start with one of the words [Delete,Remove].',
49+
path: ['paths', '/projects/{id}/users', 'delete'],
50+
severity: DiagnosticSeverity.Warning,
51+
},
52+
],
53+
},
54+
{
55+
name: 'invalid summary with exceptions',
56+
document: {
57+
paths: {
58+
'/resource': {
59+
delete: {
60+
summary: 'Destroy One Resource',
61+
'x-xgen-IPA-exception': {
62+
'xgen-IPA-117-delete-operation-summary-starts-with': 'reason',
63+
},
64+
},
65+
},
66+
'/projects/{id}/users': {
67+
delete: {
68+
summary: 'Deletes One User from One Project',
69+
'x-xgen-IPA-exception': {
70+
'xgen-IPA-117-delete-operation-summary-starts-with': 'reason',
71+
},
72+
},
73+
},
74+
},
75+
},
76+
errors: [],
77+
},
78+
]);
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import testRule from './__helpers__/testRule';
2+
import { DiagnosticSeverity } from '@stoplight/types';
3+
4+
testRule('xgen-IPA-117-update-operation-summary-starts-with', [
5+
{
6+
name: 'valid summary',
7+
document: {
8+
paths: {
9+
'/resource': {
10+
patch: {
11+
summary: 'Update One Resource',
12+
},
13+
},
14+
'/projects/{id}/users': {
15+
put: {
16+
summary: 'Update One User in One Project',
17+
},
18+
},
19+
},
20+
},
21+
errors: [],
22+
},
23+
{
24+
name: 'invalid summaries',
25+
document: {
26+
paths: {
27+
'/resource': {
28+
patch: {
29+
summary: 'Modify One Resource',
30+
},
31+
},
32+
'/projects/{id}/users': {
33+
put: {
34+
summary: 'Change One User to One Project',
35+
},
36+
},
37+
},
38+
},
39+
errors: [
40+
{
41+
code: 'xgen-IPA-117-update-operation-summary-starts-with',
42+
message: 'Operation summary must start with the word "Update".',
43+
path: ['paths', '/resource', 'patch'],
44+
severity: DiagnosticSeverity.Warning,
45+
},
46+
{
47+
code: 'xgen-IPA-117-update-operation-summary-starts-with',
48+
message: 'Operation summary must start with the word "Update".',
49+
path: ['paths', '/projects/{id}/users', 'put'],
50+
severity: DiagnosticSeverity.Warning,
51+
},
52+
],
53+
},
54+
{
55+
name: 'invalid summary with exceptions',
56+
document: {
57+
paths: {
58+
'/resource': {
59+
patch: {
60+
summary: 'Modify One Resource',
61+
'x-xgen-IPA-exception': {
62+
'xgen-IPA-117-update-operation-summary-starts-with': 'reason',
63+
},
64+
},
65+
},
66+
'/projects/{id}/users': {
67+
put: {
68+
summary: 'Change One User to One Project',
69+
'x-xgen-IPA-exception': {
70+
'xgen-IPA-117-update-operation-summary-starts-with': 'reason',
71+
},
72+
},
73+
},
74+
},
75+
},
76+
errors: [],
77+
},
78+
]);

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

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ functions:
1212
- IPA117ObjectsMustBeWellDefined
1313
- IPA117ParameterHasExamplesOrSchema
1414
- IPA117OperationSummaryFormat
15-
- IPA117OperationSummaryGetStartsWith
15+
- IPA117OperationSummaryStartsWith
1616

1717
aliases:
1818
OperationObject:
@@ -298,7 +298,66 @@ rules:
298298
given:
299299
- '$.paths[*][get].summary'
300300
then:
301-
function: 'IPA117OperationSummaryGetStartsWith'
301+
function: 'IPA117OperationSummaryStartsWith'
302302
functionOptions:
303303
allowedStartVerbs:
304304
- Return
305+
xgen-IPA-117-update-operation-summary-starts-with:
306+
description: |
307+
In operation summaries, use 'Update' instead of 'Modify' or 'Change'. For example "Update One Identity Provider".
308+
309+
##### Implementation details
310+
- The rule checks that the `summary` property of update operations use the word 'Update' as the first word.
311+
- The rule only applies to update methods and ignores custom methods
312+
##### Configuration
313+
This rule includes a configuration option:
314+
- `allowedStartVerbs`: Allow list of verb that the operation summary can start with, defaults to `['Update']`
315+
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-117-update-operation-summary-starts-with'
316+
severity: warn
317+
given:
318+
- '$.paths[*][put,patch].summary'
319+
then:
320+
function: 'IPA117OperationSummaryStartsWith'
321+
functionOptions:
322+
allowedStartVerbs:
323+
- Update
324+
xgen-IPA-117-create-operation-summary-starts-with:
325+
description: |
326+
In operation summaries, use 'Create' when the operation is creating a resource, and use 'Add' when the resource itself isn't being created. For example "Create One Identity Provider" or "Add One MongoDB Cloud User to One Project".
327+
328+
##### Implementation details
329+
- The rule checks that the `summary` property of create operations use the word 'Create' or 'Add' as the first word.
330+
- The rule only applies to create methods and ignores custom methods
331+
##### Configuration
332+
This rule includes a configuration option:
333+
- `allowedStartVerbs`: Allow list of verb that the operation summary can start with, defaults to `['Create', 'Add']`
334+
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-117-create-operation-summary-starts-with'
335+
severity: warn
336+
given:
337+
- '$.paths[*][post].summary'
338+
then:
339+
function: 'IPA117OperationSummaryStartsWith'
340+
functionOptions:
341+
allowedStartVerbs:
342+
- Create
343+
- Add
344+
xgen-IPA-117-delete-operation-summary-starts-with:
345+
description: |
346+
In operation summaries, use 'Delete' when the operation is destroying a resource, and use 'Remove' when the resource itself isn't being destroyed. For example "Delete One Identity Provider" or "Remove One MongoDB Cloud User from One Project".
347+
348+
##### Implementation details
349+
- The rule checks that the `summary` property of delete operations use the word 'Delete' or 'Remove' as the first word.
350+
- The rule only applies to delete methods and ignores custom methods
351+
##### Configuration
352+
This rule includes a configuration option:
353+
- `allowedStartVerbs`: Allow list of verb that the operation summary can start with, defaults to `['Delete', 'Remove']`
354+
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-117-delete-operation-summary-starts-with'
355+
severity: warn
356+
given:
357+
- '$.paths[*][delete].summary'
358+
then:
359+
function: 'IPA117OperationSummaryStartsWith'
360+
functionOptions:
361+
allowedStartVerbs:
362+
- Delete
363+
- Remove

tools/spectral/ipa/rulesets/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,42 @@ In operation summaries, use 'Return' instead of 'Get' or 'List'. For example "Re
904904
This rule includes a configuration option:
905905
- `allowedStartVerbs`: Allow list of verb that the operation summary can start with, defaults to `['Return']`
906906

907+
#### xgen-IPA-117-update-operation-summary-starts-with
908+
909+
![warn](https://img.shields.io/badge/warning-yellow)
910+
In operation summaries, use 'Update' instead of 'Modify' or 'Change'. For example "Update One Identity Provider".
911+
912+
##### Implementation details
913+
- The rule checks that the `summary` property of update operations use the word 'Update' as the first word.
914+
- The rule only applies to update methods and ignores custom methods
915+
##### Configuration
916+
This rule includes a configuration option:
917+
- `allowedStartVerbs`: Allow list of verb that the operation summary can start with, defaults to `['Update']`
918+
919+
#### xgen-IPA-117-create-operation-summary-starts-with
920+
921+
![warn](https://img.shields.io/badge/warning-yellow)
922+
In operation summaries, use 'Create' when the operation is creating a resource, and use 'Add' when the resource itself isn't being created. For example "Create One Identity Provider" or "Add One MongoDB Cloud User to One Project".
923+
924+
##### Implementation details
925+
- The rule checks that the `summary` property of create operations use the word 'Create' or 'Add' as the first word.
926+
- The rule only applies to create methods and ignores custom methods
927+
##### Configuration
928+
This rule includes a configuration option:
929+
- `allowedStartVerbs`: Allow list of verb that the operation summary can start with, defaults to `['Create', 'Add']`
930+
931+
#### xgen-IPA-117-delete-operation-summary-starts-with
932+
933+
![warn](https://img.shields.io/badge/warning-yellow)
934+
In operation summaries, use 'Delete' when the operation is destroying a resource, and use 'Remove' when the resource itself isn't being destroyed. For example "Delete One Identity Provider" or "Remove One MongoDB Cloud User from One Project".
935+
936+
##### Implementation details
937+
- The rule checks that the `summary` property of delete operations use the word 'Delete' or 'Remove' as the first word.
938+
- The rule only applies to delete methods and ignores custom methods
939+
##### Configuration
940+
This rule includes a configuration option:
941+
- `allowedStartVerbs`: Allow list of verb that the operation summary can start with, defaults to `['Delete', 'Remove']`
942+
907943

908944

909945
### IPA-118

tools/spectral/ipa/rulesets/functions/IPA117OperationSummaryGetStartsWith.js renamed to tools/spectral/ipa/rulesets/functions/IPA117OperationSummaryStartsWith.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@ import { resolveObject } from './utils/componentUtils.js';
33
import { isCustomMethodIdentifier } from './utils/resourceEvaluation.js';
44
import { hasCustomMethodOverride } from './utils/extensions.js';
55

6+
/**
7+
* Checks if the operation summary starts with one of the allowed verbs in the 'allowedStartVerbs' list. The rule ignores custom methods.
8+
* Note: This function is used by multiple rules evaluating get/list, update, delete and create.
9+
* @param input the operation summary to evaluate
10+
* @param allowedStartVerbs the list of allowed verbs that the operation summary must start with
11+
* @param path the path to the operation object summary in the document
12+
* @param rule the rule object containing the rule name and other metadata
13+
* @param documentInventory the document inventory containing the resolved OAS document
14+
* @returns {Array<{path: Array<string>, message: string}>|undefined} error if the summary does not start with one of the allowed verbs, or undefined if there are no errors
15+
*/
616
export default (input, { allowedStartVerbs }, { path, rule, documentInventory }) => {
717
const resourcePath = path[1];
818
const operationObjectPath = path.slice(0, -1);

0 commit comments

Comments
 (0)