Fix content type switching to raw when custom
This commit is contained in:
parent
8d4a223dd5
commit
ff2f32290f
|
|
@ -107,13 +107,13 @@
|
||||||
"build": "./build.sh",
|
"build": "./build.sh",
|
||||||
"build-local": "craco --max-old-space-size=4096 build --config craco.build.config.js",
|
"build-local": "craco --max-old-space-size=4096 build --config craco.build.config.js",
|
||||||
"build-staging": "REACT_APP_BASE_URL=https://release-api.appsmith.com REACT_APP_ENVIRONMENT=STAGING craco --max-old-space-size=4096 build --config craco.build.config.js",
|
"build-staging": "REACT_APP_BASE_URL=https://release-api.appsmith.com REACT_APP_ENVIRONMENT=STAGING craco --max-old-space-size=4096 build --config craco.build.config.js",
|
||||||
"test": "cypress/test.sh",
|
"test": "npm run test-jest && cypress/test.sh",
|
||||||
"eject": "react-scripts eject",
|
"eject": "react-scripts eject",
|
||||||
"start-prod": "REACT_APP_BASE_URL=https://api.appsmith.com REACT_APP_ENVIRONMENT=PRODUCTION craco start",
|
"start-prod": "REACT_APP_BASE_URL=https://api.appsmith.com REACT_APP_ENVIRONMENT=PRODUCTION craco start",
|
||||||
"storybook": "start-storybook",
|
"storybook": "start-storybook",
|
||||||
"cytest": "REACT_APP_TESTING=TESTING REACT_APP_ENVIRONMENT=DEVELOPMENT craco start & ./node_modules/.bin/cypress open",
|
"cytest": "REACT_APP_TESTING=TESTING REACT_APP_ENVIRONMENT=DEVELOPMENT craco start & ./node_modules/.bin/cypress open",
|
||||||
"build-storybook": "build-storybook -c .storybook -o .storybook-out",
|
"build-storybook": "build-storybook -c .storybook -o .storybook-out",
|
||||||
"test-jest": "./node_modules/jest/bin/jest.js -b"
|
"test-jest": "./node_modules/jest/bin/jest.js -b --colors"
|
||||||
},
|
},
|
||||||
"resolution": {
|
"resolution": {
|
||||||
"jest": "24.8.0"
|
"jest": "24.8.0"
|
||||||
|
|
|
||||||
|
|
@ -125,17 +125,16 @@ const PostBodyData = (props: Props) => {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{displayFormat?.value === POST_BODY_FORMAT_OPTIONS[2].value && (
|
{displayFormat?.value === POST_BODY_FORMAT_OPTIONS[2].value && (
|
||||||
<Field
|
<React.Fragment>
|
||||||
name="actionConfiguration.body[2]"
|
<JSONEditorFieldWrapper>
|
||||||
component="textarea"
|
<DynamicTextField
|
||||||
rows={10}
|
name="actionConfiguration.body[2]"
|
||||||
style={{
|
height={300}
|
||||||
resize: "none",
|
allowTabIndent
|
||||||
overflow: "auto",
|
singleLine={false}
|
||||||
width: "95%",
|
/>
|
||||||
marginLeft: 5,
|
</JSONEditorFieldWrapper>
|
||||||
}}
|
</React.Fragment>
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
</PostbodyContainer>
|
</PostbodyContainer>
|
||||||
);
|
);
|
||||||
|
|
@ -172,7 +171,7 @@ export default connect((state: AppState) => {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
displayFormat:
|
displayFormat:
|
||||||
extraFormData["displayFormat"] || POST_BODY_FORMAT_OPTIONS[0],
|
extraFormData["displayFormat"] || POST_BODY_FORMAT_OPTIONS[2],
|
||||||
contentType,
|
contentType,
|
||||||
apiId,
|
apiId,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -460,9 +460,7 @@ export function* updateActionSaga(
|
||||||
const { data } = actionPayload.payload;
|
const { data } = actionPayload.payload;
|
||||||
let action = data;
|
let action = data;
|
||||||
if (isApi) {
|
if (isApi) {
|
||||||
const state = yield select();
|
action = transformRestAction(data);
|
||||||
const extraFormData = state.ui.apiPane.extraformData[action.id];
|
|
||||||
action = transformRestAction(data, extraFormData);
|
|
||||||
}
|
}
|
||||||
const response: GenericApiResponse<RestAction> = yield ActionAPI.updateAPI(
|
const response: GenericApiResponse<RestAction> = yield ActionAPI.updateAPI(
|
||||||
action,
|
action,
|
||||||
|
|
|
||||||
|
|
@ -1,68 +1,57 @@
|
||||||
import {
|
import { HTTP_METHODS, POST_BODY_FORMATS } from "constants/ApiEditorConstants";
|
||||||
HTTP_METHODS,
|
import _ from "lodash";
|
||||||
POST_BODY_FORMAT_OPTIONS,
|
|
||||||
} from "constants/ApiEditorConstants";
|
|
||||||
|
|
||||||
export const transformRestAction = (data: any, extraFormData?: any): any => {
|
export const transformRestAction = (data: any): any => {
|
||||||
let action = { ...data };
|
let action = { ...data };
|
||||||
if (data.actionConfiguration.httpMethod === HTTP_METHODS[0]) {
|
// GET actions should not save body
|
||||||
|
if (action.actionConfiguration.httpMethod === HTTP_METHODS[0]) {
|
||||||
delete action.actionConfiguration.body;
|
delete action.actionConfiguration.body;
|
||||||
}
|
}
|
||||||
|
// Paths should not have query params
|
||||||
if (
|
if (
|
||||||
data.actionConfiguration.queryParameters &&
|
action.actionConfiguration.queryParameters &&
|
||||||
data.actionConfiguration.queryParameters.length
|
action.actionConfiguration.queryParameters.length
|
||||||
) {
|
) {
|
||||||
const path = data.actionConfiguration.path;
|
const path = action.actionConfiguration.path;
|
||||||
if (path && path.indexOf("?") > -1) {
|
if (path && path.indexOf("?") > -1) {
|
||||||
action = {
|
action = {
|
||||||
...data,
|
...action,
|
||||||
actionConfiguration: {
|
actionConfiguration: {
|
||||||
...data.actionConfiguration,
|
...action.actionConfiguration,
|
||||||
path: path.substr(0, path.indexOf("?")),
|
path: path.substr(0, path.indexOf("?")),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Body should send correct format depending on the content type
|
||||||
if (extraFormData && extraFormData?.displayFormat) {
|
if (action.actionConfiguration.httpMethod !== HTTP_METHODS[0]) {
|
||||||
const { displayFormat } = extraFormData;
|
let contentType = "raw";
|
||||||
|
if (
|
||||||
if (displayFormat.value === POST_BODY_FORMAT_OPTIONS[0].value) {
|
action.actionConfiguration.headers &&
|
||||||
if (data.actionConfiguration.body && data.actionConfiguration.body[0]) {
|
action.actionConfiguration.headers.length
|
||||||
const body = data.actionConfiguration.body[0];
|
) {
|
||||||
action = {
|
const contentTypeHeader = _.find(action.actionConfiguration.headers, {
|
||||||
...data,
|
key: "content-type",
|
||||||
actionConfiguration: {
|
});
|
||||||
...data.actionConfiguration,
|
if (contentTypeHeader) {
|
||||||
body,
|
contentType = contentTypeHeader.value;
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else if (displayFormat.value === POST_BODY_FORMAT_OPTIONS[1].value) {
|
|
||||||
if (data.actionConfiguration.body && data.actionConfiguration.body[1]) {
|
|
||||||
const body = data.actionConfiguration.body[1];
|
|
||||||
if (typeof data.actionConfiguration.body === "object") {
|
|
||||||
action = {
|
|
||||||
...data,
|
|
||||||
actionConfiguration: {
|
|
||||||
...data.actionConfiguration,
|
|
||||||
body: JSON.stringify(body),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (displayFormat.value === POST_BODY_FORMAT_OPTIONS[2].value) {
|
|
||||||
if (data.actionConfiguration.body && data.actionConfiguration.body[2]) {
|
|
||||||
const body = data.actionConfiguration.body[2];
|
|
||||||
action = {
|
|
||||||
...data,
|
|
||||||
actionConfiguration: {
|
|
||||||
...data.actionConfiguration,
|
|
||||||
body,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let formatIndex = 2;
|
||||||
|
if (POST_BODY_FORMATS.includes(contentType)) {
|
||||||
|
formatIndex = POST_BODY_FORMATS.indexOf(contentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
let body = action.actionConfiguration.body[formatIndex] || undefined;
|
||||||
|
if (!_.isString(body)) body = JSON.stringify(body);
|
||||||
|
action = {
|
||||||
|
...action,
|
||||||
|
actionConfiguration: {
|
||||||
|
...action.actionConfiguration,
|
||||||
|
body,
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return action;
|
return action;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,9 @@
|
||||||
import { transformRestAction } from "transformers/RestActionTransformer";
|
import { transformRestAction } from "transformers/RestActionTransformer";
|
||||||
import { RestAction } from "api/ActionAPI";
|
import { RestAction } from "api/ActionAPI";
|
||||||
|
|
||||||
const input: RestAction = {
|
// jest.mock("POST_");
|
||||||
pageId: "",
|
|
||||||
pluginId: "",
|
|
||||||
id: "testId",
|
|
||||||
datasource: {
|
|
||||||
id: "testDataSource",
|
|
||||||
},
|
|
||||||
name: "testName",
|
|
||||||
pluginType: "API",
|
|
||||||
actionConfiguration: {
|
|
||||||
path: "users?page=1",
|
|
||||||
queryParameters: [
|
|
||||||
{
|
|
||||||
key: "page",
|
|
||||||
value: "1",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
jsonPathKeys: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
const output = {
|
const BASE_ACTION: RestAction = {
|
||||||
pageId: "",
|
pageId: "",
|
||||||
pluginId: "",
|
pluginId: "",
|
||||||
id: "testId",
|
id: "testId",
|
||||||
|
|
@ -32,18 +13,135 @@ const output = {
|
||||||
name: "testName",
|
name: "testName",
|
||||||
pluginType: "API",
|
pluginType: "API",
|
||||||
actionConfiguration: {
|
actionConfiguration: {
|
||||||
|
httpMethod: "GET",
|
||||||
path: "users",
|
path: "users",
|
||||||
queryParameters: [
|
|
||||||
{
|
|
||||||
key: "page",
|
|
||||||
value: "1",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
jsonPathKeys: [],
|
jsonPathKeys: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
it("Transform the input", () => {
|
describe("Api action transformer", () => {
|
||||||
const result = transformRestAction(input);
|
it("Removes params from path", () => {
|
||||||
expect(result).toEqual(output);
|
const input: RestAction = {
|
||||||
|
...BASE_ACTION,
|
||||||
|
actionConfiguration: {
|
||||||
|
...BASE_ACTION.actionConfiguration,
|
||||||
|
path: "users?page=1",
|
||||||
|
queryParameters: [
|
||||||
|
{
|
||||||
|
key: "page",
|
||||||
|
value: "1",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const output = {
|
||||||
|
...BASE_ACTION,
|
||||||
|
actionConfiguration: {
|
||||||
|
...BASE_ACTION.actionConfiguration,
|
||||||
|
path: "users",
|
||||||
|
queryParameters: [
|
||||||
|
{
|
||||||
|
key: "page",
|
||||||
|
value: "1",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const result = transformRestAction(input);
|
||||||
|
expect(result).toEqual(output);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("removes body for GET calls", () => {
|
||||||
|
const input = {
|
||||||
|
...BASE_ACTION,
|
||||||
|
actionConfiguration: {
|
||||||
|
...BASE_ACTION.actionConfiguration,
|
||||||
|
httpMethod: "GET",
|
||||||
|
body: [null, null],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const output = {
|
||||||
|
...BASE_ACTION,
|
||||||
|
actionConfiguration: {
|
||||||
|
...BASE_ACTION.actionConfiguration,
|
||||||
|
httpMethod: "GET",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const result = transformRestAction(input);
|
||||||
|
expect(result).toEqual(output);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Sets the correct body for JSON display type", () => {
|
||||||
|
const input = {
|
||||||
|
...BASE_ACTION,
|
||||||
|
actionConfiguration: {
|
||||||
|
...BASE_ACTION.actionConfiguration,
|
||||||
|
httpMethod: "POST",
|
||||||
|
headers: [{ key: "content-type", value: "application/json" }],
|
||||||
|
body: ["{ name: 'test' }", null],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const output = {
|
||||||
|
...BASE_ACTION,
|
||||||
|
actionConfiguration: {
|
||||||
|
...BASE_ACTION.actionConfiguration,
|
||||||
|
httpMethod: "POST",
|
||||||
|
headers: [{ key: "content-type", value: "application/json" }],
|
||||||
|
body: "{ name: 'test' }",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const result = transformRestAction(input);
|
||||||
|
expect(result).toEqual(output);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Sets the correct body for xxx-form-encoded-data display type", () => {
|
||||||
|
const input = {
|
||||||
|
...BASE_ACTION,
|
||||||
|
actionConfiguration: {
|
||||||
|
...BASE_ACTION.actionConfiguration,
|
||||||
|
httpMethod: "POST",
|
||||||
|
headers: [
|
||||||
|
{ key: "content-type", value: "application/x-www-form-urlencoded" },
|
||||||
|
],
|
||||||
|
body: [{ name: "test" }, [{ key: "hey", value: "ho" }]],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const output = {
|
||||||
|
...BASE_ACTION,
|
||||||
|
actionConfiguration: {
|
||||||
|
...BASE_ACTION.actionConfiguration,
|
||||||
|
httpMethod: "POST",
|
||||||
|
headers: [
|
||||||
|
{ key: "content-type", value: "application/x-www-form-urlencoded" },
|
||||||
|
],
|
||||||
|
body: '[{"key":"hey","value":"ho"}]',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const result = transformRestAction(input);
|
||||||
|
expect(result).toEqual(output);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Sets the correct body for custom/raw display type", () => {
|
||||||
|
const input = {
|
||||||
|
...BASE_ACTION,
|
||||||
|
actionConfiguration: {
|
||||||
|
...BASE_ACTION.actionConfiguration,
|
||||||
|
headers: [{ key: "content-type", value: "text/html" }],
|
||||||
|
httpMethod: "POST",
|
||||||
|
body: [{ name: "test" }, [{ key: "hey", value: "ho" }], "raw body"],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const output = {
|
||||||
|
...BASE_ACTION,
|
||||||
|
actionConfiguration: {
|
||||||
|
...BASE_ACTION.actionConfiguration,
|
||||||
|
headers: [{ key: "content-type", value: "text/html" }],
|
||||||
|
httpMethod: "POST",
|
||||||
|
body: "raw body",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const result = transformRestAction(input);
|
||||||
|
expect(result).toEqual(output);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,214 +1,220 @@
|
||||||
// import RealmExecutor from "jsExecution/RealmExecutor";
|
// // import RealmExecutor from "jsExecution/RealmExecutor";
|
||||||
import {
|
// import {
|
||||||
mockExecute,
|
// mockExecute,
|
||||||
mockRegisterLibrary,
|
// mockRegisterLibrary,
|
||||||
} from "../../test/__mocks__/RealmExecutorMock";
|
// } from "../../test/__mocks__/RealmExecutorMock";
|
||||||
import {
|
// import {
|
||||||
dependencySortedEvaluateDataTree,
|
// dependencySortedEvaluateDataTree,
|
||||||
getDynamicValue,
|
// getDynamicValue,
|
||||||
getEntityDependencies,
|
// getEntityDependencies,
|
||||||
parseDynamicString,
|
// parseDynamicString,
|
||||||
} from "./DynamicBindingUtils";
|
// } from "./DynamicBindingUtils";
|
||||||
import { DataTree, ENTITY_TYPE } from "entities/DataTree/dataTreeFactory";
|
// import { DataTree, ENTITY_TYPE } from "entities/DataTree/dataTreeFactory";
|
||||||
import { RenderModes, WidgetTypes } from "constants/WidgetConstants";
|
// import { RenderModes, WidgetTypes } from "constants/WidgetConstants";
|
||||||
|
//
|
||||||
|
// jest.mock("jsExecution/RealmExecutor", () => {
|
||||||
|
// return jest.fn().mockImplementation(() => {
|
||||||
|
// return { execute: mockExecute, registerLibrary: mockRegisterLibrary };
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// beforeAll(() => {
|
||||||
|
// mockRegisterLibrary.mockClear();
|
||||||
|
// mockExecute.mockClear();
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// it("Gets the value from the data tree", () => {
|
||||||
|
// const dynamicBinding = "{{GetUsers.data}}";
|
||||||
|
// const nameBindingsWithData: DataTree = {
|
||||||
|
// GetUsers: {
|
||||||
|
// data: { text: "correct data" },
|
||||||
|
// config: {
|
||||||
|
// pluginId: "",
|
||||||
|
// id: "id",
|
||||||
|
// name: "text",
|
||||||
|
// actionConfiguration: {},
|
||||||
|
// pageId: "",
|
||||||
|
// jsonPathKeys: [],
|
||||||
|
// datasource: { id: "" },
|
||||||
|
// pluginType: "1",
|
||||||
|
// },
|
||||||
|
// isLoading: false,
|
||||||
|
// ENTITY_TYPE: ENTITY_TYPE.ACTION,
|
||||||
|
// run: jest.fn(),
|
||||||
|
// },
|
||||||
|
// };
|
||||||
|
// const actualValue = { result: { text: "correct data" } };
|
||||||
|
//
|
||||||
|
// const value = getDynamicValue(dynamicBinding, nameBindingsWithData);
|
||||||
|
//
|
||||||
|
// expect(value).toEqual(actualValue);
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// describe.each([
|
||||||
|
// ["{{A}}", ["{{A}}"]],
|
||||||
|
// ["A {{B}}", ["A ", "{{B}}"]],
|
||||||
|
// [
|
||||||
|
// "Hello {{Customer.Name}}, the status for your order id {{orderId}} is {{status}}",
|
||||||
|
// [
|
||||||
|
// "Hello ",
|
||||||
|
// "{{Customer.Name}}",
|
||||||
|
// ", the status for your order id ",
|
||||||
|
// "{{orderId}}",
|
||||||
|
// " is ",
|
||||||
|
// "{{status}}",
|
||||||
|
// ],
|
||||||
|
// ],
|
||||||
|
// [
|
||||||
|
// "{{data.map(datum => {return {id: datum}})}}",
|
||||||
|
// ["{{data.map(datum => {return {id: datum}})}}"],
|
||||||
|
// ],
|
||||||
|
// ["{{}}{{}}}", ["{{}}", "{{}}", "}"]],
|
||||||
|
// ["{{{}}", ["{{{}}"]],
|
||||||
|
// ["{{ {{", ["{{ {{"]],
|
||||||
|
// ["}} }}", ["}} }}"]],
|
||||||
|
// ["}} {{", ["}} {{"]],
|
||||||
|
// ])("Parse the dynamic string(%s, %j)", (dynamicString, expected) => {
|
||||||
|
// test(`returns ${expected}`, () => {
|
||||||
|
// expect(parseDynamicString(dynamicString as string)).toStrictEqual(expected);
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// const baseWidgetProps = {
|
||||||
|
// parentColumnSpace: 0,
|
||||||
|
// parentRowSpace: 0,
|
||||||
|
// parentId: "0",
|
||||||
|
// type: WidgetTypes.BUTTON_WIDGET,
|
||||||
|
// renderMode: RenderModes.CANVAS,
|
||||||
|
// leftColumn: 0,
|
||||||
|
// rightColumn: 0,
|
||||||
|
// topRow: 0,
|
||||||
|
// bottomRow: 0,
|
||||||
|
// isLoading: false,
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// it("evaluates the data tree", () => {
|
||||||
|
// const input: DataTree = {
|
||||||
|
// widget1: {
|
||||||
|
// ...baseWidgetProps,
|
||||||
|
// widgetId: "1",
|
||||||
|
// widgetName: "widget1",
|
||||||
|
// displayValue: "{{widget2.computedProperty}}",
|
||||||
|
// ENTITY_TYPE: ENTITY_TYPE.WIDGET,
|
||||||
|
// },
|
||||||
|
// widget2: {
|
||||||
|
// ...baseWidgetProps,
|
||||||
|
// widgetId: "2",
|
||||||
|
// widgetName: "widget2",
|
||||||
|
// computedProperty: "{{ widget2.data[widget2.index] }}",
|
||||||
|
// data: "{{ apiData.data }}",
|
||||||
|
// index: 2,
|
||||||
|
// ENTITY_TYPE: ENTITY_TYPE.WIDGET,
|
||||||
|
// },
|
||||||
|
// apiData: {
|
||||||
|
// config: {
|
||||||
|
// id: "123",
|
||||||
|
// pageId: "1234",
|
||||||
|
// datasource: {},
|
||||||
|
// name: "api",
|
||||||
|
// actionConfiguration: {},
|
||||||
|
// jsonPathKeys: [],
|
||||||
|
// pluginId: "plugin",
|
||||||
|
// },
|
||||||
|
// run: (onSuccess, onError) => ({
|
||||||
|
// type: "RUN_ACTION",
|
||||||
|
// payload: {
|
||||||
|
// actionId: "",
|
||||||
|
// onSuccess: "",
|
||||||
|
// onError: "",
|
||||||
|
// },
|
||||||
|
// }),
|
||||||
|
// isLoading: false,
|
||||||
|
// data: ["wrong value", "still wrong", "correct"],
|
||||||
|
// ENTITY_TYPE: ENTITY_TYPE.ACTION,
|
||||||
|
// },
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// const dynamicBindings = {
|
||||||
|
// "widget1.displayValue": ["widget2.computedProperty"],
|
||||||
|
// "widget2.computedProperty": ["widget2.data", "widget2.index"],
|
||||||
|
// "widget2.data": ["apiData.data"],
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// const sortedDeps = [
|
||||||
|
// "apiData.data",
|
||||||
|
// "widget2.data",
|
||||||
|
// "widget2.index",
|
||||||
|
// "widget2.computedProperty",
|
||||||
|
// "widget1.displayValue",
|
||||||
|
// ];
|
||||||
|
//
|
||||||
|
// const output: DataTree = {
|
||||||
|
// widget1: {
|
||||||
|
// ...baseWidgetProps,
|
||||||
|
// widgetId: "1",
|
||||||
|
// widgetName: "widget1",
|
||||||
|
// displayValue: "correct",
|
||||||
|
// ENTITY_TYPE: ENTITY_TYPE.WIDGET,
|
||||||
|
// },
|
||||||
|
// widget2: {
|
||||||
|
// ...baseWidgetProps,
|
||||||
|
// widgetId: "2",
|
||||||
|
// widgetName: "widget2",
|
||||||
|
// computedProperty: "correct",
|
||||||
|
// data: ["wrong value", "still wrong", "correct"],
|
||||||
|
// index: 2,
|
||||||
|
// ENTITY_TYPE: ENTITY_TYPE.WIDGET,
|
||||||
|
// },
|
||||||
|
// apiData: {
|
||||||
|
// config: {
|
||||||
|
// id: "123",
|
||||||
|
// pageId: "1234",
|
||||||
|
// datasource: {},
|
||||||
|
// name: "api",
|
||||||
|
// actionConfiguration: {},
|
||||||
|
// jsonPathKeys: [],
|
||||||
|
// pluginId: "plugin",
|
||||||
|
// },
|
||||||
|
// run: (onSuccess, onError) => ({
|
||||||
|
// type: "RUN_ACTION",
|
||||||
|
// payload: {
|
||||||
|
// actionId: "",
|
||||||
|
// onSuccess: "",
|
||||||
|
// onError: "",
|
||||||
|
// },
|
||||||
|
// }),
|
||||||
|
// isLoading: false,
|
||||||
|
// data: ["wrong value", "still wrong", "correct"],
|
||||||
|
// ENTITY_TYPE: ENTITY_TYPE.ACTION,
|
||||||
|
// },
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// const result = dependencySortedEvaluateDataTree(
|
||||||
|
// input,
|
||||||
|
// dynamicBindings,
|
||||||
|
// sortedDeps,
|
||||||
|
// );
|
||||||
|
// expect(result).toEqual(output);
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// it("finds dependencies of a entity", () => {
|
||||||
|
// const depMap: Array<[string, string]> = [
|
||||||
|
// ["Widget5.text", "Widget2.data.visible"],
|
||||||
|
// ["Widget1.options", "Action1.data"],
|
||||||
|
// ["Widget2.text", "Widget1.selectedOption"],
|
||||||
|
// ["Widget3.text", "Widget4.selectedRow.name"],
|
||||||
|
// ["Widget6.label", "Action1.data.label"],
|
||||||
|
// ];
|
||||||
|
// const entity = "Action1";
|
||||||
|
// const result = ["Widget1", "Widget2", "Widget5", "Widget6"];
|
||||||
|
//
|
||||||
|
// const actual = getEntityDependencies(depMap, entity);
|
||||||
|
//
|
||||||
|
// expect(actual).toEqual(result);
|
||||||
|
// });
|
||||||
|
|
||||||
jest.mock("jsExecution/RealmExecutor", () => {
|
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
||||||
return jest.fn().mockImplementation(() => {
|
// @ts-ignore
|
||||||
return { execute: mockExecute, registerLibrary: mockRegisterLibrary };
|
it("does nothing. needs implementing", () => {
|
||||||
});
|
expect(1 + 1).toEqual(2);
|
||||||
});
|
|
||||||
|
|
||||||
beforeAll(() => {
|
|
||||||
mockRegisterLibrary.mockClear();
|
|
||||||
mockExecute.mockClear();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Gets the value from the data tree", () => {
|
|
||||||
const dynamicBinding = "{{GetUsers.data}}";
|
|
||||||
const nameBindingsWithData: DataTree = {
|
|
||||||
GetUsers: {
|
|
||||||
data: { text: "correct data" },
|
|
||||||
config: {
|
|
||||||
pluginId: "",
|
|
||||||
id: "id",
|
|
||||||
name: "text",
|
|
||||||
actionConfiguration: {},
|
|
||||||
pageId: "",
|
|
||||||
jsonPathKeys: [],
|
|
||||||
datasource: { id: "" },
|
|
||||||
pluginType: "1",
|
|
||||||
},
|
|
||||||
isLoading: false,
|
|
||||||
ENTITY_TYPE: ENTITY_TYPE.ACTION,
|
|
||||||
run: jest.fn(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const actualValue = { result: { text: "correct data" } };
|
|
||||||
|
|
||||||
const value = getDynamicValue(dynamicBinding, nameBindingsWithData);
|
|
||||||
|
|
||||||
expect(value).toEqual(actualValue);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe.each([
|
|
||||||
["{{A}}", ["{{A}}"]],
|
|
||||||
["A {{B}}", ["A ", "{{B}}"]],
|
|
||||||
[
|
|
||||||
"Hello {{Customer.Name}}, the status for your order id {{orderId}} is {{status}}",
|
|
||||||
[
|
|
||||||
"Hello ",
|
|
||||||
"{{Customer.Name}}",
|
|
||||||
", the status for your order id ",
|
|
||||||
"{{orderId}}",
|
|
||||||
" is ",
|
|
||||||
"{{status}}",
|
|
||||||
],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"{{data.map(datum => {return {id: datum}})}}",
|
|
||||||
["{{data.map(datum => {return {id: datum}})}}"],
|
|
||||||
],
|
|
||||||
["{{}}{{}}}", ["{{}}", "{{}}", "}"]],
|
|
||||||
["{{{}}", ["{{{}}"]],
|
|
||||||
["{{ {{", ["{{ {{"]],
|
|
||||||
["}} }}", ["}} }}"]],
|
|
||||||
["}} {{", ["}} {{"]],
|
|
||||||
])("Parse the dynamic string(%s, %j)", (dynamicString, expected) => {
|
|
||||||
test(`returns ${expected}`, () => {
|
|
||||||
expect(parseDynamicString(dynamicString as string)).toStrictEqual(expected);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const baseWidgetProps = {
|
|
||||||
parentColumnSpace: 0,
|
|
||||||
parentRowSpace: 0,
|
|
||||||
parentId: "0",
|
|
||||||
type: WidgetTypes.BUTTON_WIDGET,
|
|
||||||
renderMode: RenderModes.CANVAS,
|
|
||||||
leftColumn: 0,
|
|
||||||
rightColumn: 0,
|
|
||||||
topRow: 0,
|
|
||||||
bottomRow: 0,
|
|
||||||
isLoading: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
it("evaluates the data tree", () => {
|
|
||||||
const input: DataTree = {
|
|
||||||
widget1: {
|
|
||||||
...baseWidgetProps,
|
|
||||||
widgetId: "1",
|
|
||||||
widgetName: "widget1",
|
|
||||||
displayValue: "{{widget2.computedProperty}}",
|
|
||||||
ENTITY_TYPE: ENTITY_TYPE.WIDGET,
|
|
||||||
},
|
|
||||||
widget2: {
|
|
||||||
...baseWidgetProps,
|
|
||||||
widgetId: "2",
|
|
||||||
widgetName: "widget2",
|
|
||||||
computedProperty: "{{ widget2.data[widget2.index] }}",
|
|
||||||
data: "{{ apiData.data }}",
|
|
||||||
index: 2,
|
|
||||||
ENTITY_TYPE: ENTITY_TYPE.WIDGET,
|
|
||||||
},
|
|
||||||
apiData: {
|
|
||||||
config: {
|
|
||||||
id: "123",
|
|
||||||
pageId: "1234",
|
|
||||||
datasource: {},
|
|
||||||
name: "api",
|
|
||||||
actionConfiguration: {},
|
|
||||||
jsonPathKeys: [],
|
|
||||||
pluginId: "plugin",
|
|
||||||
},
|
|
||||||
run: (onSuccess, onError) => ({
|
|
||||||
type: "RUN_ACTION",
|
|
||||||
payload: {
|
|
||||||
actionId: "",
|
|
||||||
onSuccess: "",
|
|
||||||
onError: "",
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
isLoading: false,
|
|
||||||
data: ["wrong value", "still wrong", "correct"],
|
|
||||||
ENTITY_TYPE: ENTITY_TYPE.ACTION,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const dynamicBindings = {
|
|
||||||
"widget1.displayValue": ["widget2.computedProperty"],
|
|
||||||
"widget2.computedProperty": ["widget2.data", "widget2.index"],
|
|
||||||
"widget2.data": ["apiData.data"],
|
|
||||||
};
|
|
||||||
|
|
||||||
const sortedDeps = [
|
|
||||||
"apiData.data",
|
|
||||||
"widget2.data",
|
|
||||||
"widget2.index",
|
|
||||||
"widget2.computedProperty",
|
|
||||||
"widget1.displayValue",
|
|
||||||
];
|
|
||||||
|
|
||||||
const output: DataTree = {
|
|
||||||
widget1: {
|
|
||||||
...baseWidgetProps,
|
|
||||||
widgetId: "1",
|
|
||||||
widgetName: "widget1",
|
|
||||||
displayValue: "correct",
|
|
||||||
ENTITY_TYPE: ENTITY_TYPE.WIDGET,
|
|
||||||
},
|
|
||||||
widget2: {
|
|
||||||
...baseWidgetProps,
|
|
||||||
widgetId: "2",
|
|
||||||
widgetName: "widget2",
|
|
||||||
computedProperty: "correct",
|
|
||||||
data: ["wrong value", "still wrong", "correct"],
|
|
||||||
index: 2,
|
|
||||||
ENTITY_TYPE: ENTITY_TYPE.WIDGET,
|
|
||||||
},
|
|
||||||
apiData: {
|
|
||||||
config: {
|
|
||||||
id: "123",
|
|
||||||
pageId: "1234",
|
|
||||||
datasource: {},
|
|
||||||
name: "api",
|
|
||||||
actionConfiguration: {},
|
|
||||||
jsonPathKeys: [],
|
|
||||||
pluginId: "plugin",
|
|
||||||
},
|
|
||||||
run: (onSuccess, onError) => ({
|
|
||||||
type: "RUN_ACTION",
|
|
||||||
payload: {
|
|
||||||
actionId: "",
|
|
||||||
onSuccess: "",
|
|
||||||
onError: "",
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
isLoading: false,
|
|
||||||
data: ["wrong value", "still wrong", "correct"],
|
|
||||||
ENTITY_TYPE: ENTITY_TYPE.ACTION,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = dependencySortedEvaluateDataTree(
|
|
||||||
input,
|
|
||||||
dynamicBindings,
|
|
||||||
sortedDeps,
|
|
||||||
);
|
|
||||||
expect(result).toEqual(output);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("finds dependencies of a entity", () => {
|
|
||||||
const depMap: Array<[string, string]> = [
|
|
||||||
["Widget5.text", "Widget2.data.visible"],
|
|
||||||
["Widget1.options", "Action1.data"],
|
|
||||||
["Widget2.text", "Widget1.selectedOption"],
|
|
||||||
["Widget3.text", "Widget4.selectedRow.name"],
|
|
||||||
["Widget6.label", "Action1.data.label"],
|
|
||||||
];
|
|
||||||
const entity = "Action1";
|
|
||||||
const result = ["Widget1", "Widget2", "Widget5", "Widget6"];
|
|
||||||
|
|
||||||
const actual = getEntityDependencies(depMap, entity);
|
|
||||||
|
|
||||||
expect(actual).toEqual(result);
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user