## 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>
183 lines
4.6 KiB
TypeScript
183 lines
4.6 KiB
TypeScript
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);
|
|
},
|
|
);
|
|
});
|
|
});
|