mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 02:21:13 +00:00
fix(n8n Form Node): Hidden field fix (#14219)
This commit is contained in:
@@ -2,7 +2,9 @@ import { mock } from 'jest-mock-extended';
|
||||
import { DateTime } from 'luxon';
|
||||
import type {
|
||||
FormFieldsParameter,
|
||||
IDataObject,
|
||||
INode,
|
||||
INodeExecutionData,
|
||||
IWebhookFunctions,
|
||||
MultiPartFormData,
|
||||
NodeTypeAndVersion,
|
||||
@@ -18,6 +20,7 @@ import {
|
||||
sanitizeHtml,
|
||||
validateResponseModeConfiguration,
|
||||
prepareFormFields,
|
||||
addFormResponseDataToReturnItem,
|
||||
} from '../utils';
|
||||
|
||||
describe('FormTrigger, parseFormDescription', () => {
|
||||
@@ -1032,3 +1035,75 @@ describe('validateResponseModeConfiguration', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('addFormResponseDataToReturnItem', () => {
|
||||
let returnItem: INodeExecutionData;
|
||||
|
||||
beforeEach(() => {
|
||||
returnItem = { json: {} };
|
||||
});
|
||||
|
||||
test('should use fieldName if fieldLabel is missing', () => {
|
||||
const formFields: FormFieldsParameter = [
|
||||
{ fieldName: 'Alternative Field', fieldType: 'hiddenField' },
|
||||
] as FormFieldsParameter;
|
||||
const bodyData: IDataObject = { 'field-0': 'Test Value' };
|
||||
|
||||
addFormResponseDataToReturnItem(returnItem, formFields, bodyData);
|
||||
expect(returnItem.json['Alternative Field']).toBe('Test Value');
|
||||
});
|
||||
|
||||
it('should handle null values', () => {
|
||||
const formFields: FormFieldsParameter = [{ fieldLabel: 'Test Field', fieldType: 'text' }];
|
||||
const bodyData: IDataObject = {};
|
||||
|
||||
addFormResponseDataToReturnItem(returnItem, formFields, bodyData);
|
||||
expect(returnItem.json['Test Field']).toBeNull();
|
||||
});
|
||||
|
||||
it('should process html fields and set elementName', () => {
|
||||
const formFields: FormFieldsParameter = [
|
||||
{ fieldLabel: 'HTML Field', elementName: 'htmlElement', fieldType: 'html' },
|
||||
];
|
||||
const bodyData: IDataObject = { 'field-0': '<p>HTML Content</p>' };
|
||||
|
||||
addFormResponseDataToReturnItem(returnItem, formFields, bodyData);
|
||||
expect(returnItem.json.htmlElement).toBe('<p>HTML Content</p>');
|
||||
});
|
||||
|
||||
it('should parse number fields correctly', () => {
|
||||
const formFields: FormFieldsParameter = [{ fieldLabel: 'Number Field', fieldType: 'number' }];
|
||||
const bodyData: IDataObject = { 'field-0': '42' };
|
||||
|
||||
addFormResponseDataToReturnItem(returnItem, formFields, bodyData);
|
||||
expect(returnItem.json['Number Field']).toBe(42);
|
||||
});
|
||||
|
||||
it('should trim text fields', () => {
|
||||
const formFields: FormFieldsParameter = [{ fieldLabel: 'Text Field', fieldType: 'text' }];
|
||||
const bodyData: IDataObject = { 'field-0': ' hello world ' };
|
||||
|
||||
addFormResponseDataToReturnItem(returnItem, formFields, bodyData);
|
||||
expect(returnItem.json['Text Field']).toBe('hello world');
|
||||
});
|
||||
|
||||
it('should parse multiselect fields from JSON', () => {
|
||||
const formFields: FormFieldsParameter = [
|
||||
{ fieldLabel: 'Multi Field', fieldType: 'text', multiselect: true },
|
||||
];
|
||||
const bodyData: IDataObject = { 'field-0': '["option1", "option2"]' };
|
||||
|
||||
addFormResponseDataToReturnItem(returnItem, formFields, bodyData);
|
||||
expect(returnItem.json['Multi Field']).toEqual(['option1', 'option2']);
|
||||
});
|
||||
|
||||
it('should convert single file values to an array if multipleFiles is true', () => {
|
||||
const formFields: FormFieldsParameter = [
|
||||
{ fieldLabel: 'File Field', fieldType: 'file', multipleFiles: true },
|
||||
];
|
||||
const bodyData: IDataObject = { 'field-0': 'file1.pdf' };
|
||||
|
||||
addFormResponseDataToReturnItem(returnItem, formFields, bodyData);
|
||||
expect(returnItem.json['File Field']).toEqual(['file1.pdf']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -269,6 +269,48 @@ export const validateResponseModeConfiguration = (context: IWebhookFunctions) =>
|
||||
}
|
||||
};
|
||||
|
||||
export function addFormResponseDataToReturnItem(
|
||||
returnItem: INodeExecutionData,
|
||||
formFields: FormFieldsParameter,
|
||||
bodyData: IDataObject,
|
||||
) {
|
||||
for (const [index, field] of formFields.entries()) {
|
||||
const key = `field-${index}`;
|
||||
const name = field.fieldLabel ?? field.fieldName;
|
||||
let value = bodyData[key] ?? null;
|
||||
|
||||
if (value === null) {
|
||||
returnItem.json[name] = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (field.fieldType === 'html') {
|
||||
if (field.elementName) {
|
||||
returnItem.json[field.elementName] = value;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (field.fieldType === 'number') {
|
||||
value = Number(value);
|
||||
}
|
||||
if (field.fieldType === 'text') {
|
||||
value = String(value).trim();
|
||||
}
|
||||
if (field.multiselect && typeof value === 'string') {
|
||||
value = jsonParse(value);
|
||||
}
|
||||
if (field.fieldType === 'date' && value && field.formatDate !== '') {
|
||||
value = DateTime.fromFormat(String(value), 'yyyy-mm-dd').toFormat(field.formatDate as string);
|
||||
}
|
||||
if (field.fieldType === 'file' && field.multipleFiles && !Array.isArray(value)) {
|
||||
value = [value];
|
||||
}
|
||||
|
||||
returnItem.json[name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
export async function prepareFormReturnItem(
|
||||
context: IWebhookFunctions,
|
||||
formFields: FormFieldsParameter,
|
||||
@@ -326,40 +368,7 @@ export async function prepareFormReturnItem(
|
||||
}
|
||||
}
|
||||
|
||||
for (const [index, field] of formFields.entries()) {
|
||||
const key = `field-${index}`;
|
||||
let value = bodyData[key] ?? null;
|
||||
|
||||
if (value === null) {
|
||||
returnItem.json[field.fieldLabel] = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (field.fieldType === 'html') {
|
||||
if (field.elementName) {
|
||||
returnItem.json[field.elementName] = value;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (field.fieldType === 'number') {
|
||||
value = Number(value);
|
||||
}
|
||||
if (field.fieldType === 'text') {
|
||||
value = String(value).trim();
|
||||
}
|
||||
if (field.multiselect && typeof value === 'string') {
|
||||
value = jsonParse(value);
|
||||
}
|
||||
if (field.fieldType === 'date' && value && field.formatDate !== '') {
|
||||
value = DateTime.fromFormat(String(value), 'yyyy-mm-dd').toFormat(field.formatDate as string);
|
||||
}
|
||||
if (field.fieldType === 'file' && field.multipleFiles && !Array.isArray(value)) {
|
||||
value = [value];
|
||||
}
|
||||
|
||||
returnItem.json[field.fieldLabel] = value;
|
||||
}
|
||||
addFormResponseDataToReturnItem(returnItem, formFields, bodyData);
|
||||
|
||||
const timezone = useWorkflowTimezone ? context.getTimezone() : 'UTC';
|
||||
returnItem.json.submittedAt = DateTime.now().setZone(timezone).toISO();
|
||||
|
||||
Reference in New Issue
Block a user