Skip to content

Commit beb2f7f

Browse files
committed
Improved example value for requestParameterResolution and exampleParameterResolution option to fallback to faked value instead of schema
1 parent 2c42272 commit beb2f7f

File tree

4 files changed

+46
-32
lines changed

4 files changed

+46
-32
lines changed

lib/deref.js

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,14 @@ module.exports = {
5555
* @param {*} components components in openapi spec.
5656
* @param {object} schemaResolutionCache stores already resolved references
5757
* @param {*} resolveFor - resolve refs for validation/conversion (value to be one of VALIDATION/CONVERSION)
58+
* @param {string} resolveTo The desired JSON-generation mechanism (schema: prefer using the JSONschema to
59+
generate a fake object, example: use specified examples as-is). Default: schema
5860
* @param {*} stack counter which keeps a tab on nested schemas
5961
* @param {*} seenRef References that are repeated. Used to identify circular references.
6062
* @returns {*} schema - schema that adheres to all individual schemas in schemaArr
6163
*/
6264
resolveAllOf: function (schemaArr, parameterSourceOption, components, schemaResolutionCache,
63-
resolveFor = 'CONVERSION', stack = 0, seenRef) {
65+
resolveFor = 'CONVERSION', resolveTo = 'schema', stack = 0, seenRef) {
6466

6567
if (!(schemaArr instanceof Array)) {
6668
return null;
@@ -69,13 +71,13 @@ module.exports = {
6971
if (schemaArr.length === 1) {
7072
// for just one entry in allOf, don't need to enforce type: object restriction
7173
return this.resolveRefs(schemaArr[0], parameterSourceOption, components, schemaResolutionCache, resolveFor,
72-
stack, seenRef);
74+
resolveTo, stack, seenRef);
7375
}
7476

7577
// generate one object for each schema
7678
let indivObjects = schemaArr.map((schema) => {
7779
return this.resolveRefs(schema, parameterSourceOption, components, schemaResolutionCache, resolveFor,
78-
stack, seenRef);
80+
resolveTo, stack, seenRef);
7981
}).filter((schema) => {
8082
return schema.type === 'object';
8183
}),
@@ -113,13 +115,15 @@ module.exports = {
113115
* @param {*} components components in openapi spec.
114116
* @param {object} schemaResolutionCache stores already resolved references
115117
* @param {*} resolveFor - resolve refs for validation/conversion (value to be one of VALIDATION/CONVERSION)
118+
* @param {string} resolveTo The desired JSON-generation mechanism (schema: prefer using the JSONschema to
119+
generate a fake object, example: use specified examples as-is). Default: schema
116120
* @param {*} stack counter which keeps a tab on nested schemas
117121
* @param {*} seenRef - References that are repeated. Used to identify circular references.
118122
* @returns {*} schema satisfying JSON-schema-faker.
119123
*/
120124

121125
resolveRefs: function (schema, parameterSourceOption, components, schemaResolutionCache,
122-
resolveFor = 'CONVERSION', stack = 0, seenRef = {}) {
126+
resolveFor = 'CONVERSION', resolveTo = 'schema', stack = 0, seenRef = {}) {
123127
var resolvedSchema, prop, splitRef,
124128
ERR_TOO_MANY_LEVELS = '<Error: Too many levels of nesting to fake this schema>';
125129

@@ -136,15 +140,15 @@ module.exports = {
136140

137141
if (schema.anyOf) {
138142
return this.resolveRefs(schema.anyOf[0], parameterSourceOption, components, schemaResolutionCache, resolveFor,
139-
stack, _.cloneDeep(seenRef));
143+
resolveTo, stack, _.cloneDeep(seenRef));
140144
}
141145
if (schema.oneOf) {
142146
return this.resolveRefs(schema.oneOf[0], parameterSourceOption, components, schemaResolutionCache, resolveFor,
143-
stack, _.cloneDeep(seenRef));
147+
resolveTo, stack, _.cloneDeep(seenRef));
144148
}
145149
if (schema.allOf) {
146150
return this.resolveAllOf(schema.allOf, parameterSourceOption, components, schemaResolutionCache, resolveFor,
147-
stack, _.cloneDeep(seenRef));
151+
resolveTo, stack, _.cloneDeep(seenRef));
148152
}
149153
if (schema.$ref && _.isFunction(schema.$ref.split)) {
150154
let refKey = schema.$ref;
@@ -186,7 +190,7 @@ module.exports = {
186190

187191
if (resolvedSchema) {
188192
let refResolvedSchema = this.resolveRefs(resolvedSchema, parameterSourceOption,
189-
components, schemaResolutionCache, resolveFor, stack, _.cloneDeep(seenRef));
193+
components, schemaResolutionCache, resolveFor, resolveTo, stack, _.cloneDeep(seenRef));
190194

191195
if (refResolvedSchema && refResolvedSchema.value !== ERR_TOO_MANY_LEVELS) {
192196
schemaResolutionCache[refKey] = refResolvedSchema;
@@ -221,17 +225,19 @@ module.exports = {
221225
continue;
222226
}
223227
/* eslint-enable */
224-
tempSchema.properties[prop] = this.resolveRefs(property,
225-
parameterSourceOption, components, schemaResolutionCache, resolveFor, stack, _.cloneDeep(seenRef));
228+
tempSchema.properties[prop] = this.resolveRefs(property, parameterSourceOption, components,
229+
schemaResolutionCache, resolveFor, resolveTo, stack, _.cloneDeep(seenRef));
226230
}
227231
}
228232
return tempSchema;
229233
}
230234

231235
schema.type = 'string';
232236

233-
// Don't override default value to schema for validation
234-
resolveFor !== 'VALIDATION' && (schema.default = '<object>');
237+
// Override deefault value to appropriate type representation for parameter resolution to schema
238+
if (resolveFor === 'CONVERSION' && resolveTo === 'schema') {
239+
schema.default = '<object>';
240+
}
235241
}
236242
else if (schema.type === 'array' && schema.items) {
237243
/*
@@ -260,13 +266,13 @@ module.exports = {
260266
// without this, schemas with circular references aren't faked correctly
261267
let tempSchema = _.omit(schema, 'items');
262268
tempSchema.items = this.resolveRefs(schema.items, parameterSourceOption,
263-
components, schemaResolutionCache, resolveFor, stack, _.cloneDeep(seenRef));
269+
components, schemaResolutionCache, resolveFor, resolveTo, stack, _.cloneDeep(seenRef));
264270
return tempSchema;
265271
}
266272
else if (!schema.hasOwnProperty('default')) {
267273
if (schema.hasOwnProperty('type')) {
268274
// Don't override default value to schema for validation
269-
if (resolveFor === 'CONVERSION') {
275+
if (resolveFor === 'CONVERSION' && resolveTo === 'schema') {
270276
if (!schema.hasOwnProperty('format')) {
271277
schema.default = '<' + schema.type + '>';
272278
}

lib/schemaUtils.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ function safeSchemaFaker(oldSchema, resolveTo, resolveFor, parameterSourceOption
129129
schemaFakerCache = _.get(schemaCache, 'schemaFakerCache', {});
130130

131131
resolvedSchema = deref.resolveRefs(oldSchema, parameterSourceOption, components, schemaResolutionCache,
132-
resolveFor);
132+
resolveFor, resolveTo);
133133
key = JSON.stringify(resolvedSchema);
134134

135135
if (resolveTo === 'schema') {
@@ -773,12 +773,13 @@ module.exports = {
773773
else {
774774
_.forEach(commonPathVars, (variable) => {
775775
let description = this.getParameterDescription(variable);
776+
776777
variables.push({
777778
key: variable.name,
778779
// we only fake the schema for param-level pathVars
779780
value: options.schemaFaker ?
780-
safeSchemaFaker(variable.schema || {}, 'schema', PROCESSING_TYPE.CONVERSION, PARAMETER_SOURCE.REQUEST,
781-
components, SCHEMA_FORMATS.DEFAULT, options.indentCharacter, schemaCache) : '',
781+
safeSchemaFaker(variable.schema || {}, options.requestParametersResolution, PROCESSING_TYPE.CONVERSION,
782+
PARAMETER_SOURCE.REQUEST, components, SCHEMA_FORMATS.DEFAULT, options.indentCharacter, schemaCache) : '',
782783
description: description
783784
});
784785
});
@@ -2239,7 +2240,7 @@ module.exports = {
22392240

22402241
// This is dereferenced schema (converted to JSON schema for validation)
22412242
schema = deref.resolveRefs(openApiSchemaObj, parameterSourceOption, components,
2242-
schemaCache.schemaResolutionCache, PROCESSING_TYPE.VALIDATION);
2243+
schemaCache.schemaResolutionCache, PROCESSING_TYPE.VALIDATION, resolveTo);
22432244

22442245
if (needJsonMatching) {
22452246
try {

test/unit/base.test.js

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,9 @@ describe('CONVERT FUNCTION TESTS ', function() {
243243
});
244244
it('Should respects readOnly and writeOnly properties in requestBody or response schema' +
245245
readOnlySpec, function(done) {
246-
var openapi = fs.readFileSync(readOnlySpec, 'utf8');
247-
Converter.convert({ type: 'string', data: openapi }, { schemaFaker: true }, (err, conversionResult) => {
246+
var openapi = fs.readFileSync(readOnlySpec, 'utf8'),
247+
options = { schemaFaker: true, exampleParametersResolution: 'schema' };
248+
Converter.convert({ type: 'string', data: openapi }, options, (err, conversionResult) => {
248249
let requestBody = conversionResult.output[0].data.item[0].item[1].request.body.raw,
249250
responseBody = conversionResult.output[0].data.item[0].item[0].response[0].body;
250251
expect(err).to.be.null;
@@ -311,17 +312,21 @@ describe('CONVERT FUNCTION TESTS ', function() {
311312
done();
312313
});
313314
});
314-
it('Should fallback to schema if the example is not present in the spec and the option is set to example' +
315+
it('Should fallback to faked value if the example is not present in the spec and the option is set to example' +
315316
schemaWithoutExampleSpec, function(done) {
316317
Converter.convert({ type: 'file', data: schemaWithoutExampleSpec },
317318
{ schemaFaker: true, requestParametersResolution: 'example', exampleParametersResolution: 'example' },
318319
(err, conversionResult) => {
319-
let rootRequest = conversionResult.output[0].data.item[0].request,
320-
exampleRequest = conversionResult.output[0].data.item[0].response[0].originalRequest;
321-
expect(exampleRequest.body.raw).to
322-
.equal('{\n "a": "<string>",\n "b": "<string>"\n}');
323-
expect(rootRequest.body.raw).to
324-
.equal('{\n "a": "<string>",\n "b": "<string>"\n}');
320+
let rootRequestBody = JSON.parse(conversionResult.output[0].data.item[0].request.body.raw),
321+
exampleRequestBody = JSON.parse(conversionResult.output[0].data.item[0]
322+
.response[0].originalRequest.body.raw);
323+
324+
expect(rootRequestBody).to.have.all.keys(['a', 'b']);
325+
expect(rootRequestBody.a).to.be.a('string');
326+
expect(rootRequestBody.b).to.be.a('string');
327+
expect(exampleRequestBody).to.have.all.keys(['a', 'b']);
328+
expect(exampleRequestBody.a).to.be.a('string');
329+
expect(exampleRequestBody.b).to.be.a('string');
325330
done();
326331
});
327332
});
@@ -693,10 +698,12 @@ describe('CONVERT FUNCTION TESTS ', function() {
693698
describe('[Github #57] - folderStrategy option (value: Tags) ' + tagsFolderSpec, function() {
694699
async.series({
695700
pathsOutput: (cb) => {
696-
Converter.convert({ type: 'file', data: tagsFolderSpec }, { folderStrategy: 'Paths' }, cb);
701+
Converter.convert({ type: 'file', data: tagsFolderSpec },
702+
{ folderStrategy: 'Paths', exampleParametersResolution: 'schema' }, cb);
697703
},
698704
tagsOutput: (cb) => {
699-
Converter.convert({ type: 'file', data: tagsFolderSpec }, { folderStrategy: 'Tags' }, cb);
705+
Converter.convert({ type: 'file', data: tagsFolderSpec },
706+
{ folderStrategy: 'Tags', exampleParametersResolution: 'schema' }, cb);
700707
}
701708
}, (err, res) => {
702709
var collectionItems,

test/unit/util.test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ describe('SCHEMA UTILITY FUNCTION TESTS ', function () {
163163
parameterSource = 'REQUEST',
164164
resolveTo = 'schema',
165165
resolveFor = 'CONVERSION',
166-
resolvedSchema = deref.resolveRefs(schema, parameterSource, { components }, {}, resolveFor),
166+
resolvedSchema = deref.resolveRefs(schema, parameterSource, { components }, {}, resolveFor, resolveTo),
167167
schemaCache = {
168168
schemaFakerCache: {},
169169
schemaResolutionCache: {}
@@ -205,7 +205,7 @@ describe('SCHEMA UTILITY FUNCTION TESTS ', function () {
205205
schemaResolutionCache: {}
206206
},
207207
resolvedSchema = deref.resolveRefs(schema, parameterSource, { components }, schemaCache.schemaResolutionCache,
208-
resolveFor),
208+
resolveFor, resolveTo),
209209
key = hash('resolveToExample ' + JSON.stringify(resolvedSchema)),
210210
fakedSchema = SchemaUtils.safeSchemaFaker(schema, resolveTo, resolveFor, parameterSource,
211211
{ components }, 'default', ' ', schemaCache);
@@ -640,7 +640,7 @@ describe('SCHEMA UTILITY FUNCTION TESTS ', function () {
640640
expect(retVal).to.be.an('array');
641641
expect(retVal[0].key).to.equal('varName');
642642
expect(retVal[0].description).to.equal('varDesc');
643-
expect(retVal[0].value).to.equal('<integer>');
643+
expect(retVal[0].value).to.be.a('number');
644644
});
645645
});
646646

0 commit comments

Comments
 (0)