PromucFlow_constructor/app/client/src/sagas/EvaluationsSaga.test.ts

204 lines
7.9 KiB
TypeScript
Raw Normal View History

import {
defaultAffectedJSObjects,
evalQueueBuffer,
evaluateTreeSaga,
evalWorker,
} from "./EvaluationsSaga";
import { expectSaga } from "redux-saga-test-plan";
import { EVAL_WORKER_ACTIONS } from "@appsmith/workers/Evaluation/evalWorkerActions";
import { select } from "redux-saga/effects";
import { getMetaWidgets, getWidgets, getWidgetsMeta } from "./selectors";
import { getAllActionValidationConfig } from "@appsmith//selectors/entitiesSelector";
import { getSelectedAppTheme } from "selectors/appThemingSelectors";
import { getAppMode } from "@appsmith/selectors/applicationSelectors";
import * as log from "loglevel";
import type { ReduxAction } from "@appsmith/constants/ReduxActionConstants";
import {
ReduxActionErrorTypes,
ReduxActionTypes,
} from "@appsmith/constants/ReduxActionConstants";
import { fetchPluginFormConfigsSuccess } from "actions/pluginActions";
import { createJSCollectionSuccess } from "actions/jsActionActions";
jest.mock("loglevel");
describe("evaluateTreeSaga", () => {
afterAll(() => {
jest.unmock("loglevel");
});
test("should set 'shouldRespondWithLogs'to evaluations when the log level is debug", async () => {
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(log.getLevel as any).mockReturnValue(log.levels.DEBUG);
const unEvalAndConfigTree = { unEvalTree: {}, configTree: {} };
return expectSaga(evaluateTreeSaga, unEvalAndConfigTree)
.provide([
[select(getAllActionValidationConfig), {}],
[select(getWidgets), {}],
[select(getMetaWidgets), {}],
[select(getSelectedAppTheme), {}],
[select(getAppMode), false],
[select(getWidgetsMeta), {}],
])
.call(evalWorker.request, EVAL_WORKER_ACTIONS.EVAL_TREE, {
unevalTree: unEvalAndConfigTree,
widgetTypeConfigMap: undefined,
widgets: {},
theme: {},
shouldReplay: true,
allActionValidationConfig: {},
forceEvaluation: false,
metaWidgets: {},
appMode: false,
widgetsMeta: {},
shouldRespondWithLogs: true,
affectedJSObjects: { ids: [], isAllAffected: false },
})
.run();
});
test("should set 'shouldRespondWithLogs' to false when the log level is not debug", async () => {
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(log.getLevel as any).mockReturnValue(log.levels.INFO);
const unEvalAndConfigTree = { unEvalTree: {}, configTree: {} };
return expectSaga(evaluateTreeSaga, unEvalAndConfigTree)
.provide([
[select(getAllActionValidationConfig), {}],
[select(getWidgets), {}],
[select(getMetaWidgets), {}],
[select(getSelectedAppTheme), {}],
[select(getAppMode), false],
[select(getWidgetsMeta), {}],
])
.call(evalWorker.request, EVAL_WORKER_ACTIONS.EVAL_TREE, {
unevalTree: unEvalAndConfigTree,
widgetTypeConfigMap: undefined,
widgets: {},
theme: {},
shouldReplay: true,
allActionValidationConfig: {},
forceEvaluation: false,
metaWidgets: {},
appMode: false,
widgetsMeta: {},
shouldRespondWithLogs: false,
affectedJSObjects: { ids: [], isAllAffected: false },
})
.run();
});
test("should propagate affectedJSObjects property to evaluation action", async () => {
const unEvalAndConfigTree = { unEvalTree: {}, configTree: {} };
const affectedJSObjects = {
isAllAffected: false,
ids: ["1", "2"],
};
return expectSaga(
evaluateTreeSaga,
unEvalAndConfigTree,
[],
undefined,
undefined,
undefined,
affectedJSObjects,
)
.provide([
[select(getAllActionValidationConfig), {}],
[select(getWidgets), {}],
[select(getMetaWidgets), {}],
[select(getSelectedAppTheme), {}],
[select(getAppMode), false],
[select(getWidgetsMeta), {}],
])
.call(evalWorker.request, EVAL_WORKER_ACTIONS.EVAL_TREE, {
unevalTree: unEvalAndConfigTree,
widgetTypeConfigMap: undefined,
widgets: {},
theme: {},
shouldReplay: true,
allActionValidationConfig: {},
forceEvaluation: false,
metaWidgets: {},
appMode: false,
widgetsMeta: {},
shouldRespondWithLogs: false,
affectedJSObjects,
})
.run();
});
});
describe("evalQueueBuffer", () => {
test("should return a buffered action with the default affectedJSObjects state for an action which does not have affectedJSObjects associated to it", () => {
const buffer = evalQueueBuffer();
// this action does not generate an affectedJSObject
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
buffer.put(fetchPluginFormConfigsSuccess({} as any));
const bufferedAction = buffer.take();
expect(bufferedAction).toEqual({
type: ReduxActionTypes.BUFFERED_ACTION,
affectedJSObjects: defaultAffectedJSObjects,
postEvalActions: [],
});
});
test("should club all JS actions affectedJSObjects's ids", () => {
const buffer = evalQueueBuffer();
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
buffer.put(createJSCollectionSuccess({ id: "1" } as any));
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
buffer.put(createJSCollectionSuccess({ id: "2" } as any));
const bufferedAction = buffer.take();
expect(bufferedAction).toEqual({
type: ReduxActionTypes.BUFFERED_ACTION,
affectedJSObjects: { ids: ["1", "2"], isAllAffected: false },
postEvalActions: [],
});
});
test("should return all JS actions that have changed when there is a pending action which affects all JS actions ", () => {
const buffer = evalQueueBuffer();
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
buffer.put(createJSCollectionSuccess({ id: "1" } as any));
// this action triggers an isAllAffected flag
buffer.put({
type: ReduxActionErrorTypes.FETCH_JS_ACTIONS_ERROR,
} as ReduxAction<unknown>);
// queue is not empty
expect(buffer.isEmpty()).not.toBeTruthy();
const bufferedAction = buffer.take();
expect(bufferedAction).toEqual({
type: ReduxActionTypes.BUFFERED_ACTION,
affectedJSObjects: { ids: [], isAllAffected: true },
postEvalActions: [],
});
expect(buffer.isEmpty()).toBeTruthy();
});
test("should reset the collectedAffectedJSObjects after the buffered action has been dequeued and the subsequent actions should have the defaultAffectedJSObjects", () => {
const buffer = evalQueueBuffer();
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
buffer.put(createJSCollectionSuccess({ id: "1" } as any));
const bufferedAction = buffer.take();
expect(bufferedAction).toEqual({
type: ReduxActionTypes.BUFFERED_ACTION,
affectedJSObjects: { ids: ["1"], isAllAffected: false },
postEvalActions: [],
});
expect(buffer.isEmpty()).toBeTruthy();
// this action does not generate an affectedJSObject, So the subsequent buffered action should have default affectedJSObjects
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
buffer.put(fetchPluginFormConfigsSuccess({ id: "1" } as any));
const bufferedActionsWithDefaultAffectedJSObjects = buffer.take();
expect(bufferedActionsWithDefaultAffectedJSObjects).toEqual({
type: ReduxActionTypes.BUFFERED_ACTION,
affectedJSObjects: defaultAffectedJSObjects,
postEvalActions: [],
});
});
});