Skip to content

Commit 11a1288

Browse files
CLOUDP-306579: Repeated Fields
1 parent 68d522f commit 11a1288

File tree

6 files changed

+312
-0
lines changed

6 files changed

+312
-0
lines changed

openapi/.raw/.ipaspectral.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# https://meta.stoplight.io/docs/spectral/cb95cf0d26b83-core-functions
2+
extends:
3+
- https://raw.githubusercontent.com/mongodb/openapi/a3dd7046e8dccd24bb0eb9ccc9ad8c3e39f47685/tools/spectral/ipa/ipa-spectral.yaml
4+
5+
overrides:
6+
- files:
7+
- '**#/components/schemas/DataLakeDatabaseDataSourceSettings' # external field, to be covered by CLOUDP-293178
8+
- '**#/components/schemas/DataLakeAtlasStoreReadPreference' # external field, to be covered by CLOUDP-293178
9+
rules:
10+
xgen-IPA-123-enum-values-must-be-upper-snake-case: 'off'
11+
- files:
12+
- '**#/components/schemas/DataLakeAtlasStoreInstance' # external field, to be covered by CLOUDP-293178
13+
rules:
14+
xgen-IPA-112-avoid-project-field-names: 'off'
15+
- files:
16+
- '**#/components/schemas/ClusterProviderSettings/properties/providerName' # dynamic field which can't be documented
17+
- '**#/components/schemas/DataLakeStoreSettings/properties/provider' # external field, to be covered by CLOUDP-293178
18+
rules:
19+
xgen-IPA-117-description: 'off'
20+
- files:
21+
- '**#/components/schemas/DataLakeAzureBlobStore' # external field, to be covered by CLOUDP-293178
22+
- '**#/components/schemas/AdvancedClusterDescription/properties/mongoDBEmployeeAccessGrant' # unable to document exceptions, to be covered by CLOUDP-308286
23+
- '**#/components/schemas/AtlasTenantClusterUpgradeRequest20240805/properties/mongoDBEmployeeAccessGrant' # unable to document exceptions, to be covered by CLOUDP-308286
24+
- '**#/components/schemas/ClusterDescription20240805/properties/mongoDBEmployeeAccessGrant' # unable to document exceptions, to be covered by CLOUDP-308286
25+
- '**#/components/schemas/LegacyAtlasCluster/properties/mongoDBEmployeeAccessGrant' # unable to document exceptions, to be covered by CLOUDP-308286
26+
- '**#/components/schemas/LegacyAtlasTenantClusterUpgradeRequest/properties/mongoDBEmployeeAccessGrant' # unable to document exceptions, to be covered by CLOUDP-308286
27+
- '**#/components/schemas/AdvancedAutoScalingSettings/properties/diskGB' # unable to document exceptions, to be covered by CLOUDP-308286
28+
- '**#/components/schemas/UserSecurity/properties/customerX509' # unable to document exceptions, to be covered by CLOUDP-308286
29+
rules:
30+
xgen-IPA-112-field-names-are-camel-case: 'off'
31+
- files:
32+
- '**#/components/schemas/DataLakeS3StoreSettings/allOf/1/properties/additionalStorageClasses' # unable to document exceptions, to be covered by CLOUDP-293178
33+
- '**#/components/schemas/DataLakeDatabaseDataSourceSettings/properties/databaseRegex' # unable to document exceptions, to be covered by CLOUDP-293178
34+
- '**#/components/schemas/DataLakeDatabaseDataSourceSettings/properties/collectionRegex' # unable to document exceptions, to be covered by CLOUDP-293178
35+
rules:
36+
xgen-IPA-117-description-should-not-use-inline-links: 'off'
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
import testRule from './__helpers__/testRule.js';
2+
import { DiagnosticSeverity } from '@stoplight/types';
3+
4+
testRule('xgen-IPA-124-array-max-items', [
5+
{
6+
name: 'valid array with maxItems set to 100',
7+
document: {
8+
components: {
9+
schemas: {
10+
ValidSchema: {
11+
type: 'object',
12+
properties: {
13+
items: {
14+
type: 'array',
15+
maxItems: 100,
16+
items: {
17+
type: 'string'
18+
}
19+
}
20+
}
21+
}
22+
}
23+
}
24+
},
25+
errors: []
26+
},
27+
{
28+
name: 'invalid array missing maxItems',
29+
document: {
30+
components: {
31+
schemas: {
32+
InvalidSchema: {
33+
type: 'object',
34+
properties: {
35+
items: {
36+
type: 'array',
37+
items: {
38+
type: 'string'
39+
}
40+
}
41+
}
42+
}
43+
}
44+
}
45+
},
46+
errors: [
47+
{
48+
code: 'xgen-IPA-124-array-max-items',
49+
message: 'Array must have maxItems property defined.',
50+
path: ['components', 'schemas', 'InvalidSchema', 'properties', 'items'],
51+
severity: DiagnosticSeverity.Warning
52+
}
53+
]
54+
},
55+
{
56+
name: 'invalid array with incorrect maxItems value',
57+
document: {
58+
components: {
59+
schemas: {
60+
InvalidSchema: {
61+
type: 'object',
62+
properties: {
63+
items: {
64+
type: 'array',
65+
maxItems: 50,
66+
items: {
67+
type: 'string'
68+
}
69+
}
70+
}
71+
}
72+
}
73+
}
74+
},
75+
errors: [
76+
{
77+
code: 'xgen-IPA-124-array-max-items',
78+
message: 'Array maxItems must be set to 100, found: 50.',
79+
path: ['components', 'schemas', 'InvalidSchema', 'properties', 'items'],
80+
severity: DiagnosticSeverity.Warning
81+
}
82+
]
83+
},
84+
{
85+
name: 'array with exception should be skipped',
86+
document: {
87+
components: {
88+
schemas: {
89+
ExceptionSchema: {
90+
type: 'object',
91+
properties: {
92+
items: {
93+
type: 'array',
94+
items: {
95+
type: 'string'
96+
},
97+
'x-xgen-IPA-exception': {
98+
'xgen-IPA-124-array-max-items': 'Reason'
99+
}
100+
}
101+
}
102+
}
103+
}
104+
}
105+
},
106+
errors: []
107+
},
108+
{
109+
name: 'nested arrays should all be checked',
110+
document: {
111+
components: {
112+
schemas: {
113+
NestedArrays: {
114+
type: 'object',
115+
properties: {
116+
outerArray: {
117+
type: 'array',
118+
maxItems: 100,
119+
items: {
120+
type: 'array',
121+
maxItems: 50,
122+
items: {
123+
type: 'string'
124+
}
125+
}
126+
}
127+
}
128+
}
129+
}
130+
}
131+
},
132+
errors: [
133+
{
134+
code: 'xgen-IPA-124-array-max-items',
135+
message: 'Array maxItems must be set to 100, found: 50.',
136+
path: ['components', 'schemas', 'NestedArrays', 'properties', 'outerArray', 'items'],
137+
severity: DiagnosticSeverity.Warning
138+
}
139+
]
140+
},
141+
{
142+
name: 'arrays in request/response bodies should be checked',
143+
document: {
144+
paths: {
145+
'/api/resources': {
146+
post: {
147+
requestBody: {
148+
content: {
149+
'application/json': {
150+
schema: {
151+
type: 'object',
152+
properties: {
153+
items: {
154+
type: 'array',
155+
items: {
156+
type: 'string'
157+
}
158+
}
159+
}
160+
}
161+
}
162+
}
163+
}
164+
}
165+
}
166+
}
167+
},
168+
errors: [
169+
{
170+
code: 'xgen-IPA-124-array-max-items',
171+
message: 'Array must have maxItems property defined.',
172+
path: ['paths', '/api/resources', 'post', 'requestBody', 'content', 'application/json', 'schema', 'properties', 'items'],
173+
severity: DiagnosticSeverity.Warning
174+
}
175+
]
176+
}
177+
]);

tools/spectral/ipa/ipa-spectral.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ extends:
1616
- ./rulesets/IPA-119.yaml
1717
- ./rulesets/IPA-121.yaml
1818
- ./rulesets/IPA-123.yaml
19+
- ./rulesets/IPA-124.yaml
1920
- ./rulesets/IPA-125.yaml
2021

2122
overrides:
@@ -56,3 +57,4 @@ overrides:
5657
- '**#/paths/~1rest~1unauth~1version' # external reference, to be covered by CLOUDP-309694
5758
rules:
5859
xgen-IPA-114-error-responses-refer-to-api-error: 'off'
60+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# IPA-124: Repeated Fields
2+
# http://go/ipa/124
3+
4+
functions:
5+
- IPA124ArrayMaxItems
6+
7+
rules:
8+
xgen-IPA-124-array-max-items:
9+
description: |
10+
Array fields must have a maxItems property defined with a value of 100.
11+
12+
##### Implementation details
13+
Rule checks for the following conditions:
14+
15+
- All schema objects with type 'array' must have a maxItems property
16+
- The maxItems value must be set to 100
17+
- Schema objects with `x-xgen-IPA-exception` for this rule are excluded from validation
18+
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-124-array-max-items'
19+
severity: warn
20+
resolved: false
21+
given: $..[?(@.type=="array")]
22+
then:
23+
function: IPA124ArrayMaxItems
24+
functionOptions:
25+
maxItems: 100

tools/spectral/ipa/rulesets/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,24 @@ Rule checks for the following conditions:
844844

845845

846846

847+
### IPA-124
848+
849+
Rules are based on [http://go/ipa/IPA-124](http://go/ipa/IPA-124).
850+
851+
#### xgen-IPA-124-array-max-items
852+
853+
![warn](https://img.shields.io/badge/warning-yellow)
854+
Array fields must have a maxItems property defined with a value of 100.
855+
856+
##### Implementation details
857+
Rule checks for the following conditions:
858+
859+
- All schema objects with type 'array' must have a maxItems property
860+
- The maxItems value must be set to 100
861+
- Schema objects with `x-xgen-IPA-exception` for this rule are excluded from validation
862+
863+
864+
847865
### IPA-125
848866

849867
Rules are based on [http://go/ipa/IPA-125](http://go/ipa/IPA-125).
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import {
2+
collectAdoption,
3+
collectAndReturnViolation,
4+
collectException,
5+
handleInternalError,
6+
} from './utils/collectionUtils.js';
7+
import { hasException } from './utils/exceptions.js';
8+
9+
const RULE_NAME = 'xgen-IPA-124-array-max-items';
10+
11+
/**
12+
* Checks if array fields have maxItems defined and set to 100
13+
*
14+
* @param {object} input - The array schema object from the OpenAPI spec
15+
* @param {object} options - Rule configuration options
16+
* @param {object} context - The context object containing the path and documentInventory
17+
*/
18+
export default (input, { maxItems }, { path }) => {
19+
// Check for exception at the schema level
20+
if (hasException(input, RULE_NAME)) {
21+
collectException(input, RULE_NAME, path);
22+
return;
23+
}
24+
25+
const errors = checkViolationsAndReturnErrors(input, path, maxItems);
26+
if (errors.length > 0) {
27+
return collectAndReturnViolation(path, RULE_NAME, errors);
28+
}
29+
30+
collectAdoption(path, RULE_NAME);
31+
};
32+
33+
function checkViolationsAndReturnErrors(input, path, maxItems) {
34+
try {
35+
// Check if maxItems is defined
36+
if (input.maxItems === undefined) {
37+
return [{
38+
message: `Array must have maxItems property defined.`,
39+
path,
40+
}];
41+
}
42+
// Check if maxItems is set to the required value
43+
else if (input.maxItems !== maxItems) {
44+
return [{
45+
message: `Array maxItems must be set to ${maxItems}, found: ${input.maxItems}.`,
46+
path,
47+
}];
48+
}
49+
50+
return [];
51+
} catch (e) {
52+
handleInternalError(RULE_NAME, path, e);
53+
}
54+
}

0 commit comments

Comments
 (0)