Skip to content

Commit 2eedd3f

Browse files
committed
CLOUDP-304929: exceptions on the each path
1 parent dd6ae51 commit 2eedd3f

File tree

4 files changed

+83
-8
lines changed

4 files changed

+83
-8
lines changed

tools/spectral/ipa/__tests__/IPA102CollectionIdentifierCamelCase.test.js

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,67 @@ testRule('xgen-IPA-102-collection-identifier-camelCase', [
124124
document: {
125125
paths: {
126126
'/resource_groups': {
127-
'x-xgen-IPA-exception': {
128-
'xgen-IPA-102-collection-identifier-camelCase': 'Legacy API path that cannot be changed',
127+
get: {
128+
'x-xgen-IPA-exception': {
129+
'xgen-IPA-102-collection-identifier-camelCase': 'Legacy API path that cannot be changed',
130+
},
131+
},
132+
delete: {
133+
'x-xgen-IPA-exception': {
134+
'xgen-IPA-102-collection-identifier-camelCase': 'Legacy API path that cannot be changed',
135+
},
136+
},
137+
},
138+
},
139+
},
140+
errors: [],
141+
},
142+
{
143+
name: 'valid with all methods having exceptions (every method needs exception)',
144+
document: {
145+
paths: {
146+
'/resource_groups': {
147+
get: {
148+
'x-xgen-IPA-exception': {
149+
'xgen-IPA-102-collection-identifier-camelCase': 'Legacy API path that cannot be changed',
150+
},
151+
},
152+
delete: {
153+
'x-xgen-IPA-exception': {
154+
'xgen-IPA-102-collection-identifier-camelCase': 'Legacy API path that cannot be changed',
155+
},
129156
},
130157
},
131158
},
132159
},
133160
errors: [],
134161
},
162+
{
163+
name: 'invalid when not all methods have exceptions',
164+
document: {
165+
paths: {
166+
'/resource_groups': {
167+
get: {
168+
'x-xgen-IPA-exception': {
169+
'xgen-IPA-102-collection-identifier-camelCase': 'Legacy API path that cannot be changed',
170+
},
171+
},
172+
post: {
173+
description: 'This method has no exception',
174+
},
175+
},
176+
},
177+
},
178+
errors: [
179+
{
180+
code: 'xgen-IPA-102-collection-identifier-camelCase',
181+
message:
182+
"Collection identifiers must be in camelCase. Path segment 'resource_groups' in path '/resource_groups' is not in camelCase.",
183+
path: ['paths', '/resource_groups'],
184+
severity: DiagnosticSeverity.Warning,
185+
},
186+
],
187+
},
135188
{
136189
name: 'reports violations for paths with double slashes',
137190
document: {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ rules:
1414
- Path parameters should also follow camelCase naming
1515
- Certain values can be exempted via the ignoredValues configuration that can be supplied as `ignoredValues`
1616
argument to the rule
17-
- Paths with `x-xgen-IPA-exception` for this rule are excluded from validation
17+
- Each operation within path with `x-xgen-IPA-exception` are excluded from validation
1818
- Double slashes (//) are not allowed in paths
1919
2020
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-102-collection-identifier-camelCase'

tools/spectral/ipa/rulesets/functions/IPA102CollectionIdentifierCamelCase.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
collectException,
55
handleInternalError,
66
} from './utils/collectionUtils.js';
7-
import { hasException } from './utils/exceptions.js';
7+
import { hasExceptionInEveryHttpMethod } from './utils/exceptions.js';
88
import { isPathParam } from './utils/componentUtils.js';
99
import { casing } from '@stoplight/spectral-functions';
1010

@@ -22,10 +22,12 @@ export default (input, options, { path, documentInventory }) => {
2222
const oas = documentInventory.resolved;
2323
const pathKey = input;
2424

25-
// Check for exception at the path level
26-
if (hasException(oas.paths[input], RULE_NAME)) {
27-
collectException(oas.paths[input], RULE_NAME, path);
28-
return;
25+
if (oas.paths[input]) {
26+
const pathItem = oas.paths[input];
27+
if (hasExceptionInEveryHttpMethod(pathItem, RULE_NAME)) {
28+
collectException(pathItem, RULE_NAME, path);
29+
return;
30+
}
2931
}
3032

3133
// Extract ignored values from options

tools/spectral/ipa/rulesets/functions/utils/exceptions.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,23 @@ export function hasException(object, ruleName) {
1313
}
1414
return false;
1515
}
16+
17+
/**
18+
* Checks if every HTTP method in the path item has an exception for the specified rule
19+
* Only considers methods that actually exist in the path item
20+
*
21+
* @param {object} pathItem - The path item object containing HTTP methods
22+
* @param {string} ruleName - The name of the rule to check for exceptions
23+
* @returns {boolean} true if every HTTP method has an exception for the rule, otherwise false
24+
*/
25+
export function hasExceptionInEveryHttpMethod(pathItem, ruleName) {
26+
if (!pathItem) return false;
27+
const httpMethods = ['get', 'post', 'put', 'delete', 'patch', 'options', 'head'];
28+
const existingMethods = httpMethods.filter((method) => pathItem[method]);
29+
30+
// If no HTTP methods exist, return false
31+
if (existingMethods.length === 0) return false;
32+
33+
// Check if every existing HTTP method has the exception
34+
return existingMethods.every((method) => hasException(pathItem[method], ruleName));
35+
}

0 commit comments

Comments
 (0)