mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-15 11:51:30 +00:00
feat: add helper to ensure string conversion for non-string values in Postman to Bruno conversion (#7644)
* feat: add helper to ensure string conversion for non-string values in Postman to Bruno conversion - Introduced `ensureString` function to convert numeric and non-string values to strings, defaulting null/undefined to an empty string. - Updated request handling in `importPostmanV2CollectionItem` to utilize `ensureString` for headers, parameters, and body fields. - Added tests to verify correct conversion of numeric values to strings in headers, query parameters, and body fields. * test: add test for numeric value conversion in Postman to Bruno transformation - Implemented a new test case to verify that numeric values in example request and response fields are correctly converted to strings during the Postman to Bruno conversion process. - The test checks various components including request headers, query parameters, path parameters, and body fields to ensure proper string conversion. * test: add multipart form value test for numeric conversion in Postman to Bruno transformation - Added a new test case to verify that numeric values in multipart form data are correctly converted to strings during the Postman to Bruno conversion process. - The test checks the conversion of numeric values in the request body to ensure proper handling in the transformation.
This commit is contained in:
committed by
lohit-bruno
parent
3097f3aa76
commit
04fdd6f8a9
@@ -73,6 +73,18 @@ const isItemAFolder = (item) => {
|
||||
return !item.request;
|
||||
};
|
||||
|
||||
/**
|
||||
* Postman allows non-string values (e.g. numbers) in fields like header values,
|
||||
* query param values, etc. Bruno expects these to be strings.
|
||||
* This helper converts non-null values to strings, defaulting null/undefined to ''.
|
||||
*/
|
||||
const ensureString = (value) => {
|
||||
if (value == null) return '';
|
||||
if (typeof value === 'string') return value;
|
||||
if (typeof value === 'object') return JSON.stringify(value);
|
||||
return String(value);
|
||||
};
|
||||
|
||||
const convertV21Auth = (array) => {
|
||||
return array.reduce((accumulator, currentValue) => {
|
||||
accumulator[currentValue.key] = currentValue.value;
|
||||
@@ -470,12 +482,12 @@ const importPostmanV2CollectionItem = (brunoParent, item, { useWorkers = false }
|
||||
const isFile = param.type === 'file' || (param.type === 'default' && param.src);
|
||||
const value = isFile
|
||||
? (Array.isArray(param.src) ? param.src : param.src ? [param.src] : [])
|
||||
: (Array.isArray(param.value) ? param.value.join('') : param.value ?? '');
|
||||
: (Array.isArray(param.value) ? param.value.join('') : ensureString(param.value));
|
||||
|
||||
brunoRequestItem.request.body.multipartForm.push({
|
||||
uid: uuid(),
|
||||
type: isFile ? 'file' : 'text',
|
||||
name: param.key ?? '',
|
||||
name: ensureString(param.key),
|
||||
value,
|
||||
description: transformDescription(param.description),
|
||||
enabled: !param.disabled,
|
||||
@@ -490,8 +502,8 @@ const importPostmanV2CollectionItem = (brunoParent, item, { useWorkers = false }
|
||||
if (param.key == null && param.value == null) return;
|
||||
brunoRequestItem.request.body.formUrlEncoded.push({
|
||||
uid: uuid(),
|
||||
name: param.key ?? '',
|
||||
value: param.value ?? '',
|
||||
name: ensureString(param.key),
|
||||
value: ensureString(param.value),
|
||||
description: transformDescription(param.description),
|
||||
enabled: !param.disabled
|
||||
});
|
||||
@@ -526,8 +538,8 @@ const importPostmanV2CollectionItem = (brunoParent, item, { useWorkers = false }
|
||||
if (header.key == null && header.value == null) return;
|
||||
brunoRequestItem.request.headers.push({
|
||||
uid: uuid(),
|
||||
name: header.key ?? '',
|
||||
value: header.value ?? '',
|
||||
name: ensureString(header.key),
|
||||
value: ensureString(header.value),
|
||||
description: transformDescription(header.description),
|
||||
enabled: !header.disabled
|
||||
});
|
||||
@@ -542,8 +554,8 @@ const importPostmanV2CollectionItem = (brunoParent, item, { useWorkers = false }
|
||||
}
|
||||
brunoRequestItem.request.params.push({
|
||||
uid: uuid(),
|
||||
name: param.key ?? '',
|
||||
value: param.value ?? '',
|
||||
name: ensureString(param.key),
|
||||
value: ensureString(param.value),
|
||||
description: transformDescription(param.description),
|
||||
type: 'query',
|
||||
enabled: !param.disabled
|
||||
@@ -558,8 +570,8 @@ const importPostmanV2CollectionItem = (brunoParent, item, { useWorkers = false }
|
||||
|
||||
brunoRequestItem.request.params.push({
|
||||
uid: uuid(),
|
||||
name: param.key,
|
||||
value: param.value ?? '',
|
||||
name: ensureString(param.key),
|
||||
value: ensureString(param.value),
|
||||
description: transformDescription(param.description),
|
||||
type: 'path',
|
||||
enabled: true
|
||||
@@ -616,8 +628,8 @@ const importPostmanV2CollectionItem = (brunoParent, item, { useWorkers = false }
|
||||
if (header.key == null && header.value == null) return;
|
||||
example.request.headers.push({
|
||||
uid: uuid(),
|
||||
name: header.key ?? '',
|
||||
value: header.value ?? '',
|
||||
name: ensureString(header.key),
|
||||
value: ensureString(header.value),
|
||||
description: transformDescription(header.description),
|
||||
enabled: !header.disabled
|
||||
});
|
||||
@@ -632,8 +644,8 @@ const importPostmanV2CollectionItem = (brunoParent, item, { useWorkers = false }
|
||||
}
|
||||
example.request.params.push({
|
||||
uid: uuid(),
|
||||
name: param.key ?? '',
|
||||
value: param.value ?? '',
|
||||
name: ensureString(param.key),
|
||||
value: ensureString(param.value),
|
||||
description: transformDescription(param.description),
|
||||
type: 'query',
|
||||
enabled: !param.disabled
|
||||
@@ -646,8 +658,8 @@ const importPostmanV2CollectionItem = (brunoParent, item, { useWorkers = false }
|
||||
if (!param.key) return;
|
||||
example.request.params.push({
|
||||
uid: uuid(),
|
||||
name: param.key,
|
||||
value: param.value ?? '',
|
||||
name: ensureString(param.key),
|
||||
value: ensureString(param.value),
|
||||
description: transformDescription(param.description),
|
||||
type: 'path',
|
||||
enabled: true
|
||||
@@ -666,12 +678,12 @@ const importPostmanV2CollectionItem = (brunoParent, item, { useWorkers = false }
|
||||
const isFile = param.type === 'file' || (param.type === 'default' && param.src);
|
||||
const value = isFile
|
||||
? (Array.isArray(param.src) ? param.src : param.src ? [param.src] : [])
|
||||
: (Array.isArray(param.value) ? param.value.join('') : param.value ?? '');
|
||||
: (Array.isArray(param.value) ? param.value.join('') : ensureString(param.value));
|
||||
|
||||
example.request.body.multipartForm.push({
|
||||
uid: uuid(),
|
||||
type: isFile ? 'file' : 'text',
|
||||
name: param.key ?? '',
|
||||
name: ensureString(param.key),
|
||||
value,
|
||||
description: transformDescription(param.description),
|
||||
enabled: !param.disabled,
|
||||
@@ -686,8 +698,8 @@ const importPostmanV2CollectionItem = (brunoParent, item, { useWorkers = false }
|
||||
if (param.key == null && param.value == null) return;
|
||||
example.request.body.formUrlEncoded.push({
|
||||
uid: uuid(),
|
||||
name: param.key ?? '',
|
||||
value: param.value ?? '',
|
||||
name: ensureString(param.key),
|
||||
value: ensureString(param.value),
|
||||
description: transformDescription(param.description),
|
||||
enabled: !param.disabled
|
||||
});
|
||||
@@ -717,8 +729,8 @@ const importPostmanV2CollectionItem = (brunoParent, item, { useWorkers = false }
|
||||
if (header.key == null && header.value == null) return;
|
||||
example.response.headers.push({
|
||||
uid: uuid(),
|
||||
name: header.key ?? '',
|
||||
value: header.value ?? '',
|
||||
name: ensureString(header.key),
|
||||
value: ensureString(header.value),
|
||||
description: transformDescription(header.description),
|
||||
enabled: true
|
||||
});
|
||||
|
||||
@@ -769,6 +769,161 @@ describe('postman-collection', () => {
|
||||
expect(params[2].value).toBe('');
|
||||
expect(params[2].type).toBe('query');
|
||||
});
|
||||
|
||||
it('should convert numeric values to strings in headers, params, and body fields', async () => {
|
||||
const collectionWithNumericValues = {
|
||||
info: {
|
||||
_postman_id: 'test-numeric-values',
|
||||
name: 'collection with numeric values',
|
||||
schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json'
|
||||
},
|
||||
item: [
|
||||
{
|
||||
name: 'request with numeric values',
|
||||
request: {
|
||||
method: 'POST',
|
||||
header: [
|
||||
{ key: 'X-Account-Id', value: 0 },
|
||||
{ key: 'X-Retry-Count', value: 3 }
|
||||
],
|
||||
url: {
|
||||
raw: 'https://example.com/api/:accountId',
|
||||
protocol: 'https',
|
||||
host: ['example', 'com'],
|
||||
path: ['api', ':accountId'],
|
||||
query: [
|
||||
{ key: 'limit', value: 100 },
|
||||
{ key: 'offset', value: 0 }
|
||||
],
|
||||
variable: [
|
||||
{ key: 'accountId', value: 0 }
|
||||
]
|
||||
},
|
||||
body: {
|
||||
mode: 'urlencoded',
|
||||
urlencoded: [
|
||||
{ key: 'timeout', value: 5000 }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'request with numeric multipart form values',
|
||||
request: {
|
||||
method: 'POST',
|
||||
header: [],
|
||||
url: { raw: 'https://example.com/upload' },
|
||||
body: {
|
||||
mode: 'formdata',
|
||||
formdata: [
|
||||
{ key: 'retries', value: 3, type: 'text' },
|
||||
{ key: 'priority', value: 0, type: 'text' }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const brunoCollection = await postmanToBruno(collectionWithNumericValues);
|
||||
const item = brunoCollection.items[0];
|
||||
|
||||
// Headers should have string values
|
||||
expect(item.request.headers[0].value).toBe('0');
|
||||
expect(item.request.headers[1].value).toBe('3');
|
||||
|
||||
// Query params should have string values
|
||||
const queryParams = item.request.params.filter((p) => p.type === 'query');
|
||||
expect(queryParams[0].value).toBe('100');
|
||||
expect(queryParams[1].value).toBe('0');
|
||||
|
||||
// Path params should have string values
|
||||
const pathParams = item.request.params.filter((p) => p.type === 'path');
|
||||
expect(pathParams[0].value).toBe('0');
|
||||
|
||||
// Form URL-encoded should have string values
|
||||
expect(item.request.body.formUrlEncoded[0].value).toBe('5000');
|
||||
|
||||
// Multipart form should have string values
|
||||
const multipartItem = brunoCollection.items[1];
|
||||
expect(multipartItem.request.body.multipartForm[0].value).toBe('3');
|
||||
expect(multipartItem.request.body.multipartForm[1].value).toBe('0');
|
||||
});
|
||||
|
||||
it('should convert numeric values to strings in example request and response fields', async () => {
|
||||
const collectionWithNumericExamples = {
|
||||
info: {
|
||||
_postman_id: 'test-numeric-examples',
|
||||
name: 'collection with numeric example values',
|
||||
schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json'
|
||||
},
|
||||
item: [
|
||||
{
|
||||
name: 'request with numeric example',
|
||||
request: {
|
||||
method: 'GET',
|
||||
header: [],
|
||||
url: { raw: 'https://example.com/api' }
|
||||
},
|
||||
response: [
|
||||
{
|
||||
name: 'Example with numerics',
|
||||
originalRequest: {
|
||||
method: 'GET',
|
||||
header: [
|
||||
{ key: 'X-Account-Id', value: 42 }
|
||||
],
|
||||
url: {
|
||||
raw: 'https://example.com/api/:id?page=1',
|
||||
protocol: 'https',
|
||||
host: ['example', 'com'],
|
||||
path: ['api', ':id'],
|
||||
query: [
|
||||
{ key: 'page', value: 1 }
|
||||
],
|
||||
variable: [
|
||||
{ key: 'id', value: 99 }
|
||||
]
|
||||
},
|
||||
body: {
|
||||
mode: 'urlencoded',
|
||||
urlencoded: [
|
||||
{ key: 'retries', value: 3 }
|
||||
]
|
||||
}
|
||||
},
|
||||
status: 'OK',
|
||||
code: 200,
|
||||
header: [
|
||||
{ key: 'X-RateLimit-Remaining', value: 0 }
|
||||
],
|
||||
body: '{"ok": true}'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const brunoCollection = await postmanToBruno(collectionWithNumericExamples);
|
||||
const example = brunoCollection.items[0].examples[0];
|
||||
|
||||
// Example request headers
|
||||
expect(example.request.headers[0].value).toBe('42');
|
||||
|
||||
// Example request query params
|
||||
const queryParams = example.request.params.filter((p) => p.type === 'query');
|
||||
expect(queryParams[0].value).toBe('1');
|
||||
|
||||
// Example request path params
|
||||
const pathParams = example.request.params.filter((p) => p.type === 'path');
|
||||
expect(pathParams[0].value).toBe('99');
|
||||
|
||||
// Example request form URL-encoded
|
||||
expect(example.request.body.formUrlEncoded[0].value).toBe('3');
|
||||
|
||||
// Example response headers
|
||||
expect(example.response.headers[0].value).toBe('0');
|
||||
});
|
||||
});
|
||||
|
||||
// Simple Collection (postman)
|
||||
|
||||
Reference in New Issue
Block a user