Skip to content

Commit da61fd1

Browse files
authored
Merge pull request #732 from postmanlabs/feature/fix-empty-title-issue
Fixed issue where defintions with empty title were converted with empty collection name.
2 parents a9d2b9b + cd22257 commit da61fd1

File tree

8 files changed

+234
-11
lines changed

8 files changed

+234
-11
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Fixed
66

77
- Fixed the default value of auth in the generated request when it is not resolved.
8+
- Fixed issue where collection name was empty in cases where definition title was defined as empty string.
89

910
## [v4.13.0] - 2023-05-24
1011

lib/schemapack.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
'use strict';
22

3-
// This is the default collection name if one can't be inferred from the OpenAPI spec
4-
const COLLECTION_NAME = 'Imported from OpenAPI 3.0',
5-
{ getConcreteSchemaUtils } = require('./common/versionUtils.js'),
3+
const { getConcreteSchemaUtils } = require('./common/versionUtils.js'),
64
{ convertToOAS30IfSwagger } = require('./swaggerUtils/swaggerToOpenapi.js'),
75
BROWSER = 'browser',
86
Ajv = require('ajv'),
@@ -194,12 +192,14 @@ class SchemaPack {
194192
}
195193
// if the schema is validated, return the meta data as required.
196194
else if (this.validated) {
195+
let name = utils.getCollectionName(_.get(this.openapi, 'info.title'));
196+
197197
return cb(null, {
198198
result: true,
199-
name: _.get(this.openapi, 'info.title', COLLECTION_NAME),
199+
name: name,
200200
output: [{
201201
type: 'collection',
202-
name: _.get(this.openapi, 'info.title', COLLECTION_NAME)
202+
name: name
203203
}]
204204
});
205205
}
@@ -213,12 +213,14 @@ class SchemaPack {
213213
return cb(null, validationResult);
214214
}
215215

216+
let name = utils.getCollectionName(_.get(this.openapi, 'info.title'));
217+
216218
return cb(null, {
217219
result: true,
218-
name: _.get(this.openapi, 'info.title', COLLECTION_NAME),
220+
name: name,
219221
output: [{
220222
type: 'collection',
221-
name: _.get(this.openapi, 'info.title', COLLECTION_NAME)
223+
name: name
222224
}]
223225
});
224226
});
@@ -340,7 +342,7 @@ class SchemaPack {
340342
// All generated folders and requests will go inside this
341343
generatedStore.collection = new sdk.Collection({
342344
info: {
343-
name: _.isEmpty(_.get(openapi, 'info.title')) ? COLLECTION_NAME : _.get(openapi, 'info.title')
345+
name: utils.getCollectionName(_.get(openapi, 'info.title'))
344346
}
345347
});
346348

lib/utils.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
const _ = require('lodash');
1+
const _ = require('lodash'),
2+
3+
// This is the default collection name if one can't be inferred from the OpenAPI spec
4+
COLLECTION_NAME = 'Imported from OpenAPI';
25

36
// this will have non-OAS-related utils
47

@@ -142,5 +145,19 @@ module.exports = {
142145
res.push(segment);
143146
}
144147
return res.join('/');
148+
},
149+
150+
/**
151+
* Provides collection name to be used for generated collection
152+
*
153+
* @param {*} title - Definition title
154+
* @returns {String} - Collection name
155+
*/
156+
getCollectionName: function (title) {
157+
if (_.isEmpty(title) || !_.isString(title)) {
158+
return COLLECTION_NAME;
159+
}
160+
161+
return title;
145162
}
146163
};

libV2/helpers/collection/generateCollectionFromOpenAPI.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const _ = require('lodash'),
2+
utils = require('../../utils'),
23
generateAuthrForCollectionFromOpenAPI = require('./generateAuthForCollectionFromOpenAPI'),
3-
COLLECTION_NAME = 'Imported from OpenAPI 3.0',
44

55
/**
66
* Returns a description that's usable at the collection-level
@@ -96,7 +96,7 @@ module.exports = function ({ openapi }) {
9696
return {
9797
data: {
9898
info: {
99-
name: _.get(openapi, 'info.title', COLLECTION_NAME),
99+
name: utils.getCollectionName(_.get(openapi, 'info.title')),
100100
description: getCollectionDescription(openapi)
101101
},
102102
auth: generateAuthrForCollectionFromOpenAPI(openapi, openapi.security)

libV2/utils.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
const sdk = require('postman-collection'),
22
_ = require('lodash'),
3+
4+
// This is the default collection name if one can't be inferred from the OpenAPI spec
5+
COLLECTION_NAME = 'Imported from OpenAPI',
36
generatePmResponseObject = (response) => {
47
const requestItem = generateRequestItemObject({ // eslint-disable-line no-use-before-define
58
request: response.originalRequest
@@ -182,6 +185,20 @@ module.exports = {
182185
return _.isString(url) ? url.replace(/(\{[^\/\{\}]+\})/g, replacer) : '';
183186
},
184187

188+
/**
189+
* Provides collection name to be used for generated collection
190+
*
191+
* @param {*} title - Definition title
192+
* @returns {String} - Collection name
193+
*/
194+
getCollectionName: function (title) {
195+
if (_.isEmpty(title) || !_.isString(title)) {
196+
return COLLECTION_NAME;
197+
}
198+
199+
return title;
200+
},
201+
185202
generatePmResponseObject,
186203
generateRequestItemObject
187204
};
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
openapi: 3.0.0
2+
info:
3+
version: 1.0.0
4+
title: ''
5+
license:
6+
name: MIT
7+
servers:
8+
- url: http://petstore.swagger.io/v1
9+
paths:
10+
/pets:
11+
get:
12+
summary: List all pets
13+
operationId: listPets
14+
tags:
15+
- pets
16+
parameters:
17+
- name: limit
18+
in: query
19+
description: How many items to return at one time (max 100)
20+
required: false
21+
schema:
22+
type: integer
23+
format: int32
24+
- name: variable
25+
in: query
26+
description: random variable
27+
style: form
28+
explode: false
29+
schema:
30+
type: array
31+
items:
32+
type: string
33+
- name: variable2
34+
in: query
35+
description: another random variable
36+
style: spaceDelimited
37+
schema:
38+
type: array
39+
items:
40+
type: integer
41+
format: int64
42+
responses:
43+
'200':
44+
description: An paged array of pets
45+
headers:
46+
x-next:
47+
description: A link to the next page of responses
48+
schema:
49+
type: string
50+
content:
51+
application/json:
52+
schema:
53+
$ref: "https://postman-echo.com/get"
54+
default:
55+
description: unexpected error
56+
content:
57+
application/json:
58+
schema:
59+
$ref: "#/components/schemas/Error"
60+
post:
61+
summary: Create a pet
62+
operationId: createPets
63+
tags:
64+
- pets
65+
responses:
66+
'201':
67+
description: Null response
68+
default:
69+
description: unexpected error
70+
content:
71+
application/json:
72+
schema:
73+
$ref: "#/components/schemas/Error"
74+
/pets/{petId}:
75+
get:
76+
summary: Info for a specific pet
77+
operationId: showPetById
78+
tags:
79+
- pets
80+
parameters:
81+
- name: petId
82+
in: path
83+
required: true
84+
description: The id of the pet to retrieve
85+
schema:
86+
type: string
87+
responses:
88+
'200':
89+
description: Expected response to a valid request
90+
content:
91+
application/json:
92+
schema:
93+
$ref: "#/components/schemas/Pets"
94+
default:
95+
description: unexpected error
96+
content:
97+
application/json:
98+
schema:
99+
$ref: "#/components/schemas/Error"
100+
components:
101+
schemas:
102+
Pet:
103+
required:
104+
- id
105+
- name
106+
properties:
107+
id:
108+
type: integer
109+
format: int64
110+
name:
111+
type: string
112+
tag:
113+
type: string
114+
Pets:
115+
type: array
116+
items:
117+
$ref: "#/components/schemas/Pet"
118+
Error:
119+
required:
120+
- code
121+
- message
122+
properties:
123+
code:
124+
type: integer
125+
format: int32
126+
message:
127+
type: string

test/unit/base.test.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,27 @@ describe('CONVERT FUNCTION TESTS ', function() {
758758
});
759759
});
760760

761+
it('Should return validation result for an definition with empty title field', function(done) {
762+
var invalidNoInfo = path.join(__dirname, VALID_OPENAPI_PATH + '/empty-title.yaml'),
763+
openapi = fs.readFileSync(invalidNoInfo, 'utf8');
764+
Converter.getMetaData({ type: 'json', data: openapi }, (err, status) => {
765+
if (err) {
766+
expect.fail(null, null, err);
767+
}
768+
if (status.result) {
769+
expect(status.result).to.be.eq(true);
770+
expect(status.name).to.be.equal('Imported from OpenAPI');
771+
expect(status.output[0].name).to.be.equal('Imported from OpenAPI');
772+
expect(status.output[0].type).to.be.equal('collection');
773+
done();
774+
}
775+
else {
776+
expect.fail(null, null, status.reason);
777+
done();
778+
}
779+
});
780+
});
781+
761782
it('Should return error for more than one root files', function(done) {
762783
let folderPath = path.join(__dirname, '../data/multiFile_with_two_root'),
763784
array = [
@@ -2147,6 +2168,25 @@ describe('CONVERT FUNCTION TESTS ', function() {
21472168
done();
21482169
});
21492170
});
2171+
2172+
it('Should convert definition with empty title field correctly with default name', function(done) {
2173+
const fileData = fs.readFileSync(path.join(__dirname, VALID_OPENAPI_PATH, 'empty-title.yaml'), 'utf8'),
2174+
input = {
2175+
type: 'string',
2176+
data: fileData
2177+
};
2178+
2179+
Converter.convert(input, { }, (error, result) => {
2180+
expect(error).to.be.null;
2181+
expect(result.result).to.equal(true);
2182+
expect(result.output.length).to.equal(1);
2183+
expect(result.output[0].type).to.have.equal('collection');
2184+
expect(result.output[0].data).to.have.property('info');
2185+
expect(result.output[0].data.info.name).to.eql('Imported from OpenAPI');
2186+
expect(result.output[0].data).to.have.property('item');
2187+
done();
2188+
});
2189+
});
21502190
});
21512191

21522192
describe('requestNameSource option', function() {

test/unit/convertV2.test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2310,4 +2310,23 @@ describe('The convert v2 Function', function() {
23102310
done();
23112311
});
23122312
});
2313+
2314+
it('Should convert definition with empty title field correctly with default name', function(done) {
2315+
const fileData = fs.readFileSync(path.join(__dirname, VALID_OPENAPI_PATH, 'empty-title.yaml'), 'utf8'),
2316+
input = {
2317+
type: 'string',
2318+
data: fileData
2319+
};
2320+
2321+
Converter.convert(input, { }, (error, result) => {
2322+
expect(error).to.be.null;
2323+
expect(result.result).to.equal(true);
2324+
expect(result.output.length).to.equal(1);
2325+
expect(result.output[0].type).to.have.equal('collection');
2326+
expect(result.output[0].data).to.have.property('info');
2327+
expect(result.output[0].data.info.name).to.eql('Imported from OpenAPI');
2328+
expect(result.output[0].data).to.have.property('item');
2329+
done();
2330+
});
2331+
});
23132332
});

0 commit comments

Comments
 (0)