Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(pre-request script): avoid encoding tags in parsing request urls - INS-3379 #7249

Merged
merged 8 commits into from
Apr 10, 2024
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import url from 'node:url';

import { describe, expect, it } from '@jest/globals';

import { Certificate } from '../certificates';
import { setUrlParser } from '../urls';

describe('test Certificate object', () => {
it('test methods', () => {
// make URL work in Node.js
setUrlParser(url.URL);

const cert = new Certificate({
name: 'Certificate for example.com',
matches: ['https://example.com'],
Expand Down
52 changes: 46 additions & 6 deletions packages/insomnia/src/sdk/objects/__tests__/request.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import url from 'node:url';

import { describe, expect, it } from '@jest/globals';

import { Request, RequestBody } from '../request';
import { setUrlParser } from '../urls';
import { mergeRequestBody, Request, RequestBody, toScriptRequestBody } from '../request';

describe('test request and response objects', () => {
setUrlParser(url.URL);

it('test RequestBody methods', () => {
const reqBody = new RequestBody({
mode: 'urlencoded',
Expand Down Expand Up @@ -72,4 +67,49 @@ describe('test request and response objects', () => {
const req2 = req.clone();
expect(req2.toJSON()).toEqual(req.toJSON());
});

it('test Request body transforming', () => {
const bodies = [
{
mimeType: 'text/plain',
text: 'rawContent',
},
{
mimeType: 'application/octet-stream',
fileName: 'path/to/file',
},
{
mimeType: 'application/x-www-form-urlencoded',
params: [
{ name: 'k1', value: 'v1' },
{ name: 'k2', value: 'v2' },
],
},
{
mimeType: 'application/json',
text: `{
query: 'query',
operationName: 'operation',
variables: 'var',
}`,
},
{
mimeType: 'image/gif',
fileName: '/path/to/image',
},
{
mimeType: 'multipart/form-data',
params: [
{ name: 'k1', type: 'text', value: 'v1' },
{ name: 'k2', type: 'file', value: '/path/to/image' },
],
},
];

bodies.forEach(body => {
const originalReqBody = body;
const scriptReqBody = new RequestBody(toScriptRequestBody(body));
expect(mergeRequestBody(scriptReqBody, originalReqBody)).toEqual(originalReqBody);
});
});
});
5 changes: 0 additions & 5 deletions packages/insomnia/src/sdk/objects/__tests__/response.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
import url from 'node:url';

import { describe, expect, it } from '@jest/globals';

import { Request } from '../request';
import { Response } from '../response';
import { setUrlParser } from '../urls';

describe('test request and response objects', () => {
setUrlParser(url.URL);

it('test Response methods', () => {
const req = new Request({
url: 'https://hostname.com/path',
Expand Down
91 changes: 77 additions & 14 deletions packages/insomnia/src/sdk/objects/__tests__/urls.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import url from 'node:url';

import { describe, expect, it } from '@jest/globals';

import { QueryParam, setUrlParser, Url, UrlMatchPattern } from '../urls';
import { QueryParam, Url, UrlMatchPattern } from '../urls';
import { Variable } from '../variables';

describe('test Url object', () => {
setUrlParser(url.URL);

it('test QueryParam', () => {
const queryParam = new QueryParam({
key: 'uname',
Expand Down Expand Up @@ -57,33 +53,34 @@ describe('test Url object', () => {
],
});

expect(url.getHost()).toEqual('hostvalue.com');
expect(url.getHost()).toEqual('hostValue.com');
expect(url.getPath()).toEqual('/pathLevel1/pathLevel2');

expect(url.getQueryString()).toEqual('key1=value1&key2=value2&key3=value3');
expect(url.getPathWithQuery()).toEqual('/pathLevel1/pathLevel2?key1=value1&key2=value2&key3=value3');
expect(url.getRemote(true)).toEqual('hostvalue.com:777');
expect(url.getRemote(false)).toEqual('hostvalue.com:777'); // TODO: add more cases
expect(url.getRemote(true)).toEqual('hostValue.com:777');
expect(url.getRemote(false)).toEqual('hostValue.com:777'); // TODO: add more cases

url.removeQueryParams([
new QueryParam({ key: 'key1', value: 'value1' }),
]);
url.removeQueryParams('key3');
expect(url.getQueryString()).toEqual('key2=value2');
expect(url.toString()).toEqual('https://usernameValue:passwordValue@hostvalue.com:777/pathLevel1/pathLevel2?key2=value2#hashValue');
expect(url.toString()).toEqual('https://usernameValue:passwordValue@hostValue.com:777/pathLevel1/pathLevel2?key2=value2#hashValue');

const url2 = new Url('https://usernameValue:passwordValue@hostvalue.com:777/pathLevel1/pathLevel2?key1=value1&key2=value2#hashValue');
expect(url2.getHost()).toEqual('hostvalue.com');
const url2 = new Url('https://usernameValue:passwordValue@hostValue.com:777/pathLevel1/pathLevel2?key1=value1&key2=value2#hashValue');
expect(url2.getHost()).toEqual('hostValue.com');
expect(url2.getPath()).toEqual('/pathLevel1/pathLevel2');
expect(url2.getQueryString()).toEqual('key1=value1&key2=value2');
expect(url2.getPathWithQuery()).toEqual('/pathLevel1/pathLevel2?key1=value1&key2=value2');
expect(url2.getRemote(true)).toEqual('hostvalue.com:777');
expect(url2.getRemote(false)).toEqual('hostvalue.com:777'); // TODO: add more cases
expect(url2.getRemote(true)).toEqual('hostValue.com:777');
expect(url2.getRemote(false)).toEqual('hostValue.com:777'); // TODO: add more cases

url2.removeQueryParams([
new QueryParam({ key: 'key1', value: 'value1' }),
]);
expect(url2.getQueryString()).toEqual('key2=value2');
expect(url2.toString()).toEqual('https://usernameValue:passwordValue@hostvalue.com:777/pathLevel1/pathLevel2?key2=value2#hashValue');
expect(url2.toString()).toEqual('https://usernameValue:passwordValue@hostValue.com:777/pathLevel1/pathLevel2?key2=value2#hashValue');
});

it('test Url static methods', () => {
Expand All @@ -94,6 +91,72 @@ describe('test Url object', () => {

expect(urlObj.toString()).toEqual(urlStr);
});

const urlParsingTests = [
{
testName: 'interal url',
url: 'inso/',
},
{
testName: 'interal url with protocol',
url: 'http://inso/',
},
{
testName: 'interal url with auth',
url: 'http://name:pwd@inso/',
},
{
testName: 'interal url with auth without protocol',
url: 'name:pwd@inso/',
},
{
testName: 'ip address',
url: 'http://127.0.0.1/',
},
{
testName: 'localhost',
url: 'https://localhost/',
},
{
testName: 'url with query params',
url: 'localhost/?k=v',
},
{
testName: 'url with hash',
url: 'localhost/#myHash',
},
{
testName: 'url with query params and hash',
url: 'localhost/?k=v#myHash',
},
{
testName: 'url with query params and hash',
url: 'localhost/?k={{ myValue }}',
},
{
testName: 'url with query params and hash',
url: 'localhost/#My{{ hashValue }}',
},
{
testName: 'url with path params',
url: 'inso.com/:path1/:path',
},
{
testName: 'url with tags and path params',
url: '{{ _.baseUrl }}/:path1/:path',
},
{
testName: 'hybrid of path params and tags',
url: '{{ baseUrl }}/:path_{{ _.pathSuffix }}',
},
];

urlParsingTests.forEach(testCase => {
it(`parsing url: ${testCase.testName}`, () => {
const urlObj = new Url(testCase.url);
expect(urlObj.toString()).toEqual(testCase.url);
});
});
});

describe('test Url Match Pattern', () => {
Expand Down
27 changes: 4 additions & 23 deletions packages/insomnia/src/sdk/objects/insomnia.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { expect } from 'chai';

import { ClientCertificate } from '../../models/client-certificate';
import { RequestBodyParameter, RequestHeader } from '../../models/request';
import { RequestHeader } from '../../models/request';
import { Settings } from '../../models/settings';
import { toPreRequestAuth } from './auth';
import { CookieObject } from './cookies';
import { Environment, Variables } from './environments';
import { RequestContext } from './interfaces';
import { unsupportedError } from './properties';
import { Request as ScriptRequest, RequestBodyOptions, RequestOptions } from './request';
import { Request as ScriptRequest, RequestOptions, toScriptRequestBody } from './request';
import { Response as ScriptResponse } from './response';
import { sendRequest } from './send-request';
import { test } from './test';
Expand Down Expand Up @@ -125,26 +125,6 @@ export function initInsomniaObject(
data: iterationData,
});

let reqBodyOpt: RequestBodyOptions = { mode: undefined };
if (rawObj.request.body.text != null) {
reqBodyOpt = {
mode: 'raw',
raw: rawObj.request.body.text,
};
} else if (rawObj.request.body.fileName != null && rawObj.request.body.fileName !== '') {
reqBodyOpt = {
mode: 'file',
file: rawObj.request.body.fileName,
};
} else if (rawObj.request.body.params != null) {
reqBodyOpt = {
mode: 'urlencoded',
urlencoded: rawObj.request.body.params.map(
(param: RequestBodyParameter) => ({ key: param.name, value: param.value })
),
};
}

const certificate = rawObj.clientCertificates != null && rawObj.clientCertificates.length > 0 ?
{
disabled: false,
Expand Down Expand Up @@ -203,10 +183,11 @@ export function initInsomniaObject(
header: rawObj.request.headers.map(
(header: RequestHeader) => ({ key: header.name, value: header.value })
),
body: reqBodyOpt,
body: toScriptRequestBody(rawObj.request.body),
auth: toPreRequestAuth(rawObj.request.authentication),
proxy,
certificate,
pathParameters: rawObj.request.pathParameters,
};
const request = new ScriptRequest(reqOpt);

Expand Down
Loading
Loading