## Description - Adds one click binding support for JSON form widget. #### PR fixes following issue(s) Fixes #25561 Fixes #26375 #### Media > A video or a GIF is preferred. when using Loom, don’t embed because it looks like it’s a GIF. instead, just link to the video > > #### Type of change - New feature (non-breaking change which adds functionality) ## Testing > #### How Has This Been Tested? > Please describe the tests that you ran to verify your changes. Also list any relevant details for your test configuration. > Delete anything that is not relevant - [x] Manual - [x] Jest - [x] Cypress #### Test Plan > [One click binding support on JSON Form (Test plan)](https://github.com/appsmithorg/TestSmith/issues/2523) #### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) ## Checklist: #### Dev activity - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag #### QA activity: - [ ] [Speedbreak features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-) have been covered - [ ] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-) - [ ] Test plan has been peer reviewed by project stakeholders and other QA members - [ ] Manually tested functionality on DP - [ ] We had an implementation alignment call with stakeholders post QA Round 2 - [ ] Cypress test cases have been added and approved by SDET/manual QA - [ ] Added `Test Plan Approved` label after Cypress tests were reviewed - [ ] Added `Test Plan Approved` label after JUnit tests were reviewed --------- Co-authored-by: balajisoundar <balaji@appsmith.com>
368 lines
9.9 KiB
TypeScript
368 lines
9.9 KiB
TypeScript
import { DatasourceConnectionMode } from "entities/Datasource";
|
|
import PostgreSQL from ".";
|
|
|
|
describe("PostgreSQL WidgetQueryGenerator", () => {
|
|
const initialValues = {
|
|
actionConfiguration: {
|
|
pluginSpecifiedTemplates: [{ value: true }],
|
|
},
|
|
};
|
|
test("should build select form data correctly", () => {
|
|
const expr = PostgreSQL.build(
|
|
{
|
|
select: {
|
|
limit: "data_table.pageSize",
|
|
where: 'data_table.searchText || ""',
|
|
offset: "(data_table.pageNo - 1) * data_table.pageSize",
|
|
orderBy: "data_table.sortOrder.column",
|
|
sortOrder: "data_table.sortOrder.order || 'ASC'",
|
|
},
|
|
totalRecord: false,
|
|
},
|
|
{
|
|
tableName: "someTable",
|
|
datasourceId: "someId",
|
|
aliases: [{ name: "someColumn1", alias: "someColumn1" }],
|
|
widgetId: "someWidgetId",
|
|
searchableColumn: "title",
|
|
columns: [],
|
|
primaryColumn: "genres",
|
|
connectionMode: DatasourceConnectionMode.READ_WRITE,
|
|
},
|
|
initialValues,
|
|
);
|
|
|
|
const res = `SELECT
|
|
*
|
|
FROM
|
|
someTable
|
|
WHERE
|
|
\"title\" ilike '%{{data_table.searchText || \"\"}}%'
|
|
ORDER BY
|
|
\"{{data_table.sortOrder.column || 'genres'}}\" {{data_table.sortOrder.order || 'ASC' ? \"\" : \"DESC\"}}
|
|
LIMIT
|
|
{{data_table.pageSize}}
|
|
OFFSET
|
|
{{(data_table.pageNo - 1) * data_table.pageSize}}`;
|
|
|
|
expect(expr).toEqual([
|
|
{
|
|
name: "Select_someTable",
|
|
type: "select",
|
|
dynamicBindingPathList: [
|
|
{
|
|
key: "body",
|
|
},
|
|
],
|
|
payload: {
|
|
pluginSpecifiedTemplates: [{ value: false }],
|
|
body: res,
|
|
},
|
|
},
|
|
]);
|
|
});
|
|
|
|
test("should build select form data correctly without primary column", () => {
|
|
const expr = PostgreSQL.build(
|
|
{
|
|
select: {
|
|
limit: "data_table.pageSize",
|
|
where: 'data_table.searchText || ""',
|
|
offset: "(data_table.pageNo - 1) * data_table.pageSize",
|
|
orderBy: "data_table.sortOrder.column",
|
|
sortOrder: `data_table.sortOrder.order !== "desc"`,
|
|
},
|
|
totalRecord: false,
|
|
},
|
|
{
|
|
tableName: "someTable",
|
|
datasourceId: "someId",
|
|
aliases: [{ name: "someColumn1", alias: "someColumn1" }],
|
|
widgetId: "someWidgetId",
|
|
searchableColumn: "title",
|
|
columns: [],
|
|
primaryColumn: "",
|
|
connectionMode: DatasourceConnectionMode.READ_WRITE,
|
|
},
|
|
initialValues,
|
|
);
|
|
|
|
const res = `SELECT
|
|
*
|
|
FROM
|
|
someTable
|
|
WHERE
|
|
\"title\" ilike '%{{data_table.searchText || \"\"}}%' {{data_table.sortOrder.column ? "ORDER BY " + data_table.sortOrder.column + " " + (data_table.sortOrder.order !== "desc" ? "" : "DESC") : ""}}
|
|
LIMIT
|
|
{{data_table.pageSize}}
|
|
OFFSET
|
|
{{(data_table.pageNo - 1) * data_table.pageSize}}`;
|
|
|
|
expect(expr).toEqual([
|
|
{
|
|
name: "Select_someTable",
|
|
type: "select",
|
|
dynamicBindingPathList: [
|
|
{
|
|
key: "body",
|
|
},
|
|
],
|
|
payload: {
|
|
pluginSpecifiedTemplates: [{ value: false }],
|
|
body: res,
|
|
},
|
|
},
|
|
]);
|
|
});
|
|
|
|
test("should build select form data correctly without write permissions", () => {
|
|
const expr = PostgreSQL.build(
|
|
{
|
|
select: {
|
|
limit: "data_table.pageSize",
|
|
where: 'data_table.searchText || ""',
|
|
offset: "(data_table.pageNo - 1) * data_table.pageSize",
|
|
orderBy: "data_table.sortOrder.column",
|
|
sortOrder: "data_table.sortOrder.order || 'ASC'",
|
|
},
|
|
totalRecord: false,
|
|
},
|
|
{
|
|
tableName: "someTable",
|
|
datasourceId: "someId",
|
|
aliases: [{ name: "someColumn1", alias: "someColumn1" }],
|
|
widgetId: "someWidgetId",
|
|
searchableColumn: "title",
|
|
columns: [],
|
|
primaryColumn: "genres",
|
|
connectionMode: DatasourceConnectionMode.READ_ONLY,
|
|
},
|
|
initialValues,
|
|
);
|
|
|
|
const res = `SELECT
|
|
*
|
|
FROM
|
|
someTable
|
|
WHERE
|
|
\"title\" ilike '%{{data_table.searchText || \"\"}}%'
|
|
ORDER BY
|
|
\"{{data_table.sortOrder.column || 'genres'}}\" {{data_table.sortOrder.order || 'ASC' ? \"\" : \"DESC\"}}
|
|
LIMIT
|
|
{{data_table.pageSize}}
|
|
OFFSET
|
|
{{(data_table.pageNo - 1) * data_table.pageSize}}`;
|
|
|
|
expect(expr).toEqual([
|
|
{
|
|
name: "Select_someTable",
|
|
type: "select",
|
|
dynamicBindingPathList: [
|
|
{
|
|
key: "body",
|
|
},
|
|
],
|
|
payload: {
|
|
pluginSpecifiedTemplates: [{ value: false }],
|
|
body: res,
|
|
},
|
|
},
|
|
]);
|
|
});
|
|
|
|
test("should not build update form data without primary key ", () => {
|
|
const expr = PostgreSQL.build(
|
|
{
|
|
update: {
|
|
value: `update_form.fieldState'`,
|
|
where: `"id" = {{data_table.selectedRow.id}}`,
|
|
},
|
|
totalRecord: false,
|
|
},
|
|
{
|
|
tableName: "someTable",
|
|
datasourceId: "someId",
|
|
aliases: [{ name: "someColumn1", alias: "someColumn1" }],
|
|
widgetId: "someWidgetId",
|
|
searchableColumn: "title",
|
|
columns: [
|
|
{ name: "id", type: "number", isSelected: true },
|
|
{ name: "name", type: "number", isSelected: true },
|
|
],
|
|
primaryColumn: "",
|
|
connectionMode: DatasourceConnectionMode.READ_WRITE,
|
|
},
|
|
initialValues,
|
|
);
|
|
|
|
expect(expr).toEqual([]);
|
|
});
|
|
|
|
test("should not build update form data without write permissions ", () => {
|
|
const expr = PostgreSQL.build(
|
|
{
|
|
update: {
|
|
value: `update_form.fieldState'`,
|
|
where: `"id" = {{data_table.selectedRow.id}}`,
|
|
},
|
|
totalRecord: false,
|
|
},
|
|
{
|
|
tableName: "someTable",
|
|
datasourceId: "someId",
|
|
aliases: [{ name: "someColumn1", alias: "someColumn1" }],
|
|
widgetId: "someWidgetId",
|
|
searchableColumn: "title",
|
|
columns: [
|
|
{ name: "id", type: "number", isSelected: true },
|
|
{ name: "name", type: "number", isSelected: true },
|
|
],
|
|
primaryColumn: "id",
|
|
connectionMode: DatasourceConnectionMode.READ_ONLY,
|
|
},
|
|
initialValues,
|
|
);
|
|
|
|
expect(expr).toEqual([]);
|
|
});
|
|
|
|
test("should build update form data correctly ", () => {
|
|
const expr = PostgreSQL.build(
|
|
{
|
|
update: {
|
|
value: `update_form.fieldState'`,
|
|
where: `data_table.selectedRow`,
|
|
},
|
|
totalRecord: false,
|
|
},
|
|
{
|
|
tableName: "someTable",
|
|
datasourceId: "someId",
|
|
aliases: [{ name: "someColumn1", alias: "someColumn1" }],
|
|
widgetId: "someWidgetId",
|
|
searchableColumn: "title",
|
|
columns: [
|
|
{ name: "id", type: "number", isSelected: true },
|
|
{ name: "name", type: "number", isSelected: true },
|
|
],
|
|
primaryColumn: "id",
|
|
connectionMode: DatasourceConnectionMode.READ_WRITE,
|
|
dataIdentifier: "id",
|
|
},
|
|
initialValues,
|
|
);
|
|
|
|
expect(expr).toEqual([
|
|
{
|
|
name: "Update_someTable",
|
|
type: "update",
|
|
dynamicBindingPathList: [
|
|
{
|
|
key: "body",
|
|
},
|
|
],
|
|
payload: {
|
|
body: 'UPDATE someTable SET "name"= \'{{update_form.fieldState\'.name}}\' WHERE "id"= {{data_table.selectedRow.id}};',
|
|
pluginSpecifiedTemplates: [{ value: false }],
|
|
},
|
|
},
|
|
]);
|
|
});
|
|
|
|
test("should not build insert form data without primary key ", () => {
|
|
const expr = PostgreSQL.build(
|
|
{
|
|
create: {
|
|
value: `update_form.fieldState`,
|
|
},
|
|
totalRecord: false,
|
|
},
|
|
{
|
|
tableName: "someTable",
|
|
datasourceId: "someId",
|
|
// ignore columns
|
|
aliases: [{ name: "someColumn1", alias: "someColumn1" }],
|
|
widgetId: "someWidgetId",
|
|
searchableColumn: "title",
|
|
columns: [
|
|
{ name: "id", type: "number", isSelected: true },
|
|
{ name: "name", type: "number", isSelected: true },
|
|
],
|
|
primaryColumn: "",
|
|
connectionMode: DatasourceConnectionMode.READ_WRITE,
|
|
},
|
|
initialValues,
|
|
);
|
|
expect(expr).toEqual([]);
|
|
});
|
|
|
|
test("should not build insert form data without write permissions ", () => {
|
|
const expr = PostgreSQL.build(
|
|
{
|
|
create: {
|
|
value: `update_form.fieldState`,
|
|
},
|
|
totalRecord: false,
|
|
},
|
|
{
|
|
tableName: "someTable",
|
|
datasourceId: "someId",
|
|
// ignore columns
|
|
aliases: [{ name: "someColumn1", alias: "someColumn1" }],
|
|
widgetId: "someWidgetId",
|
|
searchableColumn: "title",
|
|
columns: [
|
|
{ name: "id", type: "number", isSelected: true },
|
|
{ name: "name", type: "number", isSelected: true },
|
|
],
|
|
primaryColumn: "id",
|
|
connectionMode: DatasourceConnectionMode.READ_ONLY,
|
|
},
|
|
initialValues,
|
|
);
|
|
|
|
expect(expr).toEqual([]);
|
|
});
|
|
|
|
test("should build insert form data correctly ", () => {
|
|
const expr = PostgreSQL.build(
|
|
{
|
|
create: {
|
|
value: `update_form.fieldState`,
|
|
},
|
|
totalRecord: false,
|
|
},
|
|
{
|
|
tableName: "someTable",
|
|
datasourceId: "someId",
|
|
// ignore columns
|
|
aliases: [{ name: "someColumn1", alias: "someColumn1" }],
|
|
widgetId: "someWidgetId",
|
|
searchableColumn: "title",
|
|
columns: [
|
|
{ name: "id", type: "number", isSelected: true },
|
|
{ name: "name", type: "number", isSelected: true },
|
|
],
|
|
primaryColumn: "id",
|
|
connectionMode: DatasourceConnectionMode.READ_WRITE,
|
|
},
|
|
initialValues,
|
|
);
|
|
expect(expr).toEqual([
|
|
{
|
|
name: "Insert_someTable",
|
|
type: "create",
|
|
dynamicBindingPathList: [
|
|
{
|
|
key: "body",
|
|
},
|
|
],
|
|
payload: {
|
|
body: "INSERT INTO someTable (\"name\") VALUES ('{{update_form.fieldState.name}}')",
|
|
pluginSpecifiedTemplates: [{ value: false }],
|
|
},
|
|
},
|
|
]);
|
|
});
|
|
});
|