Skip to content

Commit 593f55f

Browse files
authored
Merge pull request #951 from postmanlabs/feature/custom-server-url-fix
using custom server urls for collection generation
2 parents 7fa75bf + b72cceb commit 593f55f

2 files changed

Lines changed: 60 additions & 4 deletions

File tree

libV2/CollectionGeneration/schemaUtils.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const generateAuthForCollectionFromOpenAPI = require('./helpers/collection/generateAuthForCollectionFromOpenAPI.js');
22
const utils = require('./utils.js');
3+
const { Url } = require('postman-collection/lib/collection/url');
34

45
const schemaFaker = require('../../assets/json-schema-faker.js'),
56
_ = require('lodash'),
@@ -231,7 +232,7 @@ let QUERYPARAM = 'query',
231232
collectionVariables = [];
232233

233234
if (!serverObj) {
234-
return { collectionVariables, pathVariables, baseUrl };
235+
return { collectionVariables, pathVariables, baseUrl, serverObj };
235236
}
236237

237238
baseUrl = sanitizeUrl(serverObj.url);
@@ -244,7 +245,7 @@ let QUERYPARAM = 'query',
244245

245246
({ collectionVariables, pathVariables } = filterCollectionAndPathVariables(baseUrl, serverVariables));
246247

247-
return { collectionVariables, pathVariables, baseUrl };
248+
return { collectionVariables, pathVariables, baseUrl, serverObj };
248249
},
249250

250251
/**
@@ -2822,7 +2823,9 @@ module.exports = {
28222823
responseTypes
28232824
} = resolveResponseForPostmanRequest(context, operationItem[method], request);
28242825

2825-
requestIdentifier = method + path;
2826+
const overridesServer = Boolean(baseUrlData.serverObj);
2827+
2828+
requestIdentifier = overridesServer ? method + new Url(url).getPath(true) : method + path;
28262829
Object.assign(requestTypesObject,
28272830
{ [requestIdentifier]: { request: requestTypes, response: responseTypes } });
28282831

test/unit/convertV2WithTypes.test.js

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,9 @@ describe('convertV2WithTypes', function() {
456456

457457
it('should resolve extractedTypes into correct schema structure', function(done) {
458458
const expectedExtractedTypes = {
459-
'get/pets': {
459+
// `GET /pets` overrides the server URL with `http://petstore3.swagger.io/{v3}`, so its
460+
// resolved request path (and therefore its type-data key) carries the `:v3` server segment.
461+
'get/:v3/pets': {
460462
'request': {
461463
'headers': '[\n {\n "keyName": "variable",\n "properties": {\n "type": "array"\n }\n }\n]',
462464
'pathParam': '[]',
@@ -539,6 +541,57 @@ describe('convertV2WithTypes', function() {
539541
);
540542
});
541543

544+
it('should key extractedTypes by the resolved request path when an operation overrides the server URL with path segments', function(done) {
545+
// An operation-level server URL with path segments (e.g. `/eslsvc/api/v3`) gets resolved
546+
// directly into the request URL, while a top-level server is surfaced via the `{{baseUrl}}`
547+
// host. The extracted-type identifier must mirror the request's resolved path (Url#getPath) in
548+
// both cases so consumers can map the types back to the generated requests.
549+
const openapi = {
550+
openapi: '3.0.0',
551+
info: { title: 'Operation level servers', version: '1.0.0' },
552+
servers: [{ url: 'https://top.example.com/v1' }],
553+
paths: {
554+
'/profile-preferences': {
555+
get: {
556+
servers: [{ url: 'https://apiintqa.hmhs.com/eslsvc/api/v3' }],
557+
responses: {
558+
200: {
559+
description: 'ok',
560+
content: { 'application/json': { schema: { type: 'object', properties: { a: { type: 'string' } } } } }
561+
}
562+
}
563+
}
564+
},
565+
'/pets': {
566+
get: {
567+
responses: {
568+
200: {
569+
description: 'ok',
570+
content: { 'application/json': { schema: { type: 'object', properties: { id: { type: 'integer' } } } } }
571+
}
572+
}
573+
}
574+
}
575+
}
576+
},
577+
options = { folderStrategy: 'Paths', schemaFaker: true };
578+
579+
Converter.convertV2WithTypes({ type: 'json', data: openapi }, options, (err, conversionResult) => {
580+
expect(err).to.be.null;
581+
expect(conversionResult.extractedTypes).to.be.an('object').that.is.not.empty;
582+
583+
const typeKeys = Object.keys(conversionResult.extractedTypes);
584+
585+
// Operation-level server path segments are part of the key (matches the request's getPath).
586+
expect(typeKeys).to.include('get/eslsvc/api/v3/profile-preferences');
587+
// Top-level server stays behind {{baseUrl}}, so its key is just the spec path.
588+
expect(typeKeys).to.include('get/pets');
589+
expect(typeKeys).to.not.include('get/profile-preferences');
590+
591+
done();
592+
});
593+
});
594+
542595
describe('composite schema support (anyOf, oneOf, allOf)', function() {
543596
it('should extract anyOf schemas in request body', function(done) {
544597
const openApiWithAnyOf = {

0 commit comments

Comments
 (0)