Skip to content

Commit 9ccd7f7

Browse files
authored
Merge pull request #24 from IBM/dont-flag-response-files
fix: dont error on schemas with type file for oas2 specs
2 parents 21af082 + ebbe1b5 commit 9ccd7f7

File tree

2 files changed

+173
-8
lines changed

2 files changed

+173
-8
lines changed

src/plugins/validation/2and3/semantic-validators/schema-ibm.js

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ module.exports.validate = function({ jsSpec, isOAS3 }, config) {
7979
});
8080

8181
schemas.forEach(({ schema, path }) => {
82-
let res = generateFormatErrors(schema, path, config);
82+
let res = generateFormatErrors(schema, path, config, isOAS3);
8383
errors.push(...res.error);
8484
warnings.push(...res.warning);
8585

@@ -104,7 +104,7 @@ module.exports.validate = function({ jsSpec, isOAS3 }, config) {
104104

105105
// Flag as an error any property that does not have a recognized "type" and "format" according to the
106106
// [Swagger 2.0 spec](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types)
107-
function generateFormatErrors(schema, contextPath, config) {
107+
function generateFormatErrors(schema, contextPath, config, isOAS3) {
108108
const result = {};
109109
result.error = [];
110110
result.warning = [];
@@ -125,7 +125,7 @@ function generateFormatErrors(schema, contextPath, config) {
125125
}
126126

127127
checkStatus = config.invalid_type_format_pair;
128-
if (checkStatus !== 'off' && !formatValid(schema)) {
128+
if (checkStatus !== 'off' && !formatValid(schema, contextPath, isOAS3)) {
129129
const path = contextPath.concat(['type']);
130130
const message = 'Property type+format is not well-defined.';
131131
result[checkStatus].push({ path, message });
@@ -134,7 +134,7 @@ function generateFormatErrors(schema, contextPath, config) {
134134
return result;
135135
}
136136

137-
function formatValid(property) {
137+
function formatValid(property, path, isOAS3) {
138138
if (property.$ref) {
139139
return true;
140140
}
@@ -169,6 +169,12 @@ function formatValid(property) {
169169
case 'array':
170170
valid = true;
171171
break;
172+
case 'file':
173+
// schemas of type file are allowed in swagger2 for responses and parameters
174+
// of type 'formData' - the violating parameters are caught by parameters-ibm
175+
// note: type file is only allowed for root schemas (not properties, etc.)
176+
valid = !isOAS3 && isRootSchema(path);
177+
break;
172178
default:
173179
valid = false;
174180
}
@@ -303,3 +309,17 @@ function checkEnumValues(schema, contextPath, config) {
303309

304310
return result;
305311
}
312+
313+
// NOTE: this function is Swagger 2 specific and would need to be adapted to be used with OAS
314+
function isRootSchema(path) {
315+
const current = path[path.length - 1];
316+
const parent = path[path.length - 2];
317+
318+
// `schema` can only exist in parameter or response objects
319+
// root schemas can also appear under a variable key in the `definitions` section
320+
// if it is the top level `definitions` section (rather than some property named "definitions"),
321+
// the path length will be 2
322+
return (
323+
current === 'schema' || (parent === 'definitions' && path.length === 2)
324+
);
325+
}

test/plugins/validation/2and3/schema-ibm.js

Lines changed: 149 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,105 @@ describe('validation plugin - semantic - schema-ibm - Swagger 2', () => {
159159
expect(res.warnings.length).toEqual(0);
160160
});
161161

162+
it('should non return an error for a response schema of type file', () => {
163+
const config = {
164+
schemas: {
165+
invalid_type_format_pair: 'error'
166+
}
167+
};
168+
169+
const spec = {
170+
paths: {
171+
'/pets': {
172+
get: {
173+
responses: {
174+
'200': {
175+
description: 'legal response',
176+
schema: {
177+
type: 'file'
178+
}
179+
}
180+
}
181+
}
182+
}
183+
}
184+
};
185+
186+
const res = validate({ jsSpec: spec }, config);
187+
expect(res.errors.length).toEqual(0);
188+
expect(res.warnings.length).toEqual(0);
189+
});
190+
191+
it('should non return an error for a definition with root type of file', () => {
192+
const config = {
193+
schemas: {
194+
invalid_type_format_pair: 'error'
195+
}
196+
};
197+
198+
const spec = {
199+
definitions: {
200+
SomeSchema: {
201+
type: 'file',
202+
description: 'file schema, used for parameter or response'
203+
}
204+
}
205+
};
206+
207+
const res = validate({ jsSpec: spec }, config);
208+
expect(res.errors.length).toEqual(0);
209+
expect(res.warnings.length).toEqual(0);
210+
});
211+
212+
it('should return an error for a response schema with non-root type file', () => {
213+
const config = {
214+
schemas: {
215+
invalid_type_format_pair: 'error'
216+
}
217+
};
218+
219+
const spec = {
220+
paths: {
221+
'/pets': {
222+
get: {
223+
responses: {
224+
'200': {
225+
description: 'legal response',
226+
schema: {
227+
properties: {
228+
this_is_bad: {
229+
type: 'file',
230+
description: 'non-root type of file is bad'
231+
}
232+
}
233+
}
234+
}
235+
}
236+
}
237+
}
238+
}
239+
};
240+
241+
const res = validate({ jsSpec: spec }, config);
242+
expect(res.errors.length).toEqual(1);
243+
expect(res.errors[0].path).toEqual([
244+
'paths',
245+
'/pets',
246+
'get',
247+
'responses',
248+
'200',
249+
'schema',
250+
'properties',
251+
'this_is_bad',
252+
'type'
253+
]);
254+
expect(res.errors[0].message).toEqual(
255+
'Property type+format is not well-defined.'
256+
);
257+
258+
expect(res.warnings.length).toEqual(0);
259+
});
260+
162261
it('should return a warning when a property name is not snake case', () => {
163262
const config = {
164263
schemas: {
@@ -574,7 +673,7 @@ describe('validation plugin - semantic - schema-ibm - OpenAPI 3', () => {
574673
}
575674
};
576675

577-
const res = validate({ jsSpec: spec }, config);
676+
const res = validate({ jsSpec: spec, isOAS3: true }, config);
578677
expect(res.errors.length).toEqual(1);
579678
expect(res.errors[0].path).toEqual([
580679
'components',
@@ -593,6 +692,52 @@ describe('validation plugin - semantic - schema-ibm - OpenAPI 3', () => {
593692
expect(res.warnings.length).toEqual(0);
594693
});
595694

695+
it('should return an error for a response schema of type file', () => {
696+
const config = {
697+
schemas: {
698+
invalid_type_format_pair: 'error'
699+
}
700+
};
701+
702+
const spec = {
703+
paths: {
704+
'/pets': {
705+
get: {
706+
responses: {
707+
'200': {
708+
content: {
709+
'application/json': {
710+
schema: {
711+
type: 'file'
712+
}
713+
}
714+
}
715+
}
716+
}
717+
}
718+
}
719+
}
720+
};
721+
722+
const res = validate({ jsSpec: spec, isOAS3: true }, config);
723+
expect(res.errors.length).toEqual(1);
724+
expect(res.errors[0].path).toEqual([
725+
'paths',
726+
'/pets',
727+
'get',
728+
'responses',
729+
'200',
730+
'content',
731+
'application/json',
732+
'schema',
733+
'type'
734+
]);
735+
expect(res.errors[0].message).toEqual(
736+
'Property type+format is not well-defined.'
737+
);
738+
expect(res.warnings.length).toEqual(0);
739+
});
740+
596741
it('should not validate an example when it contains the resemblence of a problem', () => {
597742
const config = {
598743
schemas: {
@@ -638,7 +783,7 @@ describe('validation plugin - semantic - schema-ibm - OpenAPI 3', () => {
638783
}
639784
};
640785

641-
const res = validate({ jsSpec: spec }, config);
786+
const res = validate({ jsSpec: spec, isOAS3: true }, config);
642787
expect(res.errors.length).toEqual(1);
643788
expect(res.errors[0].path).toEqual([
644789
'paths',
@@ -704,7 +849,7 @@ describe('validation plugin - semantic - schema-ibm - OpenAPI 3', () => {
704849
}
705850
};
706851

707-
const res = validate({ jsSpec: spec }, config);
852+
const res = validate({ jsSpec: spec, isOAS3: true }, config);
708853
expect(res.errors.length).toEqual(0);
709854
expect(res.warnings.length).toEqual(1);
710855
expect(res.warnings[0].path).toEqual([
@@ -750,7 +895,7 @@ describe('validation plugin - semantic - schema-ibm - OpenAPI 3', () => {
750895
}
751896
};
752897

753-
const res = validate({ jsSpec: spec }, config);
898+
const res = validate({ jsSpec: spec, isOAS3: true }, config);
754899
expect(res.errors.length).toEqual(0);
755900
expect(res.warnings.length).toEqual(1);
756901
expect(res.warnings[0].path).toEqual([

0 commit comments

Comments
 (0)