mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-28 23:24:05 +00:00
feat: add transformDescription function to handle various description formats in Postman collections (#5744)
- Implemented transformDescription to standardize handling of string and object descriptions. - Updated importPostmanV2CollectionItem to utilize transformDescription for folder, request, and parameter descriptions. - Added comprehensive tests for transformDescription covering edge cases and different formats.
This commit is contained in:
@@ -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'
|
||||
},
|
||||
|
||||
@@ -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: !@#$%^&*()');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user