From a58be175cc8a65975b7aac15fc3143c38cf3682b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Ovejero?= Date: Fri, 24 May 2024 11:00:15 +0200 Subject: [PATCH] fix(core): Prevent re-parsing of dynamically loaded options (#9503) --- .../dynamicNodeParameters.controller.ts | 3 +- packages/cli/src/requests.ts | 9 ++--- ...dynamic-node-parameters.controller.test.ts | 2 +- ...dynamic-node-parameters.controller.test.ts | 33 +++++++++++++++++++ 4 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 packages/cli/test/unit/controllers/dynamic-node-parameters.controller.test.ts diff --git a/packages/cli/src/controllers/dynamicNodeParameters.controller.ts b/packages/cli/src/controllers/dynamicNodeParameters.controller.ts index 355906eff..c6a46aa3d 100644 --- a/packages/cli/src/controllers/dynamicNodeParameters.controller.ts +++ b/packages/cli/src/controllers/dynamicNodeParameters.controller.ts @@ -1,5 +1,4 @@ import type { INodePropertyOptions } from 'n8n-workflow'; -import { jsonParse } from 'n8n-workflow'; import { Post, RestController } from '@/decorators'; import { getBase } from '@/WorkflowExecuteAdditionalData'; @@ -37,7 +36,7 @@ export class DynamicNodeParametersController { if (loadOptions) { return await this.service.getOptionsViaLoadOptions( - jsonParse(loadOptions), + loadOptions, additionalData, nodeTypeAndVersion, currentNodeParameters, diff --git a/packages/cli/src/requests.ts b/packages/cli/src/requests.ts index 60b4f3858..20679b3d2 100644 --- a/packages/cli/src/requests.ts +++ b/packages/cli/src/requests.ts @@ -3,6 +3,7 @@ import type { BannerName, ICredentialDataDecryptedObject, IDataObject, + ILoadOptions, INodeCredentialTestRequest, INodeCredentials, INodeParameters, @@ -406,19 +407,19 @@ export declare namespace DynamicNodeParametersRequest { {} >; - /** GET /dynamic-node-parameters/options */ + /** POST /dynamic-node-parameters/options */ type Options = BaseRequest<{ - loadOptions?: string; + loadOptions?: ILoadOptions; }>; - /** GET /dynamic-node-parameters/resource-locator-results */ + /** POST /dynamic-node-parameters/resource-locator-results */ type ResourceLocatorResults = BaseRequest<{ methodName: string; filter?: string; paginationToken?: string; }>; - /** GET dynamic-node-parameters/resource-mapper-fields */ + /** POST dynamic-node-parameters/resource-mapper-fields */ type ResourceMapperFields = BaseRequest<{ methodName: string; }>; diff --git a/packages/cli/test/integration/controllers/dynamic-node-parameters.controller.test.ts b/packages/cli/test/integration/controllers/dynamic-node-parameters.controller.test.ts index e9ff422c0..e28e83a70 100644 --- a/packages/cli/test/integration/controllers/dynamic-node-parameters.controller.test.ts +++ b/packages/cli/test/integration/controllers/dynamic-node-parameters.controller.test.ts @@ -39,7 +39,7 @@ describe('DynamicNodeParametersController', () => { .post('/dynamic-node-parameters/options') .send({ ...commonRequestParams, - loadOptions: 'loadOptions', + loadOptions: {}, }) .expect(200); }); diff --git a/packages/cli/test/unit/controllers/dynamic-node-parameters.controller.test.ts b/packages/cli/test/unit/controllers/dynamic-node-parameters.controller.test.ts new file mode 100644 index 000000000..fe1313a4e --- /dev/null +++ b/packages/cli/test/unit/controllers/dynamic-node-parameters.controller.test.ts @@ -0,0 +1,33 @@ +import { DynamicNodeParametersController } from '@/controllers/dynamicNodeParameters.controller'; +import type { DynamicNodeParametersRequest } from '@/requests'; +import type { DynamicNodeParametersService } from '@/services/dynamicNodeParameters.service'; +import { mock } from 'jest-mock-extended'; +import * as AdditionalData from '@/WorkflowExecuteAdditionalData'; +import type { ILoadOptions, IWorkflowExecuteAdditionalData } from 'n8n-workflow'; + +describe('DynamicNodeParametersController', () => { + const service = mock(); + const controller = new DynamicNodeParametersController(service); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('getOptions', () => { + it('should take `loadOptions` as object', async () => { + jest + .spyOn(AdditionalData, 'getBase') + .mockResolvedValue(mock()); + + const req = mock(); + const loadOptions: ILoadOptions = {}; + req.body.loadOptions = loadOptions; + + await controller.getOptions(req); + + const zerothArg = service.getOptionsViaLoadOptions.mock.calls[0][0]; + + expect(zerothArg).toEqual(loadOptions); + }); + }); +});