fix(editor): Use optional chaining for all members in execution data when using the debug feature (#12024)
Some checks are pending
Test Master / install-and-build (push) Waiting to run
Test Master / Unit tests (18.x) (push) Blocked by required conditions
Test Master / Unit tests (20.x) (push) Blocked by required conditions
Test Master / Unit tests (22.4) (push) Blocked by required conditions
Test Master / Lint (push) Blocked by required conditions
Test Master / Notify Slack on failure (push) Blocked by required conditions

This commit is contained in:
Csaba Tuncsik 2024-12-04 11:05:16 +01:00 committed by GitHub
parent 6af9c82af6
commit 67aa0c9107
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 75 additions and 6 deletions

View file

@ -1,14 +1,84 @@
import { createTestingPinia } from '@pinia/testing'; import { createTestingPinia } from '@pinia/testing';
import { setActivePinia } from 'pinia';
import { mockedStore } from '@/__tests__/utils'; import { mockedStore } from '@/__tests__/utils';
import { useWorkflowsStore } from '@/stores/workflows.store'; import { useWorkflowsStore } from '@/stores/workflows.store';
import { useExecutionDebugging } from './useExecutionDebugging'; import { useExecutionDebugging } from './useExecutionDebugging';
import type { INodeUi, IExecutionResponse } from '@/Interface'; import type { INodeUi, IExecutionResponse } from '@/Interface';
import type { Workflow } from 'n8n-workflow'; import type { Workflow } from 'n8n-workflow';
import { useToast } from '@/composables/useToast';
vi.mock('@/composables/useToast', () => {
const showToast = vi.fn();
return {
useToast: () => ({
showToast,
}),
};
});
let executionDebugging: ReturnType<typeof useExecutionDebugging>;
let toast: ReturnType<typeof useToast>;
describe('useExecutionDebugging()', () => { describe('useExecutionDebugging()', () => {
beforeEach(() => {
vi.clearAllMocks();
createTestingPinia();
executionDebugging = useExecutionDebugging();
toast = useToast();
});
it('should not throw when runData node is an empty array', async () => {
const mockExecution = {
data: {
resultData: {
runData: {
testNode: [],
},
},
},
} as unknown as IExecutionResponse;
const workflowStore = mockedStore(useWorkflowsStore);
workflowStore.getNodes.mockReturnValue([{ name: 'testNode' }] as INodeUi[]);
workflowStore.getExecution.mockResolvedValueOnce(mockExecution);
workflowStore.getCurrentWorkflow.mockReturnValue({
pinData: {},
getParentNodes: vi.fn().mockReturnValue([]),
} as unknown as Workflow);
await expect(executionDebugging.applyExecutionData('1')).resolves.not.toThrowError();
});
it('should show missing nodes warning toast', async () => {
const mockExecution = {
data: {
resultData: {
runData: {
testNode: [
{
data: {},
},
],
},
},
},
} as unknown as IExecutionResponse;
const workflowStore = mockedStore(useWorkflowsStore);
workflowStore.getNodes.mockReturnValue([{ name: 'testNode2' }] as INodeUi[]);
workflowStore.getExecution.mockResolvedValueOnce(mockExecution);
workflowStore.getCurrentWorkflow.mockReturnValue({
pinData: {},
getParentNodes: vi.fn().mockReturnValue([]),
} as unknown as Workflow);
await executionDebugging.applyExecutionData('1');
expect(workflowStore.setWorkflowExecutionData).toHaveBeenCalledWith(mockExecution);
expect(toast.showToast).toHaveBeenCalledWith(expect.objectContaining({ type: 'info' }));
expect(toast.showToast).toHaveBeenCalledWith(expect.objectContaining({ type: 'warning' }));
});
it('should applyExecutionData', async () => { it('should applyExecutionData', async () => {
setActivePinia(createTestingPinia());
const mockExecution = { const mockExecution = {
data: { data: {
resultData: { resultData: {
@ -31,10 +101,9 @@ describe('useExecutionDebugging()', () => {
getParentNodes: vi.fn().mockReturnValue([]), getParentNodes: vi.fn().mockReturnValue([]),
} as unknown as Workflow); } as unknown as Workflow);
const { applyExecutionData } = useExecutionDebugging(); await executionDebugging.applyExecutionData('1');
await applyExecutionData('1');
expect(workflowStore.setWorkflowExecutionData).toHaveBeenCalledWith(mockExecution); expect(workflowStore.setWorkflowExecutionData).toHaveBeenCalledWith(mockExecution);
expect(toast.showToast).toHaveBeenCalledTimes(1);
}); });
}); });

View file

@ -108,7 +108,7 @@ export const useExecutionDebugging = () => {
let pinnings = 0; let pinnings = 0;
pinnableNodes.forEach((node: INodeUi) => { pinnableNodes.forEach((node: INodeUi) => {
const nodeData = runData[node.name]?.[0].data?.main?.[0]; const nodeData = runData[node.name]?.[0]?.data?.main?.[0];
if (nodeData) { if (nodeData) {
pinnings++; pinnings++;
workflowsStore.pinData({ workflowsStore.pinData({