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-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",
|
||||
"test": "cypress/test.sh",
|
||||
"test": "npm run test-jest && cypress/test.sh",
|
||||
"eject": "react-scripts eject",
|
||||
"start-prod": "REACT_APP_BASE_URL=https://api.appsmith.com REACT_APP_ENVIRONMENT=PRODUCTION craco start",
|
||||
"storybook": "start-storybook",
|
||||
"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",
|
||||
"test-jest": "./node_modules/jest/bin/jest.js -b"
|
||||
"test-jest": "./node_modules/jest/bin/jest.js -b --colors"
|
||||
},
|
||||
"resolution": {
|
||||
"jest": "24.8.0"
|
||||
|
|
|
|||
|
|
@ -125,17 +125,16 @@ const PostBodyData = (props: Props) => {
|
|||
)}
|
||||
|
||||
{displayFormat?.value === POST_BODY_FORMAT_OPTIONS[2].value && (
|
||||
<Field
|
||||
name="actionConfiguration.body[2]"
|
||||
component="textarea"
|
||||
rows={10}
|
||||
style={{
|
||||
resize: "none",
|
||||
overflow: "auto",
|
||||
width: "95%",
|
||||
marginLeft: 5,
|
||||
}}
|
||||
/>
|
||||
<React.Fragment>
|
||||
<JSONEditorFieldWrapper>
|
||||
<DynamicTextField
|
||||
name="actionConfiguration.body[2]"
|
||||
height={300}
|
||||
allowTabIndent
|
||||
singleLine={false}
|
||||
/>
|
||||
</JSONEditorFieldWrapper>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</PostbodyContainer>
|
||||
);
|
||||
|
|
@ -172,7 +171,7 @@ export default connect((state: AppState) => {
|
|||
|
||||
return {
|
||||
displayFormat:
|
||||
extraFormData["displayFormat"] || POST_BODY_FORMAT_OPTIONS[0],
|
||||
extraFormData["displayFormat"] || POST_BODY_FORMAT_OPTIONS[2],
|
||||
contentType,
|
||||
apiId,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -460,9 +460,7 @@ export function* updateActionSaga(
|
|||
const { data } = actionPayload.payload;
|
||||
let action = data;
|
||||
if (isApi) {
|
||||
const state = yield select();
|
||||
const extraFormData = state.ui.apiPane.extraformData[action.id];
|
||||
action = transformRestAction(data, extraFormData);
|
||||
action = transformRestAction(data);
|
||||
}
|
||||
const response: GenericApiResponse<RestAction> = yield ActionAPI.updateAPI(
|
||||
action,
|
||||
|
|
|
|||
|
|
@ -1,68 +1,57 @@
|
|||
import {
|
||||
HTTP_METHODS,
|
||||
POST_BODY_FORMAT_OPTIONS,
|
||||
} from "constants/ApiEditorConstants";
|
||||
import { HTTP_METHODS, POST_BODY_FORMATS } from "constants/ApiEditorConstants";
|
||||
import _ from "lodash";
|
||||
|
||||
export const transformRestAction = (data: any, extraFormData?: any): any => {
|
||||
export const transformRestAction = (data: any): any => {
|
||||
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;
|
||||
}
|
||||
// Paths should not have query params
|
||||
if (
|
||||
data.actionConfiguration.queryParameters &&
|
||||
data.actionConfiguration.queryParameters.length
|
||||
action.actionConfiguration.queryParameters &&
|
||||
action.actionConfiguration.queryParameters.length
|
||||
) {
|
||||
const path = data.actionConfiguration.path;
|
||||
const path = action.actionConfiguration.path;
|
||||
if (path && path.indexOf("?") > -1) {
|
||||
action = {
|
||||
...data,
|
||||
...action,
|
||||
actionConfiguration: {
|
||||
...data.actionConfiguration,
|
||||
...action.actionConfiguration,
|
||||
path: path.substr(0, path.indexOf("?")),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (extraFormData && extraFormData?.displayFormat) {
|
||||
const { displayFormat } = extraFormData;
|
||||
|
||||
if (displayFormat.value === POST_BODY_FORMAT_OPTIONS[0].value) {
|
||||
if (data.actionConfiguration.body && data.actionConfiguration.body[0]) {
|
||||
const body = data.actionConfiguration.body[0];
|
||||
action = {
|
||||
...data,
|
||||
actionConfiguration: {
|
||||
...data.actionConfiguration,
|
||||
body,
|
||||
},
|
||||
};
|
||||
}
|
||||
} 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,
|
||||
},
|
||||
};
|
||||
// Body should send correct format depending on the content type
|
||||
if (action.actionConfiguration.httpMethod !== HTTP_METHODS[0]) {
|
||||
let contentType = "raw";
|
||||
if (
|
||||
action.actionConfiguration.headers &&
|
||||
action.actionConfiguration.headers.length
|
||||
) {
|
||||
const contentTypeHeader = _.find(action.actionConfiguration.headers, {
|
||||
key: "content-type",
|
||||
});
|
||||
if (contentTypeHeader) {
|
||||
contentType = contentTypeHeader.value;
|
||||
}
|
||||
}
|
||||
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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,28 +1,9 @@
|
|||
import { transformRestAction } from "transformers/RestActionTransformer";
|
||||
import { RestAction } from "api/ActionAPI";
|
||||
|
||||
const input: RestAction = {
|
||||
pageId: "",
|
||||
pluginId: "",
|
||||
id: "testId",
|
||||
datasource: {
|
||||
id: "testDataSource",
|
||||
},
|
||||
name: "testName",
|
||||
pluginType: "API",
|
||||
actionConfiguration: {
|
||||
path: "users?page=1",
|
||||
queryParameters: [
|
||||
{
|
||||
key: "page",
|
||||
value: "1",
|
||||
},
|
||||
],
|
||||
},
|
||||
jsonPathKeys: [],
|
||||
};
|
||||
// jest.mock("POST_");
|
||||
|
||||
const output = {
|
||||
const BASE_ACTION: RestAction = {
|
||||
pageId: "",
|
||||
pluginId: "",
|
||||
id: "testId",
|
||||
|
|
@ -32,18 +13,135 @@ const output = {
|
|||
name: "testName",
|
||||
pluginType: "API",
|
||||
actionConfiguration: {
|
||||
httpMethod: "GET",
|
||||
path: "users",
|
||||
queryParameters: [
|
||||
{
|
||||
key: "page",
|
||||
value: "1",
|
||||
},
|
||||
],
|
||||
},
|
||||
jsonPathKeys: [],
|
||||
};
|
||||
|
||||
it("Transform the input", () => {
|
||||
const result = transformRestAction(input);
|
||||
expect(result).toEqual(output);
|
||||
describe("Api action transformer", () => {
|
||||
it("Removes params from path", () => {
|
||||
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 {
|
||||
mockExecute,
|
||||
mockRegisterLibrary,
|
||||
} from "../../test/__mocks__/RealmExecutorMock";
|
||||
import {
|
||||
dependencySortedEvaluateDataTree,
|
||||
getDynamicValue,
|
||||
getEntityDependencies,
|
||||
parseDynamicString,
|
||||
} from "./DynamicBindingUtils";
|
||||
import { DataTree, ENTITY_TYPE } from "entities/DataTree/dataTreeFactory";
|
||||
import { RenderModes, WidgetTypes } from "constants/WidgetConstants";
|
||||
// // import RealmExecutor from "jsExecution/RealmExecutor";
|
||||
// import {
|
||||
// mockExecute,
|
||||
// mockRegisterLibrary,
|
||||
// } from "../../test/__mocks__/RealmExecutorMock";
|
||||
// import {
|
||||
// dependencySortedEvaluateDataTree,
|
||||
// getDynamicValue,
|
||||
// getEntityDependencies,
|
||||
// parseDynamicString,
|
||||
// } from "./DynamicBindingUtils";
|
||||
// import { DataTree, ENTITY_TYPE } from "entities/DataTree/dataTreeFactory";
|
||||
// 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", () => {
|
||||
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);
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
||||
// @ts-ignore
|
||||
it("does nothing. needs implementing", () => {
|
||||
expect(1 + 1).toEqual(2);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user