n8n/packages/nodes-base/nodes/HttpRequest/test/node/HttpRequestV1.test.ts
Khadyot Takale 47ffd1cc07
fix(HTTP Request Node): Trim url whitespace (#27381)
Co-authored-by: yehorkardash <yehor.kardash@n8n.io>
2026-05-19 07:52:14 +00:00

153 lines
4.5 KiB
TypeScript

import type { IExecuteFunctions, INodeTypeBaseDescription } from 'n8n-workflow';
import { HttpRequestV1 } from '../../V1/HttpRequestV1.node';
describe('HttpRequestV1', () => {
let node: HttpRequestV1;
let executeFunctions: IExecuteFunctions;
beforeEach(() => {
const baseDescription: INodeTypeBaseDescription = {
displayName: 'HTTP Request',
name: 'httpRequest',
description: 'Makes an HTTP request and returns the response data',
group: [],
};
node = new HttpRequestV1(baseDescription);
executeFunctions = {
getInputData: jest.fn(),
getNodeParameter: jest.fn(),
getNode: jest.fn(() => {
return {
type: 'n8n-nodes-base.httpRequest',
typeVersion: 1,
};
}),
getCredentials: jest.fn(),
helpers: {
request: jest.fn(),
requestOAuth1: jest.fn(
async () =>
await Promise.resolve({
success: true,
}),
),
requestOAuth2: jest.fn(
async () =>
await Promise.resolve({
success: true,
}),
),
requestWithAuthentication: jest.fn(),
requestWithAuthenticationPaginated: jest.fn(),
assertBinaryData: jest.fn(),
getBinaryStream: jest.fn(),
getBinaryMetadata: jest.fn(),
binaryToString: jest.fn((buffer: Buffer) => {
return buffer.toString();
}),
prepareBinaryData: jest.fn(),
},
getContext: jest.fn(),
sendMessageToUI: jest.fn(),
continueOnFail: jest.fn(),
getMode: jest.fn(),
} as unknown as IExecuteFunctions;
});
describe('URL Parameter Validation', () => {
it('should throw error when URL is only whitespace', async () => {
(executeFunctions.getInputData as jest.Mock).mockReturnValue([{ json: {} }]);
(executeFunctions.getNodeParameter as jest.Mock).mockImplementation((paramName: string) => {
switch (paramName) {
case 'responseFormat':
return 'json';
case 'requestMethod':
return 'GET';
case 'url':
return ' ';
case 'jsonParameters':
return false;
case 'options':
return {};
default:
return undefined;
}
});
(executeFunctions.getCredentials as jest.Mock).mockRejectedValue(new Error('No credentials'));
await expect(node.execute.call(executeFunctions)).rejects.toThrow(
'URL parameter cannot be empty',
);
});
it('should trim whitespace from valid URL', async () => {
(executeFunctions.getInputData as jest.Mock).mockReturnValue([{ json: {} }]);
(executeFunctions.getNodeParameter as jest.Mock).mockImplementation((paramName: string) => {
switch (paramName) {
case 'responseFormat':
return 'json';
case 'requestMethod':
return 'GET';
case 'url':
return ' http://example.com ';
case 'jsonParameters':
return false;
case 'options':
return {};
case 'bodyParametersUi':
case 'headerParametersUi':
case 'queryParametersUi':
return { parameter: [] };
default:
return undefined;
}
});
(executeFunctions.getCredentials as jest.Mock).mockRejectedValue(new Error('No credentials'));
const response = {
success: true,
};
(executeFunctions.helpers.request as jest.Mock).mockResolvedValue(response);
const result = await node.execute.call(executeFunctions);
expect(result).toEqual([[{ json: { success: true }, pairedItem: { item: 0 } }]]);
expect(executeFunctions.helpers.request).toHaveBeenCalledTimes(1);
const requestArgs = (executeFunctions.helpers.request as jest.Mock).mock.calls[0][0];
expect(requestArgs.uri ?? requestArgs.url).toBe('http://example.com');
});
it.each([
{ url: undefined, expectedType: 'undefined' },
{ url: null, expectedType: 'null' },
{ url: 42, expectedType: 'number' },
])('should throw error when URL is $expectedType', async ({ url, expectedType }) => {
(executeFunctions.getInputData as jest.Mock).mockReturnValue([{ json: {} }]);
(executeFunctions.getNodeParameter as jest.Mock).mockImplementation((paramName: string) => {
switch (paramName) {
case 'responseFormat':
return 'json';
case 'requestMethod':
return 'GET';
case 'url':
return url;
case 'jsonParameters':
return false;
case 'options':
return {};
case 'bodyParametersUi':
case 'headerParametersUi':
case 'queryParametersUi':
return { parameter: [] };
default:
return undefined;
}
});
(executeFunctions.getCredentials as jest.Mock).mockRejectedValue(new Error('No credentials'));
await expect(node.execute.call(executeFunctions)).rejects.toThrow(
`URL parameter must be a string, got ${expectedType}`,
);
});
});
});