-
Notifications
You must be signed in to change notification settings - Fork 212
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[AB-290]-Extracting-type-information from OAS #834
Changes from 1 commit
cb4599a
aa645c1
b54b8fb
abaf386
d8d9367
7217383
5ec3f70
fdc0ca2
9b30f47
d226967
8ae2fa5
6cffffb
1063175
e7abec2
c4a9591
a8de5ff
6f30294
dc4a48a
415f186
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -739,49 +739,51 @@ let QUERYPARAM = 'query', | |
/** | ||
* Processes and resolves types from Nested JSON schema structure. | ||
* | ||
* @param {Object} resolvedSchema - The resolved JSON schema to process. | ||
* @param {Set<string>} [parentRequired=new Set()] - A set of parent-required property keys to inherit. | ||
* @param {Object} resolvedSchema - The resolved JSON schema to process for type extraction. | ||
* @returns {Object} The processed schema details. | ||
*/ | ||
processSchema = (resolvedSchema) => { | ||
if (resolvedSchema.type === 'object' && resolvedSchema.properties) { | ||
const schemaDetails = { | ||
type: resolvedSchema.type || 'unknown', | ||
type: resolvedSchema.type, | ||
properties: {}, | ||
required: [] | ||
}, | ||
requiredProperties = new Set(resolvedSchema.required || []); | ||
|
||
for (let [key, prop] of Object.entries(resolvedSchema.properties)) { | ||
for (let [propName, propValue] of Object.entries(resolvedSchema.properties)) { | ||
if (!propValue.type) { | ||
continue; | ||
} | ||
const propertyDetails = { | ||
type: prop.type || 'unknown', | ||
deprecated: prop.deprecated, | ||
enum: prop.enum || undefined, | ||
minLength: prop.minLength !== undefined ? prop.minLength : undefined, | ||
maxLength: prop.maxLength !== undefined ? prop.maxLength : undefined, | ||
minimum: prop.minimum !== undefined ? prop.minimum : undefined, | ||
maximum: prop.maximum !== undefined ? prop.maximum : undefined, | ||
pattern: prop.pattern || undefined, | ||
example: prop.example !== undefined ? prop.example : undefined, | ||
description: prop.description !== undefined ? prop.description : undefined, | ||
format: prop.format || undefined | ||
type: propValue.type, | ||
deprecated: propValue.deprecated, | ||
enum: propValue.enum || undefined, | ||
minLength: propValue.minLength, | ||
maxLength: propValue.maxLength, | ||
minimum: propValue.minimum, | ||
maximum: propValue.maximum, | ||
pattern: propValue.pattern, | ||
example: propValue.example, | ||
description: propValue.description, | ||
format: propValue.format | ||
}; | ||
|
||
if (requiredProperties.has(key)) { | ||
schemaDetails.required.push(key); | ||
if (requiredProperties.has(propName)) { | ||
schemaDetails.required.push(propName); | ||
} | ||
if (prop.properties) { | ||
let res = processSchema(prop); | ||
propertyDetails.properties = res.properties; | ||
if (res.required) { | ||
propertyDetails.required = res.required; | ||
if (propValue.properties) { | ||
let processedProperties = processSchema(propValue); | ||
propertyDetails.properties = processedProperties.properties; | ||
if (processedProperties.required) { | ||
propertyDetails.required = processedProperties.required; | ||
} | ||
} | ||
else if (prop.type === 'array' && prop.items) { | ||
propertyDetails.items = processSchema(prop.items); | ||
else if (propValue.type === 'array' && propValue.items) { | ||
propertyDetails.items = processSchema(propValue.items); | ||
} | ||
|
||
schemaDetails.properties[key] = propertyDetails; | ||
schemaDetails.properties[propName] = propertyDetails; | ||
} | ||
if (schemaDetails.required && schemaDetails.required.length === 0) { | ||
schemaDetails.required = undefined; | ||
|
@@ -790,15 +792,15 @@ let QUERYPARAM = 'query', | |
} | ||
else if (resolvedSchema.type === 'array' && resolvedSchema.items) { | ||
const arrayDetails = { | ||
type: resolvedSchema.type || 'unknown', | ||
type: resolvedSchema.type, | ||
items: processSchema(resolvedSchema.items) | ||
}; | ||
if (resolvedSchema.minItems !== undefined) { arrayDetails.minItems = resolvedSchema.minItems; } | ||
if (resolvedSchema.maxItems !== undefined) { arrayDetails.maxItems = resolvedSchema.maxItems; } | ||
return arrayDetails; | ||
} | ||
return { | ||
type: resolvedSchema.type || 'unknown' | ||
type: resolvedSchema.type | ||
}; | ||
}, | ||
|
||
|
@@ -820,6 +822,7 @@ let QUERYPARAM = 'query', | |
) => { | ||
// reset readOnly and writeOnly prop cache before resolving schema to make sure we have fresh cache | ||
resetReadWritePropCache(context); | ||
|
||
let resolvedSchema = _resolveSchema(context, schema, stack, resolveFor, seenRef); | ||
|
||
/** | ||
|
@@ -844,6 +847,7 @@ let QUERYPARAM = 'query', | |
_.unset(resolvedSchema, utils.getJsonPathArray(key)); | ||
}); | ||
} | ||
|
||
return resolvedSchema; | ||
}, | ||
|
||
|
@@ -1590,6 +1594,7 @@ let QUERYPARAM = 'query', | |
} | ||
}); | ||
} | ||
|
||
// This is to handle cases when the jsf throws errors on finding unsupported types/formats | ||
try { | ||
bodyData = fakeSchema(context, requestBodySchema, shouldGenerateFromExample); | ||
|
@@ -1603,11 +1608,12 @@ let QUERYPARAM = 'query', | |
bodyData = ''; | ||
} | ||
} | ||
|
||
} | ||
if (context.enableTypeFetching && requestBodySchema.type !== undefined && | ||
requestBodySchema.type !== 'unknown') { | ||
let properties = processSchema(requestBodySchema); | ||
resolvedSchemaTypes.push(properties); | ||
|
||
if (context.enableTypeFetching && requestBodySchema.type !== undefined) { | ||
const requestBodySchemaTypes = processSchema(requestBodySchema); | ||
resolvedSchemaTypes.push(requestBodySchemaTypes); | ||
} | ||
|
||
// Generate multiple examples when either request or response contains more than one example | ||
|
@@ -1639,13 +1645,16 @@ let QUERYPARAM = 'query', | |
if (_.isEmpty(matchedRequestBodyExamples)) { | ||
matchedRequestBodyExamples = requestBodyExamples; | ||
} | ||
|
||
const generatedBody = generateExamples( | ||
context, responseExamples, matchedRequestBodyExamples, requestBodySchema, isBodyTypeXML); | ||
|
||
return { | ||
generatedBody, | ||
resolvedSchemaType: resolvedSchemaTypes[0] | ||
}; | ||
} | ||
|
||
return { | ||
generatedBody: [{ [bodyKey]: bodyData }], | ||
resolvedSchemaType: resolvedSchemaTypes[0] | ||
|
@@ -1660,7 +1669,7 @@ let QUERYPARAM = 'query', | |
urlencoded: urlEncodedParams | ||
}, | ||
resolvedBody, | ||
result, | ||
resolvedBodyResult, | ||
resolvedSchemaTypeObject; | ||
|
||
if (_.isEmpty(requestBodyContent)) { | ||
|
@@ -1671,15 +1680,16 @@ let QUERYPARAM = 'query', | |
requestBodyContent.schema = resolveSchema(context, requestBodyContent.schema); | ||
} | ||
|
||
result = resolveBodyData(context, requestBodyContent.schema); | ||
resolvedBodyResult = resolveBodyData(context, requestBodyContent.schema); | ||
resolvedBody = | ||
result && Array.isArray(result.generatedBody) && result.generatedBody.length > 0 ? | ||
result.generatedBody[0] : | ||
undefined; | ||
resolvedSchemaTypeObject = | ||
result && result.resolvedSchemaType !== undefined ? | ||
result.resolvedSchemaType : | ||
|
||
resolvedBodyResult && Array.isArray(resolvedBodyResult.generatedBody) && | ||
resolvedBodyResult.generatedBody[0] ? | ||
resolvedBodyResult.generatedBody[0] : | ||
undefined; | ||
|
||
resolvedSchemaTypeObject = resolvedBodyResult && | ||
resolvedBodyResult.resolvedSchemaType ? resolvedBodyResult.resolvedSchemaType : undefined; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above |
||
resolvedBody && (bodyData = resolvedBody.request); | ||
|
||
const encoding = requestBodyContent.encoding || {}; | ||
|
@@ -1728,22 +1738,25 @@ let QUERYPARAM = 'query', | |
formdata: formDataParams | ||
}, | ||
resolvedBody, | ||
result, | ||
resolvedBodyResult, | ||
resolvedSchemaTypeObject; | ||
|
||
if (_.isEmpty(requestBodyContent)) { | ||
return requestBodyData; | ||
} | ||
|
||
result = resolveBodyData(context, requestBodyContent.schema); | ||
resolvedBodyResult = resolveBodyData(context, requestBodyContent.schema); | ||
resolvedBody = | ||
result && Array.isArray(result.generatedBody) && result.generatedBody.length > 0 ? | ||
result.generatedBody[0] : | ||
undefined; | ||
resolvedBodyResult && Array.isArray(resolvedBodyResult.generatedBody) && | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above comment, please take care of these in all the places where you have added such checks |
||
resolvedBodyResult.generatedBody[0] ? | ||
resolvedBodyResult.generatedBody[0] : | ||
undefined; | ||
|
||
resolvedSchemaTypeObject = | ||
result && result.resolvedSchemaType !== undefined ? | ||
resolvedBodyResult && resolvedBodyResult.resolvedSchemaType ? | ||
result.resolvedSchemaType : | ||
undefined; | ||
|
||
resolvedBody && (bodyData = resolvedBody.request); | ||
|
||
encoding = _.get(requestBodyContent, 'encoding', {}); | ||
|
@@ -1848,7 +1861,7 @@ let QUERYPARAM = 'query', | |
dataToBeReturned = {}, | ||
{ concreteUtils } = context, | ||
resolvedBody, | ||
result, | ||
resolvedBodyResult, | ||
resolvedSchemaTypeObject; | ||
|
||
headerFamily = getHeaderFamily(bodyType); | ||
|
@@ -1860,15 +1873,18 @@ let QUERYPARAM = 'query', | |
} | ||
// Handling for Raw mode data | ||
else { | ||
result = resolveBodyData(context, requestContent[bodyType], bodyType); | ||
resolvedBodyResult = resolveBodyData(context, requestContent[bodyType], bodyType); | ||
resolvedBody = | ||
result && Array.isArray(result.generatedBody) && result.generatedBody.length > 0 ? | ||
result.generatedBody[0] : | ||
undefined; | ||
resolvedBodyResult && Array.isArray(resolvedBodyResult.generatedBody) && | ||
resolvedBodyResult.generatedBody[0] ? | ||
resolvedBodyResult.generatedBody[0] : | ||
undefined; | ||
|
||
resolvedSchemaTypeObject = | ||
result && result.resolvedSchemaType !== undefined ? | ||
result.resolvedSchemaType : | ||
resolvedBodyResult && resolvedBodyResult.resolvedSchemaType ? | ||
resolvedBodyResult.resolvedSchemaType : | ||
undefined; | ||
|
||
resolvedBody && (bodyData = resolvedBody.request); | ||
|
||
if ((bodyType === TEXT_XML || bodyType === APP_XML || headerFamily === HEADER_TYPE.XML)) { | ||
|
@@ -2015,20 +2031,21 @@ let QUERYPARAM = 'query', | |
return reqParam; | ||
}, | ||
|
||
createProperties = (schema, param) => { | ||
createProperties = (param) => { | ||
const { schema } = param; | ||
return { | ||
type: schema.type || 'unknown', | ||
format: schema.format || undefined, | ||
default: schema.default !== undefined ? schema.default : undefined, | ||
type: schema.type, | ||
format: schema.format, | ||
default: schema.default, | ||
required: param.required || false, | ||
deprecated: param.deprecated || false, | ||
enum: schema.enum || undefined, | ||
minLength: schema.minLength !== undefined ? schema.minLength : undefined, | ||
maxLength: schema.maxLength !== undefined ? schema.maxLength : undefined, | ||
minimum: schema.minimum !== undefined ? schema.minimum : undefined, | ||
maximum: schema.maximum !== undefined ? schema.maximum : undefined, | ||
pattern: schema.pattern || undefined, | ||
example: schema.example !== undefined ? schema.example : undefined | ||
minLength: schema.minLength, | ||
maxLength: schema.maxLength, | ||
minimum: schema.minimum, | ||
maximum: schema.maximum, | ||
pattern: schema.pattern, | ||
example: schema.example | ||
}; | ||
}, | ||
|
||
|
@@ -2060,15 +2077,14 @@ let QUERYPARAM = 'query', | |
keyName, | ||
paramValue = resolveValueOfParameter(context, param); | ||
|
||
if (param && param.schema) { | ||
const { name, schema } = param; | ||
keyName = name; | ||
properties = createProperties(schema, param); | ||
if (param && param.name && param.schema && param.schema.type) { | ||
keyName = param.name; | ||
properties = createProperties(param); | ||
} | ||
|
||
queryParamTypeInfo = { keyName, properties }; | ||
if (keyName && param.schema && param.schema.type) { | ||
queryParamTypes.push(queryParamTypeInfo); | ||
} | ||
|
||
queryParamTypes.push(queryParamTypeInfo); | ||
|
||
if (typeof paramValue === 'number' || typeof paramValue === 'boolean') { | ||
// the SDK will keep the number-ness, | ||
|
@@ -2114,16 +2130,13 @@ let QUERYPARAM = 'query', | |
keyName, | ||
paramValue = resolveValueOfParameter(context, param); | ||
|
||
if (param && param.schema) { | ||
const { name, schema } = param; | ||
keyName = name; | ||
properties = createProperties(schema, param); | ||
if (param && param.name && param.schema && param.schema.type) { | ||
keyName = param.name; | ||
properties = createProperties(param); | ||
} | ||
|
||
pathParamTypeInfo = { keyName, properties }; | ||
barshan23 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (keyName && param.schema && param.schema.type) { | ||
pathParamTypes.push(pathParamTypeInfo); | ||
} | ||
pathParamTypes.push(pathParamTypeInfo); | ||
|
||
if (typeof paramValue === 'number' || typeof paramValue === 'boolean') { | ||
// the SDK will keep the number-ness, | ||
|
@@ -2202,10 +2215,10 @@ let QUERYPARAM = 'query', | |
paramValue = resolveValueOfParameter(context, param); | ||
|
||
if (param && param.name && param.schema && param.schema.type) { | ||
const { name, schema } = param; | ||
keyName = name; | ||
properties = createProperties(schema, param); | ||
keyName = param.name; | ||
properties = createProperties(param); | ||
} | ||
|
||
headerTypeInfo = { keyName, properties }; | ||
|
||
headerTypes.push(headerTypeInfo); | ||
|
@@ -2354,17 +2367,17 @@ let QUERYPARAM = 'query', | |
keyName = name; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. keyName variable is not needed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's remove this please ^ |
||
properties = { | ||
type: schema.type, | ||
format: schema.format || undefined, | ||
default: schema.default !== undefined ? schema.default : undefined, | ||
format: schema.format, | ||
default: schema.default, | ||
required: schema.required || false, | ||
deprecated: schema.deprecated || false, | ||
enum: schema.enum || undefined, | ||
minLength: schema.minLength !== undefined ? schema.minLength : undefined, | ||
maxLength: schema.maxLength !== undefined ? schema.maxLength : undefined, | ||
minimum: schema.minimum !== undefined ? schema.minimum : undefined, | ||
maximum: schema.maximum !== undefined ? schema.maximum : undefined, | ||
pattern: schema.pattern || undefined, | ||
example: schema.example !== undefined ? schema.example : undefined | ||
minLength: schema.minLength, | ||
maxLength: schema.maxLength, | ||
minimum: schema.minimum, | ||
maximum: schema.maximum, | ||
pattern: schema.pattern, | ||
example: schema.example | ||
}; | ||
|
||
} | ||
|
@@ -2516,7 +2529,6 @@ let QUERYPARAM = 'query', | |
{ resolvedHeaderTypes, headers } = resolveResponseHeaders(context, responseSchema.headers), | ||
responseBodyHeaderObj; | ||
resolvedExamplesObject = resolvedExamples[0] && resolvedExamples[0].resolvedResponseBodyTypes; | ||
barshan23 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// eslint-disable-next-line one-var | ||
responseBodyHeaderObj = | ||
{ | ||
body: JSON.stringify(resolvedExamplesObject, null, 2), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Q: Do we really need to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, we are not doing it again There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I meant what is the use of this stringify ? keeping it as JS object also works right ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, but i wanted to export the object in such a way that it can be used by collection0definition as it is. so stringified it. and changing it right now might be risky as all the tests would start to break. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's remove all these stringify calls since they aren't necessary when we're picking up the E2E test ticket. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://postmanlabs.atlassian.net/browse/AB-293?focusedCommentId=823082 -> Tracking it here |
||
|
Unchanged files with check annotations Beta
historyRequest = [], | ||
resultObj1; | ||
before(function (done) { | ||
Check warning on line 515 in test/unit/ValidateV2.test.js
|
||
getAllTransactions(JSON.parse(collection), historyRequest); | ||
schemaPack.validateTransactionV2(historyRequest, (err, result) => { | ||
expect(err).to.be.null; |
}); | ||
// Need to handle collaping of folders | ||
it.skip('Should generate collection with collapsing unnecessary folders ' + | ||
Check warning on line 324 in test/unit/convertV2.test.js
|
||
multipleFoldersSpec, function(done) { | ||
var openapi = fs.readFileSync(multipleFoldersSpec, 'utf8'); | ||
Converter.convertV2({ type: 'string', data: openapi }, {}, (err, conversionResult) => { | ||
done(); | ||
}); | ||
}); | ||
it.skip('Should collapse child and parent folder when parent has only one child' + | ||
Check warning on line 336 in test/unit/convertV2.test.js
|
||
multipleFoldersSpec1, function(done) { | ||
var openapi = fs.readFileSync(multipleFoldersSpec1, 'utf8'); | ||
Converter.convertV2({ type: 'string', data: openapi }, { schemaFaker: true }, (err, conversionResult) => { | ||
done(); | ||
}); | ||
}); | ||
it.skip('Should generate collection without creating folders and having only one request' + | ||
Check warning on line 350 in test/unit/convertV2.test.js
|
||
multipleFoldersSpec2, function(done) { | ||
var openapi = fs.readFileSync(multipleFoldersSpec2, 'utf8'); | ||
Converter.convertV2({ type: 'string', data: openapi }, { schemaFaker: true }, (err, conversionResult) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check needs to be simplified 😞
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was simplified based on your comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant we don't need the ternary operator here 🤦