Skip to content

Commit 63b0e40

Browse files
CLOUDP-291457: IPA-123 SchemaPath and Error Message Fix
1 parent 396a928 commit 63b0e40

File tree

3 files changed

+94
-23
lines changed

3 files changed

+94
-23
lines changed

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

Lines changed: 72 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { DiagnosticSeverity } from '@stoplight/types';
33

44
testRule('xgen-IPA-123-enum-values-must-be-upper-snake-case', [
55
{
6-
name: 'valid schema - components.schemas',
6+
name: 'valid schema - components.schemas.property',
77
document: {
88
components: {
99
schemas: {
@@ -21,18 +21,18 @@ testRule('xgen-IPA-123-enum-values-must-be-upper-snake-case', [
2121
errors: [],
2222
},
2323
{
24-
name: 'invalid schema with exception - components.schemas',
24+
name: 'invalid schema with exception - components.schemas.property',
2525
document: {
2626
components: {
2727
schemas: {
2828
SchemaName: {
29-
'x-xgen-IPA-exception': {
30-
'xgen-IPA-123-enum-values-must-be-upper-snake-case': 'reason',
31-
},
3229
properties: {
3330
exampleProperty: {
3431
enum: ['exampleA', 'exampleB'],
3532
type: 'string',
33+
'x-xgen-IPA-exception': {
34+
'xgen-IPA-123-enum-values-must-be-upper-snake-case': 'reason',
35+
},
3636
},
3737
},
3838
},
@@ -42,7 +42,7 @@ testRule('xgen-IPA-123-enum-values-must-be-upper-snake-case', [
4242
errors: [],
4343
},
4444
{
45-
name: 'invalid schema - components.schemas',
45+
name: 'invalid schema - components.schemas.property',
4646
document: {
4747
components: {
4848
schemas: {
@@ -60,14 +60,72 @@ testRule('xgen-IPA-123-enum-values-must-be-upper-snake-case', [
6060
errors: [
6161
{
6262
code: 'xgen-IPA-123-enum-values-must-be-upper-snake-case',
63-
message: 'exampleA enum value must be UPPER_SNAKE_CASE. http://go/ipa/123',
64-
path: ['components', 'schemas', 'SchemaName', 'properties', 'exampleProperty', 'enum', '0'],
63+
message: 'enum[0]:exampleA enum value must be UPPER_SNAKE_CASE. http://go/ipa/123',
64+
path: ['components', 'schemas', 'SchemaName', 'properties', 'exampleProperty'],
65+
severity: DiagnosticSeverity.Warning,
66+
},
67+
{
68+
code: 'xgen-IPA-123-enum-values-must-be-upper-snake-case',
69+
message: 'enum[1]:exampleB enum value must be UPPER_SNAKE_CASE. http://go/ipa/123',
70+
path: ['components', 'schemas', 'SchemaName', 'properties', 'exampleProperty'],
71+
severity: DiagnosticSeverity.Warning,
72+
},
73+
],
74+
},
75+
{
76+
name: 'valid schema - components.schemas',
77+
document: {
78+
components: {
79+
schemas: {
80+
SchemaName: {
81+
enum: ['EXAMPLE_A', 'EXAMPLE_B'],
82+
type: 'string',
83+
},
84+
},
85+
},
86+
},
87+
errors: [],
88+
},
89+
{
90+
name: 'invalid schema with exception - components.schemas',
91+
document: {
92+
components: {
93+
schemas: {
94+
SchemaName: {
95+
'x-xgen-IPA-exception': {
96+
'xgen-IPA-123-enum-values-must-be-upper-snake-case': 'reason',
97+
},
98+
enum: ['exampleA', 'exampleB'],
99+
type: 'string',
100+
},
101+
},
102+
},
103+
},
104+
errors: [],
105+
},
106+
{
107+
name: 'invalid schema - components.schemas',
108+
document: {
109+
components: {
110+
schemas: {
111+
SchemaName: {
112+
enum: ['exampleA', 'exampleB'],
113+
type: 'string',
114+
},
115+
},
116+
},
117+
},
118+
errors: [
119+
{
120+
code: 'xgen-IPA-123-enum-values-must-be-upper-snake-case',
121+
message: 'enum[0]:exampleA enum value must be UPPER_SNAKE_CASE. http://go/ipa/123',
122+
path: ['components', 'schemas', 'SchemaName'],
65123
severity: DiagnosticSeverity.Warning,
66124
},
67125
{
68126
code: 'xgen-IPA-123-enum-values-must-be-upper-snake-case',
69-
message: 'exampleB enum value must be UPPER_SNAKE_CASE. http://go/ipa/123',
70-
path: ['components', 'schemas', 'SchemaName', 'properties', 'exampleProperty', 'enum', '1'],
127+
message: 'enum[1]:exampleB enum value must be UPPER_SNAKE_CASE. http://go/ipa/123',
128+
path: ['components', 'schemas', 'SchemaName'],
71129
severity: DiagnosticSeverity.Warning,
72130
},
73131
],
@@ -136,14 +194,14 @@ testRule('xgen-IPA-123-enum-values-must-be-upper-snake-case', [
136194
errors: [
137195
{
138196
code: 'xgen-IPA-123-enum-values-must-be-upper-snake-case',
139-
message: 'exampleA enum value must be UPPER_SNAKE_CASE. http://go/ipa/123',
140-
path: ['paths', '/a/{exampleId}', 'get', 'parameters', '0', 'schema', 'enum', '0'],
197+
message: 'enum[0]:exampleA enum value must be UPPER_SNAKE_CASE. http://go/ipa/123',
198+
path: ['paths', '/a/{exampleId}', 'get', 'parameters', '0', 'schema'],
141199
severity: DiagnosticSeverity.Warning,
142200
},
143201
{
144202
code: 'xgen-IPA-123-enum-values-must-be-upper-snake-case',
145-
message: 'exampleB enum value must be UPPER_SNAKE_CASE. http://go/ipa/123',
146-
path: ['paths', '/a/{exampleId}', 'get', 'parameters', '0', 'schema', 'enum', '1'],
203+
message: 'enum[1]:exampleB enum value must be UPPER_SNAKE_CASE. http://go/ipa/123',
204+
path: ['paths', '/a/{exampleId}', 'get', 'parameters', '0', 'schema'],
147205
severity: DiagnosticSeverity.Warning,
148206
},
149207
],

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ export default (input, _, { path, documentInventory }) => {
1919

2020
if (isUpperSnakeCase) {
2121
errors.push({
22-
path: [...path, index],
23-
message: `${enumValue} ${ERROR_MESSAGE} `,
22+
path: schemaPath,
23+
message: `enum[${index}]:${enumValue} ${ERROR_MESSAGE} `,
2424
});
2525
}
2626
});

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

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,41 @@ export function isPathParam(str) {
1616
/**
1717
* Extracts the schema path from the given JSONPath array.
1818
*
19-
* This function is designed to handle two types of paths commonly encountered in OpenAPI definitions:
19+
* This function handles the following types of paths in OpenAPI definitions:
2020
*
2121
* 1. **Component Schema Paths**:
22-
* - Represented as: `components.schemas.schemaName.*.enum`
23-
* - This path indicates that the enum is defined within a schema under `components.schemas`.
22+
* - Represented as: `components.schemas.schemaName.enum`
23+
* - This path indicates that the enum is defined directly within a schema under `components.schemas`.
2424
* - The function returns the first three elements (`["components", "schemas", "schemaName"]`).
2525
*
26-
* 2. **Parameter Schema Paths**:
26+
* 2. **Component Schema Property Paths**:
27+
* - Represented as: `components.schemas.schemaName.properties.propertyName.enum`
28+
* - This path indicates that the enum is defined for a specific property of a schema.
29+
* - The function returns up to the property level (`["components", "schemas", "schemaName", "properties", "propertyName"]`).
30+
*
31+
* 3. **Parameter Schema Paths**:
2732
* - Represented as: `paths.*.method.parameters[*].schema.enum`
2833
* - This path indicates that the enum is part of a parameter's schema in an operation.
2934
* - The function identifies the location of `schema` in the path and returns everything up to (and including) it.
3035
*
3136
* @param {string[]} path - An array representing the JSONPath structure of the OpenAPI definition.
32-
* @returns {string[]} The truncated path pointing to the schema object.
37+
* @returns {string[]} The truncated path pointing to the schema object or property.
3338
*/
39+
3440
export function getSchemaPath(path) {
3541
if (path.includes('components')) {
42+
const propertyIndex = path.findIndex((item) => item === 'properties');
43+
if (propertyIndex !== -1) {
44+
// Path is for a component.schema.property enum
45+
return path.slice(0, propertyIndex + 2);
46+
}
47+
// Path is for a component.schema enum
3648
return path.slice(0, 3);
3749
} else if (path.includes('paths')) {
38-
const index = path.findIndex((item) => item === 'schema');
39-
return path.slice(0, index + 1);
50+
const schemaIndex = path.findIndex((item) => item === 'schema');
51+
return path.slice(0, schemaIndex + 1);
4052
}
53+
return [];
4154
}
4255

4356
/**

0 commit comments

Comments
 (0)