mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-21 02:56:40 -08:00
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
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:
parent
6af9c82af6
commit
67aa0c9107
|
@ -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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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({
|
||||||
|
|
Loading…
Reference in a new issue