BRU-3246 fix - added a param check method replacing the param null check (#8157)

This commit is contained in:
Utkarsh
2026-06-16 15:30:04 +05:30
committed by GitHub
parent b73bf9d898
commit 07c7348666
6 changed files with 120 additions and 7 deletions

View File

@@ -12,6 +12,24 @@ const hasLength = (str) => {
return str.length > 0;
};
const hasResolvablePathParamValue = (pathParam) => {
if (!pathParam || pathParam.enabled === false) {
return false;
}
const { value } = pathParam;
if (value === null || value === undefined) {
return false;
}
if (typeof value === 'string' && !hasLength(value)) {
return false;
}
return true;
};
export const parsePathParams = (url) => {
let uri = url.slice();
@@ -124,7 +142,8 @@ export const interpolateUrlPathParams = (url, params, variables = {}, options =
if (segment.startsWith(':')) {
const name = segment.slice(1);
const pathParam = params.find((p) => p?.name === name && p?.type === 'path');
return pathParam ? substituteValue(pathParam.value) : segment;
return hasResolvablePathParamValue(pathParam) ? substituteValue(pathParam.value) : segment;
// return pathParam ? substituteValue(pathParam.value) : segment;
}
// for OData-style parameters (parameters inside parentheses)
@@ -147,7 +166,7 @@ export const interpolateUrlPathParams = (url, params, variables = {}, options =
if (!name) continue;
const pathParam = params.find((p) => p?.name === name && p?.type === 'path');
if (pathParam) {
if (hasResolvablePathParamValue(pathParam)) {
result = result.replace(':' + match[1], substituteValue(pathParam.value));
}
}

View File

@@ -412,6 +412,23 @@ describe('Url Utils - interpolateUrl, interpolateUrlPathParams', () => {
expect(result).toEqual(expectedUrl);
});
it('should keep colon path segments when the path param has no value', () => {
const url = 'https://httpbin.org/anything/:test-segment';
const params = [{ name: 'test-segment', type: 'path', enabled: true, value: '' }];
const result = interpolateUrlPathParams(url, params);
expect(result).toEqual('https://httpbin.org/anything/:test-segment');
});
it('should keep colon path segments when no path param is defined', () => {
const url = 'https://httpbin.org/anything/:analyze-text';
const result = interpolateUrlPathParams(url, []);
expect(result).toEqual('https://httpbin.org/anything/:analyze-text');
});
});
describe('Url Utils - interpolateUrlPathParams with { raw: true }', () => {

View File

@@ -2,6 +2,24 @@ const { interpolate } = require('@usebruno/common');
const { each, forOwn, cloneDeep, find } = require('lodash');
const { isFormData } = require('@usebruno/common').utils;
const hasResolvablePathParamValue = (pathParam) => {
if (!pathParam || pathParam.enabled === false) {
return false;
}
const { value } = pathParam;
if (value === null || value === undefined) {
return false;
}
if (typeof value === 'string' && value.trim() === '') {
return false;
}
return true;
};
const isBinaryRequestBody = (data) => Buffer.isBuffer(data) || typeof data?.pipe === 'function';
const getContentType = (headers = {}) => {
@@ -142,7 +160,7 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc
if (path.startsWith(':')) {
const paramName = path.slice(1);
const existingPathParam = request.pathParams.find((param) => param.name === paramName);
if (!existingPathParam) {
if (!hasResolvablePathParamValue(existingPathParam)) {
return '/' + path;
}
return '/' + existingPathParam.value;
@@ -163,7 +181,7 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc
name = name.replace(/^[('"`]+/, '');
if (name) {
const existingPathParam = request.pathParams.find((param) => param.name === name);
if (existingPathParam) {
if (hasResolvablePathParamValue(existingPathParam)) {
result = result.replace(':' + match[1], existingPathParam.value);
}
}

View File

@@ -2,6 +2,24 @@ const { interpolate } = require('@usebruno/common');
const { each, forOwn, cloneDeep } = require('lodash');
const { isFormData } = require('@usebruno/common').utils;
const hasResolvablePathParamValue = (pathParam) => {
if (!pathParam || pathParam.enabled === false) {
return false;
}
const { value } = pathParam;
if (value === null || value === undefined) {
return false;
}
if (typeof value === 'string' && value.trim() === '') {
return false;
}
return true;
};
const isBinaryRequestBody = (data) => Buffer.isBuffer(data) || typeof data?.pipe === 'function';
const getContentType = (headers = {}) => {
@@ -180,7 +198,7 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc
if (path.startsWith(':')) {
const paramName = path.slice(1);
const existingPathParam = request.pathParams.find((param) => param.name === paramName);
if (!existingPathParam) {
if (!hasResolvablePathParamValue(existingPathParam)) {
return '/' + path;
}
return '/' + existingPathParam.value;
@@ -201,7 +219,7 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc
name = name.replace(/^[('"`]+/, '');
if (name) {
const existingPathParam = request.pathParams.find((param) => param.name === name);
if (existingPathParam) {
if (hasResolvablePathParamValue(existingPathParam)) {
result = result.replace(':' + match[1], existingPathParam.value);
}
}

View File

@@ -181,6 +181,41 @@ describe('interpolate-vars: interpolateVars', () => {
const result = interpolateVars(request, null, null, null);
expect(result.url).toBe('http://example.com/Category(\'foobar\')/Item(1)/foobar/Tags(%22tag%20test%22)');
});
it('keeps colon path segments when the path param has no value', async () => {
const request = {
method: 'POST',
url: 'https://httpbin.org/anything/:test-segment',
pathParams: [
{
type: 'path',
name: 'test-segment',
value: ''
}
]
};
const result = interpolateVars(request, null, null, null);
expect(result.url).toBe('https://httpbin.org/anything/:test-segment');
});
it('keeps colon path segments when the path param is disabled', async () => {
const request = {
method: 'POST',
url: 'https://httpbin.org/anything/:test-segment',
pathParams: [
{
type: 'path',
name: 'test-segment',
value: 'replaced',
enabled: false
}
]
};
const result = interpolateVars(request, null, null, null);
expect(result.url).toBe('https://httpbin.org/anything/:test-segment');
});
});
describe('With process environment variables', () => {

View File

@@ -68,7 +68,13 @@ class BrunoRequest {
if (segment.startsWith(':')) {
const paramName = segment.slice(1);
const pathParam = this.req.pathParams.find((param) => param.name === paramName);
if (pathParam && pathParam.value) {
if (
pathParam
&& pathParam.enabled !== false
&& pathParam.value !== null
&& pathParam.value !== undefined
&& (typeof pathParam.value !== 'string' || pathParam.value.trim() !== '')
) {
return pathParam.value;
}
}