Skip to content

Commit 89f35d8

Browse files
authored
Merge pull request #656 from postmanlabs/fix/sw2ConsumesProdcuesWildcard
prevent use of */* to end in an empty response
2 parents 01654f0 + 13a3268 commit 89f35d8

File tree

3 files changed

+178
-21
lines changed

3 files changed

+178
-21
lines changed

lib/schemaUtils.js

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ const { formatDataPath, checkIsCorrectType, isKnownType } = require('./common/sc
101101
{ compareVersion } = require('./common/versionUtils.js'),
102102
parse = require('./parse'),
103103
{ getBundleContentAndComponents, parseFileOrThrow } = require('./bundle.js'),
104-
MULTI_FILE_API_TYPE_ALLOWED_VALUE = 'multiFile';
104+
MULTI_FILE_API_TYPE_ALLOWED_VALUE = 'multiFile',
105+
MEDIA_TYPE_ALL_RANGES = '*/*';
105106
/* eslint-enable */
106107

107108
// See https://github.com/json-schema-faker/json-schema-faker/tree/master/docs#available-options
@@ -1377,7 +1378,8 @@ module.exports = {
13771378
convertToPmResponseBody: function(contentObj, components, options, schemaCache) {
13781379
options = _.merge({}, defaultOptions, options);
13791380

1380-
var responseBody, cTypeHeader, hasComputedType, cTypes;
1381+
var responseBody, cTypeHeader, hasComputedType, cTypes,
1382+
isJsonLike = false;
13811383
if (!contentObj) {
13821384
return {
13831385
contentTypeHeader: null,
@@ -1418,12 +1420,24 @@ module.exports = {
14181420
responseBody = JSON.stringify(responseBody, null, options.indentCharacter);
14191421
}
14201422
else if (typeof responseBody !== 'string') {
1421-
// since the collection v2 schema only supports body being a string
1422-
responseBody = '';
1423+
if (cTypeHeader === MEDIA_TYPE_ALL_RANGES) {
1424+
if (!_.isObject(responseBody) && _.isFunction(_.get(responseBody, 'toString'))) {
1425+
responseBody = responseBody.toString();
1426+
}
1427+
else {
1428+
responseBody = JSON.stringify(responseBody, null, options.indentCharacter);
1429+
isJsonLike = true;
1430+
}
1431+
}
1432+
else {
1433+
responseBody = '';
1434+
}
14231435
}
1436+
14241437
return {
14251438
contentTypeHeader: cTypeHeader,
1426-
responseBody: responseBody
1439+
responseBody: responseBody,
1440+
isJsonLike
14271441
};
14281442
},
14291443

@@ -2157,7 +2171,34 @@ module.exports = {
21572171
});
21582172

21592173
responseBodyWrapper = this.convertToPmResponseBody(response.content, components, options, schemaCache);
2174+
previewLanguage = this.resolveResponsePreviewLanguageAndResponseHeader(responseBodyWrapper,
2175+
responseHeaders, response);
2176+
// replace 'X' char with '0'
2177+
code = code.replace(/X|x/g, '0');
2178+
code = code === 'default' ? 500 : _.toSafeInteger(code);
2179+
2180+
sdkResponse = new sdk.Response({
2181+
name: response.description,
2182+
code: code || 500,
2183+
header: responseHeaders,
2184+
body: responseBodyWrapper.responseBody,
2185+
originalRequest: originalRequest
2186+
});
2187+
sdkResponse._postman_previewlanguage = previewLanguage;
2188+
2189+
return sdkResponse;
2190+
},
21602191

2192+
/**
2193+
* Identifies the previewLanguage to use and also adds the identified content header to the responseHeaders array
2194+
* @param {object} responseBodyWrapper generated response body and its related information
2195+
* @param {object} responseHeaders - The existent array of response headers
2196+
* @param {object} response in operationItem responses
2197+
* @returns {string} previewLanguage
2198+
*/
2199+
resolveResponsePreviewLanguageAndResponseHeader: function (responseBodyWrapper,
2200+
responseHeaders, response) {
2201+
let previewLanguage = 'text';
21612202
if (responseBodyWrapper.contentTypeHeader) {
21622203
// we could infer the content-type header from the body
21632204
responseHeaders.push({ key: 'Content-Type', value: responseBodyWrapper.contentTypeHeader });
@@ -2167,6 +2208,9 @@ module.exports = {
21672208
else if (this.getHeaderFamily(responseBodyWrapper.contentTypeHeader) === HEADER_TYPE.XML) {
21682209
previewLanguage = PREVIEW_LANGUAGE.XML;
21692210
}
2211+
else if (responseBodyWrapper.isJsonLike) {
2212+
previewLanguage = PREVIEW_LANGUAGE.JSON;
2213+
}
21702214
}
21712215
else if (response.content && Object.keys(response.content).length > 0) {
21722216
responseHeaders.push({ key: 'Content-Type', value: Object.keys(response.content)[0] });
@@ -2176,24 +2220,14 @@ module.exports = {
21762220
else if (this.getHeaderFamily(Object.keys(response.content)[0]) === HEADER_TYPE.XML) {
21772221
previewLanguage = PREVIEW_LANGUAGE.XML;
21782222
}
2223+
else if (responseBodyWrapper.isJsonLike) {
2224+
previewLanguage = PREVIEW_LANGUAGE.JSON;
2225+
}
21792226
}
21802227
else {
21812228
responseHeaders.push({ key: 'Content-Type', value: TEXT_PLAIN });
21822229
}
2183-
// replace 'X' char with '0'
2184-
code = code.replace(/X/g, '0');
2185-
code = code === 'default' ? 500 : _.toSafeInteger(code);
2186-
2187-
sdkResponse = new sdk.Response({
2188-
name: response.description,
2189-
code: code || 500,
2190-
header: responseHeaders,
2191-
body: responseBodyWrapper.responseBody,
2192-
originalRequest: originalRequest
2193-
});
2194-
sdkResponse._postman_previewlanguage = previewLanguage;
2195-
2196-
return sdkResponse;
2230+
return previewLanguage;
21972231
},
21982232

21992233
/**
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
{
2+
"swagger": "2.0",
3+
"info": {
4+
"description": "This API provides access to signature platform \n\nWorkflow:\n\nDepending on the needs of the client, the order and use of the calls to the API may differ.<br>\nHere is an example of a very basic workflow:\n1) Create Request - Provides the information that will be used for the signer's certificate.\n2) Create Signature Request - Provides the information for the creation of the visible signature. Also provides the document(s) to be signed.\n3) Launch Signature Request - Launches the signature process based on the two previous requests.\n4) Get Signature Request Status - Returns the current status of the signature request and, if the status is \"SIGNED\", provides the signed document.\nA list of all requests is provided below, however the order is not necessarily correct for the signature process.\n\nWe suggest that the client begins with this basic workflow and expands based on their specific needs.",
5+
"version": "1.11.2",
6+
"title": "Signature api"
7+
},
8+
"host": "sign-sandbox.certeurope.fr",
9+
"basePath": "/",
10+
"tags": [{
11+
"name": "Signature",
12+
"description": "Centralize Signing API"
13+
}],
14+
"paths": {
15+
"/centralize/admin/orders/{raProfileId}": {
16+
"post": {
17+
"tags": ["Signature"],
18+
"summary": "createAdminCentralizedOrder",
19+
"operationId": "createAdminCentralizedOrderUsingPOST",
20+
"consumes": ["application/json"],
21+
"produces": ["*/*"],
22+
"parameters": [{
23+
"name": "raProfileId",
24+
"in": "path",
25+
"description": "raProfileId",
26+
"required": true,
27+
"type": "integer",
28+
"format": "int64"
29+
}, {
30+
"in": "body",
31+
"name": "request",
32+
"description": "request",
33+
"required": true,
34+
"schema": {
35+
"$ref": "#/definitions/CentralizedOrderRequestDTO"
36+
}
37+
}],
38+
"responses": {
39+
"200": {
40+
"description": "OK",
41+
"schema": {
42+
"$ref": "#/definitions/AliveOKDTO"
43+
}
44+
}
45+
}
46+
}
47+
}
48+
},
49+
"definitions": {
50+
"AliveOKDTO": {
51+
"type": "object",
52+
"properties": {
53+
"archiver": {
54+
"type": "boolean"
55+
},
56+
"kms": {
57+
"type": "boolean"
58+
},
59+
"ok": {
60+
"type": "boolean"
61+
},
62+
"ts": {
63+
"type": "boolean"
64+
}
65+
},
66+
"title": "AliveOKDTO"
67+
},
68+
"CentralizedOrderRequestDTO": {
69+
"type": "object",
70+
"properties": {
71+
"aeFolderId": {
72+
"type": "string"
73+
},
74+
"clientIdentifier": {
75+
"type": "string"
76+
},
77+
"enableEmail": {
78+
"type": "boolean"
79+
},
80+
"enableOtp": {
81+
"type": "boolean"
82+
},
83+
"enablePin": {
84+
"type": "boolean"
85+
},
86+
"enableSharing": {
87+
"type": "boolean"
88+
},
89+
"externalOrderRequestId": {
90+
"type": "string"
91+
},
92+
"otpContact": {
93+
"type": "string"
94+
},
95+
"signatureMode": {
96+
"type": "string",
97+
"enum": ["SOFTWARE", "HARDWARE"]
98+
}
99+
},
100+
"title": "CentralizedOrderRequestDTO"
101+
}
102+
}
103+
}

test/unit/x20schemapack.test.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ describe('getMetaData method', function() {
4848
});
4949

5050
describe('Convert method', function() {
51-
it('Should convert an example file from: ', function(done) {
51+
it('Should convert an example file from: sampleswagger.json', function(done) {
5252
const fileSource = path.join(__dirname, SWAGGER_20_FOLDER_JSON, 'sampleswagger.json'),
5353
fileData = fs.readFileSync(fileSource, 'utf8'),
5454
input = {
@@ -60,8 +60,28 @@ describe('Convert method', function() {
6060
schemapack.convert((error, result) => {
6161
expect(error).to.be.null;
6262
expect(result.result).to.be.true;
63+
done();
64+
});
65+
});
66+
67+
it('Should convert an example file from: rangeMediaType.json', function(done) {
68+
const fileSource = path.join(__dirname, SWAGGER_20_FOLDER_JSON, 'rangeMediaType.json'),
69+
fileData = fs.readFileSync(fileSource, 'utf8'),
70+
input = {
71+
type: 'string',
72+
data: fileData
73+
},
74+
schemapack = new SchemaPack(input);
75+
76+
schemapack.convert((error, result) => {
77+
expect(error).to.be.null;
78+
expect(result.output[0].data.item[0].response[0]._postman_previewlanguage).to.equal('json');
79+
expect(result.output[0].data.item[0].response[0].body).to.not.be.empty;
80+
expect(result.output[0].data.item[0].response[0].header.find((header) => {
81+
return header.key === 'Content-Type';
82+
}).value).to.equal('*/*');
83+
done();
6384
});
64-
done();
6585
});
6686

6787
it('Should convert and exclude deprecated operations - has only one op and is deprecated', function() {

0 commit comments

Comments
 (0)