mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-09 22:24:05 -08:00
fix(editor): Fix bug with node names with certain characters (#8013)
## Summary Fixes the issue that dots and other special characters can not be used in node-names ## Related tickets and issues https://linear.app/n8n/issue/ADO-1244/nodes-wont-output-data-if-the-name-contains-some-characters https://community.n8n.io/t/bug-report-name-of-node-affects-output-data/31674 https://community.n8n.io/t/stripe-output-data/32418/1 https://community.n8n.io/t/monday-com-returning-items-but-no-data/31834 https://community.n8n.io/t/no-data-while-there-is-actually-data/32563 https://community.n8n.io/t/bug-report-periods-in-node-names/34119 https://github.com/n8n-io/n8n/issues/7896 ## Review / Merge checklist - [ ] PR title and summary are descriptive. **Remember, the title automatically goes into the changelog. Use `(no-changelog)` otherwise.** ([conventions](https://github.com/n8n-io/n8n/blob/master/.github/pull_request_title_conventions.md)) - [ ] [Docs updated](https://github.com/n8n-io/n8n-docs) or follow-up ticket created. - [ ] Tests included. > A bug is not considered fixed, unless a test is added to prevent it from happening again. > A feature is not complete without tests. --------- Co-authored-by: Alex Grozav <alex@grozav.com>
This commit is contained in:
parent
8a5343401d
commit
26f0d57f5f
|
@ -0,0 +1,182 @@
|
||||||
|
import { setActivePinia } from 'pinia';
|
||||||
|
import { createTestingPinia } from '@pinia/testing';
|
||||||
|
import { useNodeHelpers } from '@/composables/useNodeHelpers';
|
||||||
|
import { createTestNode } from '@/__tests__/mocks';
|
||||||
|
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||||
|
|
||||||
|
vi.mock('@/stores/workflows.store', () => ({
|
||||||
|
useWorkflowsStore: vi.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('useNodeHelpers()', () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
setActivePinia(createTestingPinia());
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getNodeInputData()', () => {
|
||||||
|
it('should return an empty array when node is null', () => {
|
||||||
|
const { getNodeInputData } = useNodeHelpers();
|
||||||
|
|
||||||
|
const result = getNodeInputData(null);
|
||||||
|
expect(result).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an empty array when workflowsStore.getWorkflowExecution() is null', () => {
|
||||||
|
vi.mocked(useWorkflowsStore).mockReturnValue({
|
||||||
|
getWorkflowExecution: null,
|
||||||
|
} as ReturnType<typeof useWorkflowsStore>);
|
||||||
|
const { getNodeInputData } = useNodeHelpers();
|
||||||
|
const node = createTestNode({
|
||||||
|
name: 'test',
|
||||||
|
type: 'test',
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = getNodeInputData(node);
|
||||||
|
expect(result).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an empty array when workflowsStore.getWorkflowExecution() is null', () => {
|
||||||
|
vi.mocked(useWorkflowsStore).mockReturnValue({
|
||||||
|
getWorkflowExecution: null,
|
||||||
|
} as ReturnType<typeof useWorkflowsStore>);
|
||||||
|
const { getNodeInputData } = useNodeHelpers();
|
||||||
|
const node = createTestNode({
|
||||||
|
name: 'test',
|
||||||
|
type: 'test',
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = getNodeInputData(node);
|
||||||
|
expect(result).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an empty array when resultData is not available', () => {
|
||||||
|
vi.mocked(useWorkflowsStore).mockReturnValue({
|
||||||
|
getWorkflowExecution: {
|
||||||
|
data: {
|
||||||
|
resultData: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as unknown as ReturnType<typeof useWorkflowsStore>);
|
||||||
|
const { getNodeInputData } = useNodeHelpers();
|
||||||
|
const node = createTestNode({
|
||||||
|
name: 'test',
|
||||||
|
type: 'test',
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = getNodeInputData(node);
|
||||||
|
expect(result).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an empty array when taskData is unavailable', () => {
|
||||||
|
const nodeName = 'Code';
|
||||||
|
vi.mocked(useWorkflowsStore).mockReturnValue({
|
||||||
|
getWorkflowExecution: {
|
||||||
|
data: {
|
||||||
|
resultData: {
|
||||||
|
runData: {
|
||||||
|
[nodeName]: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as unknown as ReturnType<typeof useWorkflowsStore>);
|
||||||
|
const { getNodeInputData } = useNodeHelpers();
|
||||||
|
const node = createTestNode({
|
||||||
|
name: nodeName,
|
||||||
|
type: 'test',
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = getNodeInputData(node);
|
||||||
|
expect(result).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an empty array when taskData.data is unavailable', () => {
|
||||||
|
const nodeName = 'Code';
|
||||||
|
vi.mocked(useWorkflowsStore).mockReturnValue({
|
||||||
|
getWorkflowExecution: {
|
||||||
|
data: {
|
||||||
|
resultData: {
|
||||||
|
runData: {
|
||||||
|
[nodeName]: [{ data: undefined }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as unknown as ReturnType<typeof useWorkflowsStore>);
|
||||||
|
const { getNodeInputData } = useNodeHelpers();
|
||||||
|
const node = createTestNode({
|
||||||
|
name: nodeName,
|
||||||
|
type: 'test',
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = getNodeInputData(node);
|
||||||
|
expect(result).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return input data from inputOverride', () => {
|
||||||
|
const nodeName = 'Code';
|
||||||
|
const data = { hello: 'world' };
|
||||||
|
vi.mocked(useWorkflowsStore).mockReturnValue({
|
||||||
|
getWorkflowExecution: {
|
||||||
|
data: {
|
||||||
|
resultData: {
|
||||||
|
runData: {
|
||||||
|
[nodeName]: [
|
||||||
|
{
|
||||||
|
inputOverride: {
|
||||||
|
main: [data],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as unknown as ReturnType<typeof useWorkflowsStore>);
|
||||||
|
const { getNodeInputData } = useNodeHelpers();
|
||||||
|
const node = createTestNode({
|
||||||
|
name: nodeName,
|
||||||
|
type: 'test',
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = getNodeInputData(node, 0, 0, 'input');
|
||||||
|
expect(result).toEqual(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each(['example', 'example.withdot', 'example.with.dots', 'example.with.dots and spaces'])(
|
||||||
|
'should return input data for "%s" node name, with given connection type and output index',
|
||||||
|
(nodeName) => {
|
||||||
|
const data = { hello: 'world' };
|
||||||
|
vi.mocked(useWorkflowsStore).mockReturnValue({
|
||||||
|
getWorkflowExecution: {
|
||||||
|
data: {
|
||||||
|
resultData: {
|
||||||
|
runData: {
|
||||||
|
[nodeName]: [
|
||||||
|
{
|
||||||
|
data: {
|
||||||
|
main: [data],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as unknown as ReturnType<typeof useWorkflowsStore>);
|
||||||
|
const { getNodeInputData } = useNodeHelpers();
|
||||||
|
const node = createTestNode({
|
||||||
|
name: nodeName,
|
||||||
|
type: 'test',
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = getNodeInputData(node);
|
||||||
|
expect(result).toEqual(data);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
|
@ -539,7 +539,7 @@ export function useNodeHelpers() {
|
||||||
}
|
}
|
||||||
const runData = executionData.resultData.runData;
|
const runData = executionData.resultData.runData;
|
||||||
|
|
||||||
const taskData = get(runData, `[${node.name}][${runIndex}]`);
|
const taskData = get(runData, [node.name, runIndex]);
|
||||||
if (!taskData) {
|
if (!taskData) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue