mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix(core): Fix resuming executions on test webhooks from Wait forms (#13410)
This commit is contained in:
parent
4fa666b976
commit
8ffd3167d5
|
@ -1,12 +1,16 @@
|
||||||
|
import type express from 'express';
|
||||||
import { mock } from 'jest-mock-extended';
|
import { mock } from 'jest-mock-extended';
|
||||||
import { FORM_NODE_TYPE, type Workflow } from 'n8n-workflow';
|
import { FORM_NODE_TYPE, type Workflow } from 'n8n-workflow';
|
||||||
|
|
||||||
import type { ExecutionRepository } from '@/databases/repositories/execution.repository';
|
import type { ExecutionRepository } from '@/databases/repositories/execution.repository';
|
||||||
import { WaitingForms } from '@/webhooks/waiting-forms';
|
import { WaitingForms } from '@/webhooks/waiting-forms';
|
||||||
|
|
||||||
|
import type { IExecutionResponse } from '../../interfaces';
|
||||||
|
import type { WaitingWebhookRequest } from '../webhook.types';
|
||||||
|
|
||||||
describe('WaitingForms', () => {
|
describe('WaitingForms', () => {
|
||||||
const executionRepository = mock<ExecutionRepository>();
|
const executionRepository = mock<ExecutionRepository>();
|
||||||
const waitingWebhooks = new WaitingForms(mock(), mock(), executionRepository, mock());
|
const waitingForms = new WaitingForms(mock(), mock(), executionRepository, mock());
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.restoreAllMocks();
|
jest.restoreAllMocks();
|
||||||
|
@ -27,7 +31,7 @@ describe('WaitingForms', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = waitingWebhooks.findCompletionPage(workflow, {}, 'Form1');
|
const result = waitingForms.findCompletionPage(workflow, {}, 'Form1');
|
||||||
expect(result).toBe('Form1');
|
expect(result).toBe('Form1');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -45,7 +49,7 @@ describe('WaitingForms', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = waitingWebhooks.findCompletionPage(workflow, {}, 'Form1');
|
const result = waitingForms.findCompletionPage(workflow, {}, 'Form1');
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -61,7 +65,7 @@ describe('WaitingForms', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = waitingWebhooks.findCompletionPage(workflow, {}, 'NonForm');
|
const result = waitingForms.findCompletionPage(workflow, {}, 'NonForm');
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -79,7 +83,7 @@ describe('WaitingForms', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = waitingWebhooks.findCompletionPage(workflow, {}, 'Form1');
|
const result = waitingForms.findCompletionPage(workflow, {}, 'Form1');
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -121,7 +125,7 @@ describe('WaitingForms', () => {
|
||||||
Form3: [],
|
Form3: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = waitingWebhooks.findCompletionPage(workflow, runData, 'LastNode');
|
const result = waitingForms.findCompletionPage(workflow, runData, 'LastNode');
|
||||||
expect(result).toBe('Form3');
|
expect(result).toBe('Form3');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -151,7 +155,7 @@ describe('WaitingForms', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = waitingWebhooks.findCompletionPage(workflow, {}, 'LastNode');
|
const result = waitingForms.findCompletionPage(workflow, {}, 'LastNode');
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -192,8 +196,29 @@ describe('WaitingForms', () => {
|
||||||
Form2: [],
|
Form2: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = waitingWebhooks.findCompletionPage(workflow, runData, 'LastNode');
|
const result = waitingForms.findCompletionPage(workflow, runData, 'LastNode');
|
||||||
expect(result).toBe('Form2');
|
expect(result).toBe('Form2');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should mark as test form webhook when execution mode is manual', async () => {
|
||||||
|
jest
|
||||||
|
// @ts-expect-error Protected method
|
||||||
|
.spyOn(waitingForms, 'getWebhookExecutionData')
|
||||||
|
// @ts-expect-error Protected method
|
||||||
|
.mockResolvedValue(mock<IWebhookResponseCallbackData>());
|
||||||
|
|
||||||
|
const execution = mock<IExecutionResponse>({
|
||||||
|
finished: false,
|
||||||
|
mode: 'manual',
|
||||||
|
data: {
|
||||||
|
resultData: { lastNodeExecuted: 'someNode', error: undefined },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
executionRepository.findSingleExecution.mockResolvedValue(execution);
|
||||||
|
|
||||||
|
await waitingForms.executeWebhook(mock<WaitingWebhookRequest>(), mock<express.Response>());
|
||||||
|
|
||||||
|
expect(execution.data.isTestWebhook).toBe(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -116,6 +116,12 @@ export class WaitingForms extends WaitingWebhooks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A manual execution resumed by a webhook call needs to be marked as such
|
||||||
|
* so workers in scaling mode reuse the existing execution data.
|
||||||
|
*/
|
||||||
|
if (execution.mode === 'manual') execution.data.isTestWebhook = true;
|
||||||
|
|
||||||
return await this.getWebhookExecutionData({
|
return await this.getWebhookExecutionData({
|
||||||
execution,
|
execution,
|
||||||
req,
|
req,
|
||||||
|
|
Loading…
Reference in a new issue