diff --git a/app/client/src/ce/workers/Evaluation/Actions.ts b/app/client/src/ce/workers/Evaluation/Actions.ts index 0fdabdf8a0..429bc551cc 100644 --- a/app/client/src/ce/workers/Evaluation/Actions.ts +++ b/app/client/src/ce/workers/Evaluation/Actions.ts @@ -98,15 +98,21 @@ export const addDataTreeToContext = (args: { EVAL_CONTEXT, ); - // if eval is not trigger based i.e., sync eval then we skip adding entity and platform function to evalContext if (!isTriggerBased) return; + // if eval is not trigger based i.e., sync eval then we skip adding entity function to evalContext + addEntityFunctionsToEvalContext(EVAL_CONTEXT, entityFunctionCollection); +}; +export const addEntityFunctionsToEvalContext = ( + evalContext: EvalContext, + entityFunctionCollection: Record>, +) => { for (const [entityName, funcObj] of Object.entries( entityFunctionCollection, )) { - EVAL_CONTEXT[entityName] = Object.assign( + evalContext[entityName] = Object.assign( {}, - EVAL_CONTEXT[entityName], + evalContext[entityName], funcObj, ); } diff --git a/app/client/src/workers/Evaluation/fns/__tests__/index.test.ts b/app/client/src/workers/Evaluation/fns/__tests__/index.test.ts new file mode 100644 index 0000000000..cf6ea3f5a5 --- /dev/null +++ b/app/client/src/workers/Evaluation/fns/__tests__/index.test.ts @@ -0,0 +1,102 @@ +import { MAIN_THREAD_ACTION } from "@appsmith/workers/Evaluation/evalWorkerActions"; +import { addPlatformFunctionsToEvalContext } from "@appsmith/workers/Evaluation/Actions"; +import { setEvalContext } from "workers/Evaluation/evaluate"; +import type { DataTree } from "entities/DataTree/dataTreeTypes"; +import { ENTITY_TYPE } from "entities/DataTree/dataTreeFactory"; +import { RenderModes } from "constants/WidgetConstants"; + +const dataTree: DataTree = { + action1: { + actionId: "123", + data: {}, + config: {}, + datasourceUrl: "", + isLoading: false, + run: {}, + clear: {}, + responseMeta: { isExecutionSuccess: false }, + ENTITY_TYPE: ENTITY_TYPE.ACTION, + }, + WidgetName: { + widgetName: "WidgetName", + bottomRow: 0, + isLoading: false, + leftColumn: 0, + rightColumn: 0, + topRow: 0, + type: "TABLE_WIDGET", + version: 1, + dynamicBindingPathList: [], + ENTITY_TYPE: ENTITY_TYPE.WIDGET, + meta: {}, + widgetId: "sfwe", + renderMode: RenderModes.CANVAS, + parentColumnSpace: 3, + parentRowSpace: 4, + }, +}; + +jest.mock("workers/Evaluation/handlers/evalTree", () => ({ + get dataTreeEvaluator() { + return { + evalTree: dataTree, + }; + }, +})); + +const requestMock = jest.fn(); +jest.mock("../utils/Messenger.ts", () => ({ + ...jest.requireActual("../utils/Messenger.ts"), + get WorkerMessenger() { + return { + request: (...args: any) => requestMock(...args), + }; + }, +})); + +describe("Tests for entity function to be defined", () => { + beforeAll(() => { + self["$isDataField"] = false; + setEvalContext({ + dataTree: dataTree, + isTriggerBased: true, + isDataField: false, + }); + addPlatformFunctionsToEvalContext(self); + }); + + it("1. After resetWidget is executed", async () => { + requestMock.mockReturnValue( + Promise.resolve({ + data: ["resolved"], + }), + ); + const evalContext = globalThis as any; + evalContext.resetWidget("WidgetName", true); + + const successHandler = jest.fn(); + const invocation = evalContext.action1.run(); + invocation.then(successHandler); + expect(requestMock).toBeCalledWith({ + method: MAIN_THREAD_ACTION.PROCESS_TRIGGER, + data: { + enableJSFnPostProcessors: true, + enableJSVarUpdateTracking: true, + trigger: { + type: "RUN_PLUGIN_ACTION", + payload: { + actionId: "123", + params: {}, + }, + }, + triggerMeta: { + source: {}, + triggerPropertyName: undefined, + onPageLoad: false, + }, + }, + }); + await expect(invocation).resolves.toEqual("resolved"); + expect(successHandler).toBeCalledWith("resolved"); + }); +}); diff --git a/app/client/src/workers/Evaluation/fns/resetWidget.ts b/app/client/src/workers/Evaluation/fns/resetWidget.ts index 0d35c47b95..6a46177b37 100644 --- a/app/client/src/workers/Evaluation/fns/resetWidget.ts +++ b/app/client/src/workers/Evaluation/fns/resetWidget.ts @@ -15,7 +15,7 @@ import type { import { isWidget } from "@appsmith/workers/Evaluation/evaluationUtils"; import { klona } from "klona"; import { getDynamicBindings, isDynamicValue } from "utils/DynamicBindingUtils"; -import evaluateSync from "../evaluate"; +import evaluateSync, { setEvalContext } from "../evaluate"; import type { DescendantWidgetMap } from "sagas/WidgetOperationUtils"; import type { MetaState } from "reducers/entityReducers/metaReducer"; import type { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer"; @@ -126,6 +126,14 @@ function resetWidgetMetaProperty( finalValue = klona(expressionToEvaluate); } + // Switch back to async evaluation once done with sync tasks. + setEvalContext({ + dataTree: evalTree, + configTree: dataTreeEvaluator.getConfigTree(), + isDataField: false, + isTriggerBased: true, + }); + const parsedValue = validateAndParseWidgetProperty({ fullPropertyPath: `${widget.widgetName}.${defaultPropertyPath}`, widget: unEvalEntity,