Skip to content

Commit 92d6480

Browse files
CLOUDP-304967: Add IPA rule for description format
1 parent 3915e0a commit 92d6480

File tree

4 files changed

+187
-0
lines changed

4 files changed

+187
-0
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import testRule from './__helpers__/testRule';
2+
import { DiagnosticSeverity } from '@stoplight/types';
3+
4+
testRule('xgen-IPA-117-description-uppercase-period', [
5+
{
6+
name: 'valid description',
7+
document: {
8+
components: {
9+
schemas: {
10+
Schema: {
11+
properties: {
12+
id: {
13+
description: 'Description.',
14+
},
15+
},
16+
},
17+
},
18+
},
19+
},
20+
errors: [],
21+
},
22+
{
23+
name: 'invalid descriptions',
24+
document: {
25+
components: {
26+
schemas: {
27+
Schema: {
28+
properties: {
29+
noPeriod: {
30+
description: 'Description',
31+
},
32+
noUpperCase: {
33+
description: 'description.',
34+
},
35+
noUpperCaseNoPeriod: {
36+
description: 'description',
37+
},
38+
},
39+
},
40+
},
41+
},
42+
},
43+
errors: [
44+
{
45+
code: 'xgen-IPA-117-description-uppercase-period',
46+
message: 'Descriptions must end with a full stop(.).',
47+
path: ['components', 'schemas', 'Schema', 'properties', 'noPeriod'],
48+
severity: DiagnosticSeverity.Warning,
49+
},
50+
{
51+
code: 'xgen-IPA-117-description-uppercase-period',
52+
message: 'Descriptions must start with Uppercase.',
53+
path: ['components', 'schemas', 'Schema', 'properties', 'noUpperCase'],
54+
severity: DiagnosticSeverity.Warning,
55+
},
56+
{
57+
code: 'xgen-IPA-117-description-uppercase-period',
58+
message: 'Descriptions must start with Uppercase.',
59+
path: ['components', 'schemas', 'Schema', 'properties', 'noUpperCaseNoPeriod'],
60+
severity: DiagnosticSeverity.Warning,
61+
},
62+
{
63+
code: 'xgen-IPA-117-description-uppercase-period',
64+
message: 'Descriptions must end with a full stop(.).',
65+
path: ['components', 'schemas', 'Schema', 'properties', 'noUpperCaseNoPeriod'],
66+
severity: DiagnosticSeverity.Warning,
67+
},
68+
],
69+
},
70+
{
71+
name: 'invalid components with exceptions',
72+
document: {
73+
components: {
74+
schemas: {
75+
Schema: {
76+
properties: {
77+
noPeriod: {
78+
description: 'Description',
79+
'x-xgen-IPA-exception': {
80+
'xgen-IPA-117-description-uppercase-period': 'reason',
81+
},
82+
},
83+
noUpperCase: {
84+
description: 'description.',
85+
'x-xgen-IPA-exception': {
86+
'xgen-IPA-117-description-uppercase-period': 'reason',
87+
},
88+
},
89+
noUpperCaseNoPeriod: {
90+
description: 'description',
91+
'x-xgen-IPA-exception': {
92+
'xgen-IPA-117-description-uppercase-period': 'reason',
93+
},
94+
},
95+
},
96+
},
97+
},
98+
},
99+
},
100+
errors: [],
101+
},
102+
]);

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
functions:
55
- IPA117HasDescription
6+
- IPA117DescriptionUpperCasePeriod
67

78
rules:
89
xgen-IPA-117-description:
@@ -30,3 +31,27 @@ rules:
3031
- '$.components.parameters[*]'
3132
then:
3233
function: 'IPA117HasDescription'
34+
xgen-IPA-117-description-uppercase-period:
35+
description: |
36+
Descriptions must start with Uppercase and end with a full stop(.)
37+
38+
##### Implementation details
39+
Rule checks the format of the description property in the following components:
40+
- Info object
41+
- Tags
42+
- Operation objects
43+
- Inline schema properties for operation object requests and responses
44+
- Parameter objects (in operations and components)
45+
- Schema properties
46+
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-117-description-uppercase-period'
47+
severity: warn
48+
given:
49+
- '$.info'
50+
- '$.tags[*]'
51+
- '$.paths[*][get,put,post,delete,options,head,patch,trace]'
52+
- '$.paths[*][get,put,post,delete,options,head,patch,trace].parameters[*]'
53+
- '$.paths[*][get,put,post,delete,options,head,patch,trace]..content..properties[*]'
54+
- '$.components.schemas..properties[*]'
55+
- '$.components.parameters[*]'
56+
then:
57+
function: 'IPA117DescriptionUpperCasePeriod'

tools/spectral/ipa/rulesets/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,20 @@ Rule checks for description property in the following components:
535535
- Schema properties
536536
The rule also fails if the description is an empty string.
537537

538+
#### xgen-IPA-117-description-uppercase-period
539+
540+
![warn](https://img.shields.io/badge/warning-yellow)
541+
Descriptions must start with Uppercase and end with a full stop(.)
542+
543+
##### Implementation details
544+
Rule checks the format of the description property in the following components:
545+
- Info object
546+
- Tags
547+
- Operation objects
548+
- Inline schema properties for operation object requests and responses
549+
- Parameter objects (in operations and components)
550+
- Schema properties
551+
538552

539553

540554
### IPA-123
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { hasException } from './utils/exceptions.js';
2+
import {
3+
collectAdoption,
4+
collectAndReturnViolation,
5+
collectException,
6+
handleInternalError,
7+
} from './utils/collectionUtils.js';
8+
9+
const RULE_NAME = 'xgen-IPA-117-description-uppercase-period';
10+
const ERROR_MESSAGE_PERIOD = 'Descriptions must end with a full stop(.).';
11+
const ERROR_MESSAGE_UPPER_CASE = 'Descriptions must start with Uppercase.';
12+
13+
export default (input, opts, { path }) => {
14+
if (!input['description']) {
15+
return;
16+
}
17+
18+
if (hasException(input, RULE_NAME)) {
19+
collectException(input, RULE_NAME, path);
20+
return;
21+
}
22+
23+
const errors = checkViolationsAndReturnErrors(input['description'], path);
24+
if (errors.length !== 0) {
25+
return collectAndReturnViolation(path, RULE_NAME, errors);
26+
}
27+
collectAdoption(path, RULE_NAME);
28+
};
29+
30+
function checkViolationsAndReturnErrors(description, path) {
31+
const upperCaseStart = new RegExp(`^[A-Z]`);
32+
const periodEnd = new RegExp(`[.]$`);
33+
const errors = [];
34+
35+
try {
36+
if (!upperCaseStart.test(description)) {
37+
errors.push({ path, message: ERROR_MESSAGE_UPPER_CASE });
38+
}
39+
if (!periodEnd.test(description)) {
40+
errors.push({ path, message: ERROR_MESSAGE_PERIOD });
41+
}
42+
return errors;
43+
} catch (e) {
44+
handleInternalError(RULE_NAME, path, e);
45+
}
46+
}

0 commit comments

Comments
 (0)