Skip to content

Commit 7cd81a5

Browse files
committed
fix: more specific errors
1 parent 0efbfd7 commit 7cd81a5

File tree

2 files changed

+85
-6
lines changed

2 files changed

+85
-6
lines changed

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

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,74 @@ testRule('xgen-IPA-125-oneOf-must-have-discriminator', [
9494
errors: [
9595
{
9696
code: 'xgen-IPA-125-oneOf-must-have-discriminator',
97-
message: 'Each oneOf property must include a discriminator property to define the exact type.',
97+
message: 'The schema has oneOf but no discriminator property.',
98+
path: ['schemas', 'Animal'],
99+
severity: DiagnosticSeverity.Error,
100+
},
101+
],
102+
},
103+
{
104+
name: 'invalid oneOf with non-object discriminator',
105+
document: {
106+
components: componentSchemas,
107+
schemas: {
108+
Animal: {
109+
oneOf: [{ $ref: '#/components/schemas/Dog' }, { $ref: '#/components/schemas/Cat' }],
110+
discriminator: "I'm a string, not an object!",
111+
},
112+
},
113+
},
114+
errors: [
115+
{
116+
code: 'xgen-IPA-125-oneOf-must-have-discriminator',
117+
message: 'Discriminator property is not an object.',
118+
path: ['schemas', 'Animal'],
119+
severity: DiagnosticSeverity.Error,
120+
},
121+
],
122+
},
123+
{
124+
name: 'invalid oneOf with discriminator but no propertyName',
125+
document: {
126+
components: componentSchemas,
127+
schemas: {
128+
Animal: {
129+
oneOf: [{ $ref: '#/components/schemas/Dog' }, { $ref: '#/components/schemas/Cat' }],
130+
discriminator: {
131+
mapping: {
132+
dog: '#/components/schemas/Dog',
133+
cat: '#/components/schemas/Cat',
134+
},
135+
},
136+
},
137+
},
138+
},
139+
errors: [
140+
{
141+
code: 'xgen-IPA-125-oneOf-must-have-discriminator',
142+
message: 'Discriminator has no propertyName defined.',
143+
path: ['schemas', 'Animal'],
144+
severity: DiagnosticSeverity.Error,
145+
},
146+
],
147+
},
148+
{
149+
name: 'invalid oneOf with discriminator but no mapping',
150+
document: {
151+
components: componentSchemas,
152+
schemas: {
153+
Animal: {
154+
oneOf: [{ $ref: '#/components/schemas/Dog' }, { $ref: '#/components/schemas/Cat' }],
155+
discriminator: {
156+
propertyName: 'type',
157+
},
158+
},
159+
},
160+
},
161+
errors: [
162+
{
163+
code: 'xgen-IPA-125-oneOf-must-have-discriminator',
164+
message: 'Discriminator must have a mapping object.',
98165
path: ['schemas', 'Animal'],
99166
severity: DiagnosticSeverity.Error,
100167
},

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

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ import { resolveObject } from './utils/componentUtils.js';
33
import { hasException } from './utils/exceptions.js';
44

55
const RULE_NAME = 'xgen-IPA-125-oneOf-must-have-discriminator';
6-
const ERROR_MESSAGE = 'Each oneOf property must include a discriminator property to define the exact type.';
6+
const GENERIC_ERROR_MESSAGE = 'Each oneOf property must include a discriminator property to define the exact type.';
7+
const MISSING_DISCRIMINATOR_MESSAGE = 'The schema has oneOf but no discriminator property.';
8+
const INVALID_DISCRIMINATOR_MESSAGE = 'Discriminator property is not an object.';
9+
const MISSING_PROPERTY_NAME_MESSAGE = 'Discriminator has no propertyName defined.';
10+
const MISSING_MAPPING_MESSAGE = 'Discriminator must have a mapping object.';
711
const MAPPING_ERROR_MESSAGE =
812
'The discriminator mapping must match the oneOf references. Unmatched Discriminator mappings with oneOf references:';
913

@@ -26,13 +30,21 @@ export default (input, _, { path, documentInventory }) => {
2630
return;
2731
}
2832

29-
// Validate the presence of a discriminator
30-
if (!schema.discriminator || typeof schema.discriminator !== 'object' || !schema.discriminator.propertyName) {
31-
return collectAndReturnViolation(path, RULE_NAME, [{ message: ERROR_MESSAGE }]);
33+
// Validate the presence of a discriminator with more specific error messages
34+
if (!schema.discriminator) {
35+
return collectAndReturnViolation(path, RULE_NAME, [{ message: MISSING_DISCRIMINATOR_MESSAGE }]);
36+
}
37+
38+
if (typeof schema.discriminator !== 'object') {
39+
return collectAndReturnViolation(path, RULE_NAME, [{ message: INVALID_DISCRIMINATOR_MESSAGE }]);
40+
}
41+
42+
if (!schema.discriminator.propertyName) {
43+
return collectAndReturnViolation(path, RULE_NAME, [{ message: MISSING_PROPERTY_NAME_MESSAGE }]);
3244
}
3345

3446
if (!schema.discriminator.mapping) {
35-
return collectAndReturnViolation(path, RULE_NAME, [{ message: ERROR_MESSAGE }]);
47+
return collectAndReturnViolation(path, RULE_NAME, [{ message: MISSING_MAPPING_MESSAGE }]);
3648
}
3749

3850
const oneOfRefs = schema.oneOf.map((item) => item.$ref);

0 commit comments

Comments
 (0)