From 0f541a1ab055ce104da9758ddbf1a77dcd839c70 Mon Sep 17 00:00:00 2001 From: Mahtis Michel Date: Thu, 7 Jan 2021 20:26:34 +0100 Subject: [PATCH] fix(sample-gen): first oneOf or anyOf should be combined with schema (#6775) * fix(sample-gen): oneOf and anyOf should be merge into schema when there was oneOf or anyOf defined it just used the first schema of it to generate the samples. Now, the first oneOf or anyOf is combined with the schema to generate samples. * test(sample-gen): oneOf and anyOf should be combined with schema --- src/core/plugins/samples/fn.js | 69 ++++++++++++++++++++++------ test/unit/core/plugins/samples/fn.js | 66 ++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 14 deletions(-) diff --git a/src/core/plugins/samples/fn.js b/src/core/plugins/samples/fn.js index 751b6166..03d0a462 100644 --- a/src/core/plugins/samples/fn.js +++ b/src/core/plugins/samples/fn.js @@ -48,12 +48,62 @@ const liftSampleHelper = (oldSchema, target) => { if(target.xml === undefined && oldSchema.xml !== undefined) { target.xml = oldSchema.xml } + if(target.type === undefined && oldSchema.type !== undefined) { + target.type = oldSchema.type + } return target } export const sampleFromSchemaGeneric = (schema, config={}, exampleOverride = undefined, respectXML = false) => { + schema = objectify(schema) + let usePlainValue = exampleOverride !== undefined || schema.example !== undefined || schema && schema.default !== undefined + // first check if there is the need of combining this schema with others required by allOf + const hasOneOf = !usePlainValue && schema && schema.oneOf && schema.oneOf.length > 0 + const hasAnyOf = !usePlainValue && schema && schema.anyOf && schema.anyOf.length > 0 + if(!usePlainValue && (hasOneOf || hasAnyOf)) { + const schemaToAdd = objectify(hasOneOf + ? schema.oneOf[0] + : schema.anyOf[0] + ) + liftSampleHelper(schemaToAdd, schema) + if(!schema.xml && schemaToAdd.xml) { + schema.xml = schemaToAdd.xml + } + if(schema.example !== undefined && schemaToAdd.example !== undefined) { + usePlainValue = true + } else if(schemaToAdd.properties) { + if(!schema.properties) { + schema.properties = {} + } + let props = objectify(schemaToAdd.properties) + for (let propName in props) { + if (!props.hasOwnProperty(propName)) { + continue + } + if ( props[propName] && props[propName].deprecated ) { + continue + } + if ( props[propName] && props[propName].readOnly && !config.includeReadOnly ) { + continue + } + if ( props[propName] && props[propName].writeOnly && !config.includeWriteOnly ) { + continue + } + if(!schema.properties[propName]) { + schema.properties[propName] = props[propName] + if(!schemaToAdd.required && Array.isArray(schemaToAdd.required) && schemaToAdd.required.indexOf(propName) !== -1) { + if(!schema.required) { + schema.required = [propName] + } else { + schema.required.push(propName) + } + } + } + } + } + } const _attr = {} - let { xml, type, example, properties, additionalProperties, items } = objectify(schema) + let { xml, type, example, properties, additionalProperties, items } = schema let { includeReadOnly, includeWriteOnly } = config xml = xml || {} let { name, prefix, namespace } = xml @@ -77,18 +127,6 @@ export const sampleFromSchemaGeneric = (schema, config={}, exampleOverride = und res[displayName] = [] } - const usePlainValue = exampleOverride !== undefined || example !== undefined || schema && schema.default !== undefined - - const hasOneOf = !usePlainValue && schema && schema.oneOf && schema.oneOf.length > 0 - const hasAnyOf = !usePlainValue && schema && schema.anyOf && schema.anyOf.length > 0 - if(!usePlainValue && (hasOneOf || hasAnyOf)) { - const someSchema = hasOneOf - ? schema.oneOf[0] - : schema.anyOf[0] - liftSampleHelper(schema, someSchema) - return sampleFromSchemaGeneric(someSchema, config, undefined, respectXML) - } - // try recover missing type if(schema && !type) { if(properties || additionalProperties) { @@ -105,6 +143,7 @@ export const sampleFromSchemaGeneric = (schema, config={}, exampleOverride = und let addPropertyToResult if(respectXML) { addPropertyToResult = (propName, overrideE = undefined) => { + if(schema) { // case it is an xml attribute props[propName].xml = props[propName].xml || {} @@ -139,8 +178,10 @@ export const sampleFromSchemaGeneric = (schema, config={}, exampleOverride = und } } } else { - addPropertyToResult = (propName, overrideE) => + addPropertyToResult = (propName, overrideE) => { + res[propName] = sampleFromSchemaGeneric(props[propName], config, overrideE, respectXML) + } } // check for plain value and if found use it to generate sample from it diff --git a/test/unit/core/plugins/samples/fn.js b/test/unit/core/plugins/samples/fn.js index ae95076b..0a766379 100644 --- a/test/unit/core/plugins/samples/fn.js +++ b/test/unit/core/plugins/samples/fn.js @@ -29,6 +29,72 @@ describe("sampleFromSchema", () => { expect(sampleFromSchema(definition, { includeReadOnly: false })).toEqual(expected) }) + it("combine first oneOf or anyOf with schema's definitions", function () { + let definition = { + type: "object", + anyOf: [ + { + type: "object", + properties: { + test2: { + type: "string", + example: "anyOf" + }, + test: { + type: "string", + example: "anyOf" + } + } + } + ], + properties: { + test: { + type: "string", + example: "schema" + } + } + } + + let expected = { + test: "schema", + test2: "anyOf" + } + + expect(sampleFromSchema(definition, { includeReadOnly: false })).toEqual(expected) + + definition = { + type: "object", + oneOf: [ + { + type: "object", + properties: { + test2: { + type: "string", + example: "oneOf" + }, + test: { + type: "string", + example: "oneOf" + } + } + } + ], + properties: { + test: { + type: "string", + example: "schema" + } + } + } + + expected = { + test: "schema", + test2: "oneOf" + } + + expect(sampleFromSchema(definition, { includeReadOnly: false })).toEqual(expected) + }) + it("returns object with no readonly fields for parameter", function () { let definition = { type: "object",