mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-08 22:45:25 +00:00
375 lines
16 KiB
JavaScript
375 lines
16 KiB
JavaScript
import { splitOnFirst, parsePathParams, interpolateUrl, interpolateUrlPathParams } from './index';
|
|
|
|
describe('Url Utils - parsePathParams', () => {
|
|
it('should parse path - case 1', () => {
|
|
const params = parsePathParams('www.example.com');
|
|
expect(params).toEqual([]);
|
|
});
|
|
|
|
it('should parse path - case 2', () => {
|
|
const params = parsePathParams('http://www.example.com');
|
|
expect(params).toEqual([]);
|
|
});
|
|
|
|
it('should parse path - case 3', () => {
|
|
const params = parsePathParams('https://www.example.com');
|
|
expect(params).toEqual([]);
|
|
});
|
|
|
|
it('should parse path - case 4', () => {
|
|
const params = parsePathParams('https://www.example.com/users/:id');
|
|
expect(params).toEqual([{ name: 'id', value: '' }]);
|
|
});
|
|
|
|
it('should parse path - case 5', () => {
|
|
const params = parsePathParams('https://www.example.com/users/:id/');
|
|
expect(params).toEqual([{ name: 'id', value: '' }]);
|
|
});
|
|
|
|
it('should parse path - case 6', () => {
|
|
const params = parsePathParams('https://www.example.com/users/:id/:');
|
|
expect(params).toEqual([{ name: 'id', value: '' }]);
|
|
});
|
|
|
|
it('should parse path - case 7', () => {
|
|
const params = parsePathParams('https://www.example.com/users/:id/posts/:id');
|
|
expect(params).toEqual([{ name: 'id', value: '' }]);
|
|
});
|
|
|
|
it('should parse path - case 8', () => {
|
|
const params = parsePathParams('https://www.example.com/users/:id/posts/:postId');
|
|
expect(params).toEqual([
|
|
{ name: 'id', value: '' },
|
|
{ name: 'postId', value: '' }
|
|
]);
|
|
});
|
|
|
|
it('should parse path param inside parentheses and quotes', () => {
|
|
const params = parsePathParams('https://example.com/ExchangeRates(\':ExchangeRateOID\')');
|
|
expect(params).toEqual([{ name: 'ExchangeRateOID', value: '' }]);
|
|
});
|
|
|
|
it('should parse path param inside parentheses and no quotes', () => {
|
|
const params = parsePathParams('https://example.com/ExchangeRates(:ExchangeRateOID)');
|
|
expect(params).toEqual([{ name: 'ExchangeRateOID', value: '' }]);
|
|
});
|
|
|
|
it('should parse multiple path params inside parentheses', () => {
|
|
const params = parsePathParams('https://example.com/Exchange(:ExchangeId)/ExchangeRates(:ExchangeRateOID)');
|
|
expect(params).toEqual([{ name: 'ExchangeId', value: '' }, { name: 'ExchangeRateOID', value: '' }]);
|
|
});
|
|
|
|
it('should parse mix and match of normal and param inside parentheses', () => {
|
|
const params = parsePathParams('https://example.com/Exchange(:ExchangeId)/:key');
|
|
expect(params).toEqual([{ name: 'ExchangeId', value: '' }, { name: 'key', value: '' }]);
|
|
});
|
|
|
|
// OData-specific test cases for enhanced path parameter parsing
|
|
it('should parse OData entity key with single quotes', () => {
|
|
const params = parsePathParams('https://example.com/odata/Products(\':productId\')');
|
|
expect(params).toEqual([{ name: 'productId', value: '' }]);
|
|
});
|
|
|
|
it('should parse OData entity key with double quotes', () => {
|
|
const params = parsePathParams('https://example.com/odata/Products(":productId")');
|
|
expect(params).toEqual([{ name: 'productId', value: '' }]);
|
|
});
|
|
|
|
it('should parse OData entity key with backticks', () => {
|
|
const params = parsePathParams('https://example.com/odata/Products(`:productId`)');
|
|
expect(params).toEqual([{ name: 'productId', value: '' }]);
|
|
});
|
|
|
|
it('should handle OData parameters with mixed quote types', () => {
|
|
const params = parsePathParams('https://example.com/odata/Products(\':productId\')/Categories(":categoryId")');
|
|
expect(params).toEqual([{ name: 'productId', value: '' }, { name: 'categoryId', value: '' }]);
|
|
});
|
|
|
|
it('should parse OData entity key with parentheses only', () => {
|
|
const params = parsePathParams('https://example.com/odata/Products(:productId)');
|
|
expect(params).toEqual([{ name: 'productId', value: '' }]);
|
|
});
|
|
|
|
it('should parse OData composite key with mixed parameter styles', () => {
|
|
// Test both positional and named parameter styles in the same key
|
|
const params = parsePathParams('https://example.com/odata/Orders(:orderId,ProductId=:productId)');
|
|
expect(params).toEqual([{ name: 'orderId', value: '' }, { name: 'productId', value: '' }]);
|
|
});
|
|
|
|
it('should parse OData navigation property with key', () => {
|
|
const params = parsePathParams('https://example.com/odata/Orders(:orderId)/Items(\':itemId\')');
|
|
expect(params).toEqual([{ name: 'orderId', value: '' }, { name: 'itemId', value: '' }]);
|
|
});
|
|
|
|
it('should parse OData function with parameters', () => {
|
|
const params = parsePathParams('https://example.com/odata/GetProductsByCategory(categoryId=\':categoryId\')');
|
|
expect(params).toEqual([{ name: 'categoryId', value: '' }]);
|
|
});
|
|
|
|
it('should parse OData action with complex parameters', () => {
|
|
const params = parsePathParams('https://example.com/odata/Products(\':productId\')/Rate(rating=:rating,comment=\':comment\')');
|
|
expect(params).toEqual([{ name: 'productId', value: '' }, { name: 'rating', value: '' }, { name: 'comment', value: '' }]);
|
|
});
|
|
|
|
it('should handle OData parameters with special characters in names', () => {
|
|
const params = parsePathParams('https://example.com/odata/Products(\':product-id\')');
|
|
expect(params).toEqual([{ name: 'product', value: '' }]);
|
|
});
|
|
|
|
it('should handle OData parameters with underscores in names', () => {
|
|
const params = parsePathParams('https://example.com/odata/Products(\':product_id\')');
|
|
expect(params).toEqual([{ name: 'product_id', value: '' }]);
|
|
});
|
|
|
|
it('should parse OData composite key with positional parameters', () => {
|
|
const params = parsePathParams('https://example.com/odata/Orders(:orderId,:productId)');
|
|
expect(params).toEqual([{ name: 'orderId', value: '' }, { name: 'productId', value: '' }]);
|
|
});
|
|
|
|
it('should parse OData composite key with named parameters', () => {
|
|
const params = parsePathParams('https://example.com/odata/Orders(OrderId=:orderId,ProductId=:productId)');
|
|
expect(params).toEqual([{ name: 'orderId', value: '' }, { name: 'productId', value: '' }]);
|
|
});
|
|
|
|
it('should handle OData navigation properties', () => {
|
|
const params = parsePathParams('https://example.com/odata/Orders(:orderId)/Items');
|
|
expect(params).toEqual([{ name: 'orderId', value: '' }]);
|
|
});
|
|
|
|
it('should handle OData function parameters', () => {
|
|
const params = parsePathParams('https://example.com/odata/Products/GetProductsByCategory(categoryId=:categoryId)');
|
|
expect(params).toEqual([{ name: 'categoryId', value: '' }]);
|
|
});
|
|
|
|
it('should handle OData parameters with query options in path', () => {
|
|
const params = parsePathParams('https://example.com/odata/Products(\':productId\')?$expand=Category');
|
|
expect(params).toEqual([{ name: 'productId', value: '' }]);
|
|
});
|
|
|
|
it('should handle OData parameters with multiple segments and mixed syntax', () => {
|
|
const params = parsePathParams('https://example.com/odata/Orders(:orderId)/Items(\':itemId\')/Properties(:propName)');
|
|
expect(params).toEqual([{ name: 'orderId', value: '' }, { name: 'itemId', value: '' }, { name: 'propName', value: '' }]);
|
|
});
|
|
|
|
it('should handle OData parameters with empty string values', () => {
|
|
const params = parsePathParams('https://example.com/odata/Products(\'\')');
|
|
expect(params).toEqual([]);
|
|
});
|
|
|
|
it('should NOT treat embedded colons as path parameters (regression fix)', () => {
|
|
// This test case reproduces the bug reported in issue #5805
|
|
const params = parsePathParams('/start/1:2:AHLS-HASD/form');
|
|
expect(params).toEqual([]);
|
|
});
|
|
|
|
it('should NOT treat embedded colons as path parameters in full URLs', () => {
|
|
const params = parsePathParams('https://example.com/start/1:2:AHLS-HASD/form');
|
|
expect(params).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe('Url Utils - URN parsing', () => {
|
|
it('should handle basic URN segments correctly', () => {
|
|
// Test case from issue #5817 - Don't treat URN segments as path parameters
|
|
const params = parsePathParams('https://example.com/urn:ard:show:3479462da794e97');
|
|
expect(params).toEqual([]);
|
|
|
|
// Test case for path parameter that starts with urn:
|
|
const params2 = parsePathParams('https://example.com/:urn_type');
|
|
expect(params2).toEqual([{ name: 'urn_type', value: '' }]);
|
|
});
|
|
|
|
it('should handle URNs with special characters', () => {
|
|
const params = parsePathParams('https://example.com/urn:isbn:0-330.12345-X');
|
|
expect(params).toEqual([]);
|
|
|
|
// URN with percent-encoded characters
|
|
const params2 = parsePathParams('https://example.com/urn:uuid:6e8bc430%2D9c3a-11d9-9669-0800200c9a66');
|
|
expect(params).toEqual([]);
|
|
});
|
|
|
|
it('should handle mixed URN and path parameter scenarios', () => {
|
|
// URN followed by path parameter
|
|
const params = parsePathParams('https://example.com/urn:nbn:de:bvb/123/:section');
|
|
expect(params).toEqual([{ name: 'section', value: '' }]);
|
|
|
|
// Path parameter followed by URN
|
|
const params2 = parsePathParams('https://example.com/:type/urn:isbn:123');
|
|
expect(params2).toEqual([{ name: 'type', value: '' }]);
|
|
|
|
// URN-like path parameter (not a real URN)
|
|
const params3 = parsePathParams('https://example.com/:urn:type');
|
|
expect(params3).toEqual([{ name: 'urn:type', value: '' }]);
|
|
});
|
|
|
|
it('should handle edge cases with URN-like patterns', () => {
|
|
// URN with uppercase (should be case-insensitive)
|
|
const params = parsePathParams('https://example.com/URN:isbn:123');
|
|
expect(params).toEqual([]);
|
|
|
|
// Path that looks like URN but isn't
|
|
const params2 = parsePathParams('https://example.com/noturn:something:here');
|
|
expect(params2).toEqual([]);
|
|
|
|
// Multiple colons in path parameter
|
|
const params3 = parsePathParams('https://example.com/:urn:isbn:type');
|
|
expect(params3).toEqual([{ name: 'urn:isbn:type', value: '' }]);
|
|
});
|
|
|
|
it('should handle URNs in complex URLs', () => {
|
|
// URN with query parameters
|
|
const params = parsePathParams('https://example.com/urn:isbn:123?format=:format');
|
|
expect(params).toEqual([]);
|
|
|
|
// Multiple URNs and path parameters
|
|
const params2 = parsePathParams('https://example.com/:category/urn:isbn:123/:subcategory/urn:issn:456');
|
|
expect(params2).toEqual([
|
|
{ name: 'category', value: '' },
|
|
{ name: 'subcategory', value: '' }
|
|
]);
|
|
|
|
// URN with fragment
|
|
const params3 = parsePathParams('https://example.com/urn:nbn:de:bvb:123#:section');
|
|
expect(params3).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe('Url Utils - OData parameters', () => {
|
|
it('should handle OData parameters with escaped quotes', () => {
|
|
const params = parsePathParams('https://example.com/odata/Products(\'ABC\'\'123\')');
|
|
expect(params).toEqual([]);
|
|
});
|
|
|
|
it('should handle OData parameters with spaces in quotes', () => {
|
|
const params = parsePathParams('https://example.com/odata/Products(\'Product Name With Spaces\')');
|
|
expect(params).toEqual([]);
|
|
});
|
|
|
|
it('should handle OData parameters with numeric keys', () => {
|
|
const params = parsePathParams('https://example.com/odata/Products(12345)');
|
|
expect(params).toEqual([]);
|
|
});
|
|
|
|
it('should handle OData parameters with GUID keys', () => {
|
|
const params = parsePathParams('https://example.com/odata/Products(\'123e4567-e89b-12d3-a456-426614174000\')');
|
|
expect(params).toEqual([]);
|
|
});
|
|
|
|
it('should handle OData with query parameters for variable interpolation', () => {
|
|
const params = parsePathParams('https://example.com/odata/Products?$filter=Category eq \'{{category}}\'&$orderby={{sortField}}');
|
|
expect(params).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe('Url Utils - splitOnFirst', () => {
|
|
it('should split on first - case 1', () => {
|
|
const params = splitOnFirst('a', '=');
|
|
expect(params).toEqual(['a']);
|
|
});
|
|
|
|
it('should split on first - case 2', () => {
|
|
const params = splitOnFirst('a=', '=');
|
|
expect(params).toEqual(['a', '']);
|
|
});
|
|
|
|
it('should split on first - case 3', () => {
|
|
const params = splitOnFirst('a=1', '=');
|
|
expect(params).toEqual(['a', '1']);
|
|
});
|
|
|
|
it('should split on first - case 4', () => {
|
|
const params = splitOnFirst('a=1&b=2', '=');
|
|
expect(params).toEqual(['a', '1&b=2']);
|
|
});
|
|
|
|
it('should split on first - case 5', () => {
|
|
const params = splitOnFirst('a=1&b=2', '&');
|
|
expect(params).toEqual(['a=1', 'b=2']);
|
|
});
|
|
});
|
|
|
|
describe('Url Utils - interpolateUrl, interpolateUrlPathParams', () => {
|
|
it('should interpolate url correctly', () => {
|
|
const url = '{{host}}/api/:id/path?foo={{foo}}&bar={{bar}}&baz={{process.env.baz}}';
|
|
const expectedUrl = 'https://example.com/api/:id/path?foo=foo_value&bar=bar_value&baz=baz_value';
|
|
|
|
const result = interpolateUrl({ url, variables: { 'host': 'https://example.com', 'foo': 'foo_value', 'bar': 'bar_value', 'process.env.baz': 'baz_value' } });
|
|
|
|
expect(result).toEqual(expectedUrl);
|
|
});
|
|
|
|
it('should interpolate path params correctly', () => {
|
|
const url = 'https://example.com/api/:id/path';
|
|
const params = [{ name: 'id', type: 'path', enabled: true, value: '123' }];
|
|
const expectedUrl = 'https://example.com/api/123/path';
|
|
|
|
const result = interpolateUrlPathParams(url, params);
|
|
|
|
expect(result).toEqual(expectedUrl);
|
|
});
|
|
|
|
it('should interpolate url and path params correctly', () => {
|
|
const url = '{{host}}/api/:id/path?foo={{foo}}&bar={{bar}}&baz={{process.env.baz}}';
|
|
const params = [{ name: 'id', type: 'path', enabled: true, value: '123' }];
|
|
const expectedUrl = 'https://example.com/api/123/path?foo=foo_value&bar=bar_value&baz=baz_value';
|
|
|
|
const intermediateResult = interpolateUrl({ url, variables: { 'host': 'https://example.com', 'foo': 'foo_value', 'bar': 'bar_value', 'process.env.baz': 'baz_value' } });
|
|
const result = interpolateUrlPathParams(intermediateResult, params);
|
|
|
|
expect(result).toEqual(expectedUrl);
|
|
});
|
|
|
|
it('should interpolate path params correctly', () => {
|
|
const url = 'https://example.com/api/:id/path/:user';
|
|
const params = [{ name: 'id', type: 'path', enabled: true, value: '123' }, { name: 'user', type: 'path', enabled: true, value: '{{user}}' }];
|
|
const variables = { user: 'John' };
|
|
const expectedUrl = 'https://example.com/api/123/path/John';
|
|
|
|
const result = interpolateUrlPathParams(url, params, variables);
|
|
|
|
expect(result).toEqual(expectedUrl);
|
|
});
|
|
|
|
it('should interpolate url and path params correctly', () => {
|
|
const url = '{{host}}/api/:id/path/:user?foo={{foo}}&bar={{bar}}&baz={{process.env.baz}}';
|
|
const params = [{ name: 'id', type: 'path', enabled: true, value: '123' }, { name: 'user', type: 'path', enabled: true, value: '{{user}}' }];
|
|
const variables = { 'host': 'https://example.com', 'foo': 'foo_value', 'bar': 'bar_value', 'process.env.baz': 'baz_value', 'user': 'John' };
|
|
const expectedUrl = 'https://example.com/api/123/path/John?foo=foo_value&bar=bar_value&baz=baz_value';
|
|
|
|
const intermediateResult = interpolateUrl({ url, variables });
|
|
const result = interpolateUrlPathParams(intermediateResult, params, variables);
|
|
|
|
expect(result).toEqual(expectedUrl);
|
|
});
|
|
|
|
it('should handle empty params', () => {
|
|
const url = 'https://example.com/api';
|
|
const params = [];
|
|
const expectedUrl = 'https://example.com/api';
|
|
|
|
const result = interpolateUrlPathParams(url, params);
|
|
|
|
expect(result).toEqual(expectedUrl);
|
|
});
|
|
|
|
it('should handle invalid URL, case 1', () => {
|
|
const url = 'example.com/api/:id';
|
|
const params = [{ name: 'id', type: 'path', enabled: true, value: '123' }];
|
|
const expectedUrl = 'http://example.com/api/123';
|
|
|
|
const result = interpolateUrlPathParams(url, params);
|
|
|
|
expect(result).toEqual(expectedUrl);
|
|
});
|
|
|
|
it('should handle invalid URL, case 2', () => {
|
|
const url = 'http://1.1.1.1:3000:id';
|
|
const params = [{ name: 'id', type: 'path', enabled: true, value: '123' }];
|
|
const expectedUrl = 'http://1.1.1.1:3000:id';
|
|
|
|
const result = interpolateUrlPathParams(url, params);
|
|
|
|
expect(result).toEqual(expectedUrl);
|
|
});
|
|
});
|