diff --git a/packages/bruno-converters/src/postman/postman-to-bruno.js b/packages/bruno-converters/src/postman/postman-to-bruno.js index e9c4f421f..7eb64c4c5 100644 --- a/packages/bruno-converters/src/postman/postman-to-bruno.js +++ b/packages/bruno-converters/src/postman/postman-to-bruno.js @@ -43,6 +43,31 @@ const parseGraphQLRequest = (graphqlSource) => { } }; +/** + * Transforms Postman descriptions to handle both legacy and new formats. + * + * Postman changed their description format: + * - Legacy format: description was a simple string + * - New format: description is an object with 'content' and 'type' properties + * + * This function handles both formats to ensure backward compatibility. + */ +const transformDescription = (description) => { + if (!description) { + return ''; + } + + if (typeof description === 'string') { + return description; + } + + if (typeof description === 'object' && description.hasOwnProperty('content')) { + return description.content; + } + + return ''; +}; + const isItemAFolder = (item) => { return !item.request; }; @@ -290,7 +315,7 @@ const importPostmanV2CollectionItem = (brunoParent, item, { useWorkers = false } items: [], seq: index + 1, root: { - docs: i.description || '', + docs: transformDescription(i.description), meta: { name: folderName }, @@ -379,7 +404,7 @@ const importPostmanV2CollectionItem = (brunoParent, item, { useWorkers = false } formUrlEncoded: [], multipartForm: [] }, - docs: i.request.description || '' + docs: transformDescription(i.request.description) } }; @@ -461,7 +486,7 @@ const importPostmanV2CollectionItem = (brunoParent, item, { useWorkers = false } type: type, name: param.key, value: value, - description: param.description, + description: transformDescription(param.description), enabled: !param.disabled }); }); @@ -474,7 +499,7 @@ const importPostmanV2CollectionItem = (brunoParent, item, { useWorkers = false } uid: uuid(), name: param.key, value: param.value, - description: param.description, + description: transformDescription(param.description), enabled: !param.disabled }); }); @@ -509,7 +534,7 @@ const importPostmanV2CollectionItem = (brunoParent, item, { useWorkers = false } uid: uuid(), name: header.key, value: header.value, - description: header.description, + description: transformDescription(header.description), enabled: !header.disabled }); }); @@ -522,7 +547,7 @@ const importPostmanV2CollectionItem = (brunoParent, item, { useWorkers = false } uid: uuid(), name: param.key, value: param.value, - description: param.description, + description: transformDescription(param.description), type: 'query', enabled: !param.disabled }); @@ -538,7 +563,7 @@ const importPostmanV2CollectionItem = (brunoParent, item, { useWorkers = false } uid: uuid(), name: param.key, value: param.value ?? '', - description: param.description ?? '', + description: transformDescription(param.description), type: 'path', enabled: true }); @@ -573,7 +598,7 @@ const importPostmanV2Collection = async (collection, { useWorkers = false }) => items: [], environments: [], root: { - docs: collection.info.description || '', + docs: transformDescription(collection.info.description), meta: { name: collection.info.name || 'Untitled Collection' }, diff --git a/packages/bruno-converters/tests/postman/postman-to-bruno/transform-description.spec.js b/packages/bruno-converters/tests/postman/postman-to-bruno/transform-description.spec.js new file mode 100644 index 000000000..d47a92163 --- /dev/null +++ b/packages/bruno-converters/tests/postman/postman-to-bruno/transform-description.spec.js @@ -0,0 +1,364 @@ +import { describe, it, expect } from '@jest/globals'; +import postmanToBruno from '../../../src/postman/postman-to-bruno'; + +describe('transformDescription function', () => { + it('should handle null and undefined descriptions', async () => { + const collection = { + info: { + name: 'Test Collection', + schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json', + description: null + }, + item: [] + }; + + const brunoCollection = await postmanToBruno(collection); + expect(brunoCollection.root.docs).toBe(''); + }); + + it('should handle string descriptions (legacy format)', async () => { + const collection = { + info: { + name: 'Test Collection', + schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json', + description: 'This is a string description' + }, + item: [] + }; + + const brunoCollection = await postmanToBruno(collection); + expect(brunoCollection.root.docs).toBe('This is a string description'); + }); + + it('should handle object descriptions with content property (new Postman format)', async () => { + const collection = { + info: { + name: 'Test Collection', + schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json', + description: { + content: 'This is the content from the new Postman format', + type: 'text/plain' + } + }, + item: [] + }; + + const brunoCollection = await postmanToBruno(collection); + expect(brunoCollection.root.docs).toBe('This is the content from the new Postman format'); + }); + + it('should handle object descriptions without content property', async () => { + const collection = { + info: { + name: 'Test Collection', + schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json', + description: { + type: 'text/plain' + } + }, + item: [] + }; + + const brunoCollection = await postmanToBruno(collection); + expect(brunoCollection.root.docs).toBe(''); + }); + + it('should handle request descriptions with new format', async () => { + const collection = { + info: { + name: 'Test Collection', + schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json' + }, + item: [ + { + name: 'Test Request', + request: { + method: 'GET', + url: 'https://api.example.com/test', + description: { + content: 'This is a request description in new format', + type: 'text/plain' + } + } + } + ] + }; + + const brunoCollection = await postmanToBruno(collection); + expect(brunoCollection.items[0].request.docs).toBe('This is a request description in new format'); + }); + + it('should handle folder descriptions with new format', async () => { + const collection = { + info: { + name: 'Test Collection', + schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json' + }, + item: [ + { + name: 'Test Folder', + description: { + content: 'This is a folder description in new format', + type: 'text/plain' + }, + item: [] + } + ] + }; + + const brunoCollection = await postmanToBruno(collection); + expect(brunoCollection.items[0].root.docs).toBe('This is a folder description in new format'); + }); + + it('should handle header descriptions with new format', async () => { + const collection = { + info: { + name: 'Test Collection', + schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json' + }, + item: [ + { + name: 'Test Request', + request: { + method: 'GET', + url: 'https://api.example.com/test', + header: [ + { + key: 'Authorization', + value: 'Bearer token', + description: { + content: 'Authorization header description', + type: 'text/plain' + } + } + ] + } + } + ] + }; + + const brunoCollection = await postmanToBruno(collection); + expect(brunoCollection.items[0].request.headers[0].description).toBe('Authorization header description'); + }); + + it('should handle query parameter descriptions with new format', async () => { + const collection = { + info: { + name: 'Test Collection', + schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json' + }, + item: [ + { + name: 'Test Request', + request: { + method: 'GET', + url: { + raw: 'https://api.example.com/test?param=value', + host: ['api', 'example', 'com'], + path: ['test'], + query: [ + { + key: 'param', + value: 'value', + description: { + content: 'Query parameter description', + type: 'text/plain' + } + } + ] + } + } + } + ] + }; + + const brunoCollection = await postmanToBruno(collection); + expect(brunoCollection.items[0].request.params[0].description).toBe('Query parameter description'); + }); + + it('should handle path variable descriptions with new format', async () => { + const collection = { + info: { + name: 'Test Collection', + schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json' + }, + item: [ + { + name: 'Test Request', + request: { + method: 'GET', + url: { + raw: 'https://api.example.com/users/:id', + host: ['api', 'example', 'com'], + path: ['users', ':id'], + variable: [ + { + key: 'id', + value: '123', + description: { + content: 'User ID path variable', + type: 'text/plain' + } + } + ] + } + } + } + ] + }; + + const brunoCollection = await postmanToBruno(collection); + expect(brunoCollection.items[0].request.params[0].description).toBe('User ID path variable'); + }); + + it('should handle form data descriptions with new format', async () => { + const collection = { + info: { + name: 'Test Collection', + schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json' + }, + item: [ + { + name: 'Test Request', + request: { + method: 'POST', + url: 'https://api.example.com/test', + body: { + mode: 'formdata', + formdata: [ + { + key: 'field1', + value: 'value1', + description: { + content: 'Form field description', + type: 'text/plain' + } + } + ] + } + } + } + ] + }; + + const brunoCollection = await postmanToBruno(collection); + expect(brunoCollection.items[0].request.body.multipartForm[0].description).toBe('Form field description'); + }); + + it('should handle urlencoded form descriptions with new format', async () => { + const collection = { + info: { + name: 'Test Collection', + schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json' + }, + item: [ + { + name: 'Test Request', + request: { + method: 'POST', + url: 'https://api.example.com/test', + body: { + mode: 'urlencoded', + urlencoded: [ + { + key: 'field1', + value: 'value1', + description: { + content: 'URL encoded field description', + type: 'text/plain' + } + } + ] + } + } + } + ] + }; + + const brunoCollection = await postmanToBruno(collection); + expect(brunoCollection.items[0].request.body.formUrlEncoded[0].description).toBe('URL encoded field description'); + }); + + it('should handle mixed description formats in the same collection', async () => { + const collection = { + info: { + name: 'Test Collection', + schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json', + description: 'Collection with string description' + }, + item: [ + { + name: 'Test Folder', + description: { + content: 'Folder with object description', + type: 'text/plain' + }, + item: [ + { + name: 'Test Request', + request: { + method: 'GET', + url: 'https://api.example.com/test', + description: 'Request with string description', + header: [ + { + key: 'Content-Type', + value: 'application/json', + description: { + content: 'Header with object description', + type: 'text/plain' + } + } + ] + } + } + ] + } + ] + }; + + const brunoCollection = await postmanToBruno(collection); + + // Collection description (string) + expect(brunoCollection.root.docs).toBe('Collection with string description'); + + // Folder description (object) + expect(brunoCollection.items[0].root.docs).toBe('Folder with object description'); + + // Request description (string) + expect(brunoCollection.items[0].items[0].request.docs).toBe('Request with string description'); + + // Header description (object) + expect(brunoCollection.items[0].items[0].request.headers[0].description).toBe('Header with object description'); + }); + + it('should handle edge cases like empty strings and special characters', async () => { + const collection = { + info: { + name: 'Test Collection', + schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json', + description: { + content: '', + type: 'text/plain' + } + }, + item: [ + { + name: 'Test Request', + request: { + method: 'GET', + url: 'https://api.example.com/test', + description: { + content: 'Description with special chars: !@#$%^&*()', + type: 'text/plain' + } + } + } + ] + }; + + const brunoCollection = await postmanToBruno(collection); + expect(brunoCollection.root.docs).toBe(''); + expect(brunoCollection.items[0].request.docs).toBe('Description with special chars: !@#$%^&*()'); + }); +});