diff --git a/packages/bruno-electron/src/ipc/network/prepare-request.js b/packages/bruno-electron/src/ipc/network/prepare-request.js index 74cb85ac6e..92183fb0ca 100644 --- a/packages/bruno-electron/src/ipc/network/prepare-request.js +++ b/packages/bruno-electron/src/ipc/network/prepare-request.js @@ -5,6 +5,7 @@ const FormData = require('form-data'); const fs = require('fs'); const path = require('path'); const { getTreePathFromCollectionToItem } = require('../../utils/collection'); +const { buildFormUrlEncodedPayload } = require('../../utils/common'); const mergeFolderLevelHeaders = (request, requestTreePath) => { let folderHeaders = new Map(); @@ -298,7 +299,7 @@ const prepareRequest = (item, collection) => { let contentTypeDefined = false; let url = request.url; - // collection headers + // Collection level headers each(get(collectionRoot, 'request.headers', []), (h) => { if (h.enabled && h.name.length > 0) { headers[h.name] = h.value; @@ -317,6 +318,7 @@ const prepareRequest = (item, collection) => { mergeFolderLevelVars(request, requestTreePath); } + // Request level headers each(request.headers, (h) => { if (h.enabled && h.name.length > 0) { headers[h.name] = h.value; @@ -370,11 +372,11 @@ const prepareRequest = (item, collection) => { } if (request.body.mode === 'formUrlEncoded') { - axiosRequest.headers['content-type'] = 'application/x-www-form-urlencoded'; - const params = {}; + if (!contentTypeDefined) { + axiosRequest.headers['content-type'] = 'application/x-www-form-urlencoded'; + } const enabledParams = filter(request.body.formUrlEncoded, (p) => p.enabled); - each(enabledParams, (p) => (params[p.name] = p.value)); - axiosRequest.data = params; + axiosRequest.data = buildFormUrlEncodedPayload(enabledParams); } if (request.body.mode === 'multipartForm') { diff --git a/packages/bruno-electron/src/utils/common.js b/packages/bruno-electron/src/utils/common.js index 50b17bb38d..1962ac260f 100644 --- a/packages/bruno-electron/src/utils/common.js +++ b/packages/bruno-electron/src/utils/common.js @@ -85,6 +85,24 @@ const flattenDataForDotNotation = (data) => { return result; }; +/** + * @param {Array.} params The request body Array + * @returns {object} Returns an obj with repeating key as a array of values + * {item: 2, item: 3, item1: 4} becomes {item: [2,3], item1: 4} + */ +const buildFormUrlEncodedPayload = (params) => { + return params.reduce((acc, p) => { + if (!acc[p.name]) { + acc[p.name] = p.value; + } else if (Array.isArray(acc[p.name])) { + acc[p.name].push(p.value); + } else { + acc[p.name] = [acc[p.name], p.value]; + } + return acc; + }, {}); +}; + module.exports = { uuid, stringifyJson, @@ -93,5 +111,6 @@ module.exports = { safeParseJSON, simpleHash, generateUidBasedOnHash, - flattenDataForDotNotation + flattenDataForDotNotation, + buildFormUrlEncodedPayload }; diff --git a/packages/bruno-electron/tests/network/prepare-request.spec.js b/packages/bruno-electron/tests/network/prepare-request.spec.js index 808a127d92..b61d42c50a 100644 --- a/packages/bruno-electron/tests/network/prepare-request.spec.js +++ b/packages/bruno-electron/tests/network/prepare-request.spec.js @@ -1,6 +1,7 @@ const { describe, it, expect } = require('@jest/globals'); const prepareRequest = require('../../src/ipc/network/prepare-request'); +const { buildFormUrlEncodedPayload } = require('../../src/utils/common'); describe('prepare-request: prepareRequest', () => { describe('Decomments request body', () => { @@ -17,5 +18,43 @@ describe('prepare-request: prepareRequest', () => { const result = prepareRequest({ request: { body } }, {}); expect(result.data).toEqual(expected); }); + + it('should handle single key-value pair', () => { + const requestObj = [{ name: 'item', value: 2 }]; + const expected = { item: 2 }; + const result = buildFormUrlEncodedPayload(requestObj); + expect(result).toEqual(expected); + }); + + it('should handle multiple key-value pairs with unique keys', () => { + const requestObj = [ + { name: 'item1', value: 2 }, + { name: 'item2', value: 3 } + ]; + const expected = { item1: 2, item2: 3 }; + const result = buildFormUrlEncodedPayload(requestObj); + expect(result).toEqual(expected); + }); + + it('should handle multiple key-value pairs with the same key', () => { + const requestObj = [ + { name: 'item', value: 2 }, + { name: 'item', value: 3 } + ]; + const expected = { item: [2, 3] }; + const result = buildFormUrlEncodedPayload(requestObj); + expect(result).toEqual(expected); + }); + + it('should handle mixed key-value pairs with unique and duplicate keys', () => { + const requestObj = [ + { name: 'item1', value: 2 }, + { name: 'item2', value: 3 }, + { name: 'item1', value: 4 } + ]; + const expected = { item1: [2, 4], item2: 3 }; + const result = buildFormUrlEncodedPayload(requestObj); + expect(result).toEqual(expected); + }); }); -}); +}); \ No newline at end of file