From 5d213dddc6848455035a2dfd4e6db532624b4769 Mon Sep 17 00:00:00 2001 From: Rahul Barwal Date: Tue, 17 Dec 2024 18:16:27 +0530 Subject: [PATCH] chore: Split derived.test.js to separate files. (#38162) ## Description This PR started with this goal: - Deleted the unreadable `derived.test.js` (4668 lines) file and split each suite to its file. - Moved all `derived.js` related specs in widget folder to __tests__ folder Later we found that `testRegex` in `jest.config` will treat anything inside `__tests__` as runnable, so we modify this rule and are moving to a consistent naming for our unit tests(any file ending with `.test.` or `.spec.` This refactor aims to improve maintainability and ensure that the table widget's derived properties are thoroughly tested. Fixes #`Issue Number` _or_ Fixes `Issue URL` > [!WARNING] > _If no issue exists, please create an issue first, and check with the maintainers if the issue is valid._ ## Automation /ok-to-test tags="" ### :mag: Cypress test results > [!WARNING] > Tests have not run on the HEAD b3168bb1a6d3070a910972d1d9a78d61a3aaee91 yet >
Tue, 17 Dec 2024 10:20:54 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [x] No ## Summary by CodeRabbit - **New Features** - Expanded properties for table widget configuration. - Introduced sample data constants for column schemas and processed table data. - **Bug Fixes** - Improved validation tests for editable cells and row selection functions. - **Tests** - Added comprehensive test suites for various table widget functionalities, including filtering, sorting, and row selection. - Introduced tests for handling HTML content within table columns. - Added tests for new functions related to row updates and indices. - Enhanced test coverage for existing utility functions and table properties. - **Chores** - Updated import paths to reflect a new directory structure across various test files. - Modified Jest configuration for improved readability and regex adjustments. --- app/client/jest.config.js | 11 +- ...=> apiFailureResponseInterceptors.test.ts} | 0 ...tors.ts => apiRequestInterceptors.test.ts} | 0 ... => apiSucessResponseInterceptors.test.ts} | 0 .../{test.ts => metaReducer.test.ts} | 0 .../{ => __tests__}/TableRendered.test.ts | 4 +- .../widget/__tests__/derived.test/fixture.js | 191 + .../getEditableCellValidity.test.js | 1247 +++++ .../derived.test/getFilteredTableData.test.js | 1457 +++++ .../getOrderedTableColumns.test.js | 169 + .../derived.test/getPageOffset.test.js | 91 + .../derived.test/getSelectedRow.test.js | 244 + .../derived.test/getSelectedRows.test.js | 99 + .../derived.test/getTriggeredRow.test.js | 111 + .../derived.test/getUpdatedRow.test.js | 99 + .../derived.test/getUpdatedRowIndices.test.js | 64 + .../derived.test/getUpdatedRows.test.js | 243 + .../derived.test/htmlColumns.test.js | 579 ++ .../derived.test/tableHeaders.test.js | 111 + .../{ => __tests__}/propertyUtils.test.ts | 6 +- .../widget/{ => __tests__}/utilities.test.ts | 8 +- .../TableWidgetV2/widget/derived.test.js | 4667 ----------------- .../JSObject/{test.ts => JSObject.test.ts} | 0 .../{test.ts => dataTreeEvaluator.test.ts} | 0 .../{test.ts => DependencyMap.test.ts} | 0 25 files changed, 4720 insertions(+), 4681 deletions(-) rename app/client/src/api/__tests__/{apiFailureResponseInterceptors.ts => apiFailureResponseInterceptors.test.ts} (100%) rename app/client/src/api/__tests__/{apiRequestInterceptors.ts => apiRequestInterceptors.test.ts} (100%) rename app/client/src/api/__tests__/{apiSucessResponseInterceptors.ts => apiSucessResponseInterceptors.test.ts} (100%) rename app/client/src/reducers/entityReducers/metaReducer/{test.ts => metaReducer.test.ts} (100%) rename app/client/src/widgets/TableWidgetV2/widget/{ => __tests__}/TableRendered.test.ts (98%) create mode 100644 app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/fixture.js create mode 100644 app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getEditableCellValidity.test.js create mode 100644 app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getFilteredTableData.test.js create mode 100644 app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getOrderedTableColumns.test.js create mode 100644 app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getPageOffset.test.js create mode 100644 app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getSelectedRow.test.js create mode 100644 app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getSelectedRows.test.js create mode 100644 app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getTriggeredRow.test.js create mode 100644 app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getUpdatedRow.test.js create mode 100644 app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getUpdatedRowIndices.test.js create mode 100644 app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getUpdatedRows.test.js create mode 100644 app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/htmlColumns.test.js create mode 100644 app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/tableHeaders.test.js rename app/client/src/widgets/TableWidgetV2/widget/{ => __tests__}/propertyUtils.test.ts (99%) rename app/client/src/widgets/TableWidgetV2/widget/{ => __tests__}/utilities.test.ts (99%) delete mode 100644 app/client/src/widgets/TableWidgetV2/widget/derived.test.js rename app/client/src/workers/Evaluation/JSObject/{test.ts => JSObject.test.ts} (100%) rename app/client/src/workers/common/DataTreeEvaluator/{test.ts => dataTreeEvaluator.test.ts} (100%) rename app/client/src/workers/common/DependencyMap/{test.ts => DependencyMap.test.ts} (100%) diff --git a/app/client/jest.config.js b/app/client/jest.config.js index cb8c0ad995a3..76534b076496 100644 --- a/app/client/jest.config.js +++ b/app/client/jest.config.js @@ -23,17 +23,19 @@ module.exports = { before: [ { path: "node_modules/ts-jest-mock-import-meta", - options: { metaObjectReplacement: { url: "https://www.url.com" } }, + options: { + metaObjectReplacement: { url: "https://www.url.com" }, + }, }, ], }, - } + }, ], }, testEnvironment: "jsdom", testTimeout: 9000, setupFilesAfterEnv: ["/test/setup.ts"], - testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(tsx|ts|js)?$", + testRegex: "\\.(test|spec)\\.(tsx|ts|js)?$", moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node", "css"], moduleDirectories: ["node_modules", "src", "test"], transformIgnorePatterns: [ @@ -68,8 +70,7 @@ module.exports = { "/node_modules/@blueprintjs/select/lib/esnext", "@appsmith/ads": "/node_modules/@appsmith/ads", "^canvas$": "jest-canvas-mock", - "^entities/(.*)$": "/src/entities/$1", // Match 'entities/*' - + "^entities/(.*)$": "/src/entities/$1", // Match 'entities/*' }, globals: { APPSMITH_FEATURE_CONFIGS: { diff --git a/app/client/src/api/__tests__/apiFailureResponseInterceptors.ts b/app/client/src/api/__tests__/apiFailureResponseInterceptors.test.ts similarity index 100% rename from app/client/src/api/__tests__/apiFailureResponseInterceptors.ts rename to app/client/src/api/__tests__/apiFailureResponseInterceptors.test.ts diff --git a/app/client/src/api/__tests__/apiRequestInterceptors.ts b/app/client/src/api/__tests__/apiRequestInterceptors.test.ts similarity index 100% rename from app/client/src/api/__tests__/apiRequestInterceptors.ts rename to app/client/src/api/__tests__/apiRequestInterceptors.test.ts diff --git a/app/client/src/api/__tests__/apiSucessResponseInterceptors.ts b/app/client/src/api/__tests__/apiSucessResponseInterceptors.test.ts similarity index 100% rename from app/client/src/api/__tests__/apiSucessResponseInterceptors.ts rename to app/client/src/api/__tests__/apiSucessResponseInterceptors.test.ts diff --git a/app/client/src/reducers/entityReducers/metaReducer/test.ts b/app/client/src/reducers/entityReducers/metaReducer/metaReducer.test.ts similarity index 100% rename from app/client/src/reducers/entityReducers/metaReducer/test.ts rename to app/client/src/reducers/entityReducers/metaReducer/metaReducer.test.ts diff --git a/app/client/src/widgets/TableWidgetV2/widget/TableRendered.test.ts b/app/client/src/widgets/TableWidgetV2/widget/__tests__/TableRendered.test.ts similarity index 98% rename from app/client/src/widgets/TableWidgetV2/widget/TableRendered.test.ts rename to app/client/src/widgets/TableWidgetV2/widget/__tests__/TableRendered.test.ts index fcd4e4a1dfe0..9b4ad4e77f3a 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/TableRendered.test.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/__tests__/TableRendered.test.ts @@ -1,6 +1,6 @@ import { ResponsiveBehavior } from "layoutSystems/common/utils/constants"; -import TableWidgetV2 from "."; -import type { TableWidgetProps } from "../constants"; +import TableWidgetV2 from ".."; +import type { TableWidgetProps } from "../../constants"; describe("TableWidgetV2 getWidgetView", () => { const tableWidgetProps: TableWidgetProps = { diff --git a/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/fixture.js b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/fixture.js new file mode 100644 index 000000000000..1d7f7d821a55 --- /dev/null +++ b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/fixture.js @@ -0,0 +1,191 @@ +export const samplePrimaryColumns = { + step: { + index: 0, + width: 150, + id: "step", + originalId: "step", + alias: "step", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "0.875rem", + enableFilter: true, + enableSort: true, + isVisible: true, + isCellVisible: true, + isCellEditable: false, + isDerived: false, + label: "step", + computedValue: ["#1", "#2", "#3"], + labelColor: "#FFFFFF", + cellBackground: "", + textColor: "", + fontStyle: "", + }, + task: { + index: 1, + width: 150, + id: "task", + originalId: "task", + alias: "task", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "0.875rem", + enableFilter: true, + enableSort: true, + isVisible: true, + isCellVisible: true, + isCellEditable: false, + isDerived: false, + label: "task", + computedValue: [ + "Drop a table", + "Create a query fetch_users with the Mock DB", + "Bind the query using => fetch_users.data", + ], + labelColor: "#FFFFFF", + cellBackground: "", + textColor: "", + fontStyle: "", + }, + status: { + index: 2, + width: 150, + id: "status", + originalId: "status", + alias: "status", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "0.875rem", + enableFilter: true, + enableSort: true, + isVisible: true, + isCellVisible: true, + isCellEditable: false, + isDerived: false, + label: "status", + computedValue: ["✅", "--", "--"], + labelColor: "#FFFFFF", + cellBackground: "", + textColor: "", + fontStyle: "", + }, + action: { + index: 3, + width: 150, + id: "action", + originalId: "action", + alias: "action", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "button", + textSize: "0.875rem", + enableFilter: true, + enableSort: true, + isVisible: true, + isCellVisible: true, + isCellEditable: false, + isDisabled: false, + isDerived: false, + label: "action", + onClick: + "{{currentRow.step === '#1' ? showAlert('Done', 'success') : currentRow.step === '#2' ? navigateTo('https://docs.appsmith.com/core-concepts/connecting-to-data-sources/querying-a-database',undefined,'NEW_WINDOW') : navigateTo('https://docs.appsmith.com/core-concepts/displaying-data-read/display-data-tables',undefined,'NEW_WINDOW')}}", + computedValue: ["", "", ""], + labelColor: "#FFFFFF", + buttonColor: ["#553DE9", "#553DE9", "#553DE9"], + borderRadius: ["0.375rem", "0.375rem", "0.375rem"], + boxShadow: ["none", "none", "none"], + buttonLabel: ["Action", "Action", "Action"], + buttonVariant: "PRIMARY", + }, + customColumn1: { + allowCellWrapping: false, + index: 4, + width: 150, + originalId: "customColumn1", + id: "customColumn1", + alias: "customColumn1", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "menuButton", + textSize: "0.875rem", + enableFilter: true, + enableSort: true, + isVisible: true, + isDisabled: false, + isCellEditable: false, + isEditable: false, + isCellVisible: true, + isDerived: true, + label: "menu", + isSaveVisible: true, + isDiscardVisible: true, + computedValue: "", + buttonStyle: "rgb(3, 179, 101)", + labelColor: "#FFFFFF", + menuColor: ["#553DE9", "#553DE9", "#553DE9"], + borderRadius: ["0.375rem", "0.375rem", "0.375rem"], + boxShadow: ["none", "none", "none"], + customAlias: "", + menuButtonLabel: ["Open Menu", "Open Menu", "Open Menu"], + menuVariant: "PRIMARY", + menuButtoniconName: "", + }, + customColumn2: { + allowCellWrapping: false, + index: 5, + width: 150, + originalId: "customColumn2", + id: "customColumn2", + alias: "customColumn2", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "iconButton", + textSize: "0.875rem", + enableFilter: true, + enableSort: true, + isVisible: true, + isDisabled: false, + isCellEditable: false, + isEditable: false, + isCellVisible: true, + isDerived: true, + label: "icon", + isSaveVisible: true, + isDiscardVisible: true, + computedValue: "", + buttonStyle: "rgb(3, 179, 101)", + labelColor: "#FFFFFF", + buttonColor: ["#553DE9", "#553DE9", "#553DE9"], + borderRadius: ["0.375rem", "0.375rem", "0.375rem"], + boxShadow: ["none", "none", "none"], + customAlias: "", + buttonVariant: "PRIMARY", + iconName: "add", + }, +}; +export const sampleProcessedTableData = [ + { + step: "#1", + task: "Drop a table", + status: "✅", + action: "", + __originalIndex__: 0, + }, + { + step: "#2", + task: "Create a query fetch_users with the Mock DB", + status: "--", + action: "", + __originalIndex__: 1, + }, + { + step: "#3", + task: "Bind the query using => fetch_users.data", + status: "--", + action: "", + __originalIndex__: 2, + }, +]; diff --git a/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getEditableCellValidity.test.js b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getEditableCellValidity.test.js new file mode 100644 index 000000000000..93de27d17be6 --- /dev/null +++ b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getEditableCellValidity.test.js @@ -0,0 +1,1247 @@ +import _ from "lodash"; +import derivedProperty from "../../derived"; + +describe("getEditableCellValidity", () => { + const { getEditableCellValidity } = derivedProperty; + + it("should test that its returns empty object when editableCell is empty and isAddRowInProgess is false", () => { + expect( + getEditableCellValidity( + { + editableCell: {}, + isAddRowInProgress: false, + }, + null, + _, + ), + ).toEqual({}); + }); + + describe("should test that it validates the editableColumn against all the validation properties", () => { + it("should return true for editable column when validation is empty", () => { + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: "", + }, + primaryColumns: { + step: { + columnType: "text", + alias: "step", + validation: {}, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: "123", + }, + primaryColumns: { + step: { + columnType: "text", + alias: "step", + validation: {}, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + }); + + it("should return true for editable column when isColumnEditableCellRequired is off and there is no value", () => { + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: "", + }, + primaryColumns: { + step: { + columnType: "text", + alias: "step", + validation: { + isColumnEditableCellRequired: false, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: undefined, + }, + primaryColumns: { + step: { + columnType: "text", + alias: "step", + validation: { + isColumnEditableCellRequired: false, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: null, + }, + primaryColumns: { + step: { + columnType: "text", + alias: "step", + validation: { + isColumnEditableCellRequired: false, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + }); + + it("should return true for editable column when isColumnEditableCellValid is true", () => { + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: null, + }, + primaryColumns: { + step: { + columnType: "text", + alias: "step", + validation: { + isColumnEditableCellValid: true, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + }); + + it("should return false for editable column when isColumnEditableCellValid is false", () => { + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: "test", + }, + primaryColumns: { + step: { + columnType: "text", + alias: "step", + validation: { + isColumnEditableCellValid: false, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: false }); + }); + + it("should return true for editable column when regex is matching", () => { + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: "#1", + }, + primaryColumns: { + step: { + columnType: "text", + alias: "step", + validation: { + regex: "^#1$", + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: "test", + }, + primaryColumns: { + step: { + columnType: "text", + alias: "step", + validation: { + regex: "^test$", + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + }); + + it("should return false for editable column when regex is not matching", () => { + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: "test", + }, + primaryColumns: { + step: { + columnType: "text", + alias: "step", + validation: { + regex: "^#1$", + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: false }); + + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: "#1", + }, + primaryColumns: { + step: { + columnType: "text", + alias: "step", + validation: { + regex: "^test$", + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: false }); + }); + + it("should return false for editable column when isColumnEditableCellRequired is true and there is no value", () => { + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: "", + }, + primaryColumns: { + step: { + columnType: "text", + alias: "step", + validation: { + isColumnEditableCellRequired: true, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: false }); + }); + + it("should return true for editable column when isColumnEditableCellRequired and there is value", () => { + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: "test", + }, + primaryColumns: { + step: { + columnType: "text", + alias: "step", + validation: { + isColumnEditableCellRequired: true, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + }); + + it("should return true for editable column when value is above min", () => { + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: 1, + }, + primaryColumns: { + step: { + columnType: "number", + alias: "step", + validation: { + min: 0, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + }); + + it("should return false for editable column when value is below min", () => { + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: -1, + }, + primaryColumns: { + step: { + columnType: "number", + alias: "step", + validation: { + min: 0, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: false }); + }); + + it("should return true for editable column when value is below max", () => { + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: 2, + }, + primaryColumns: { + step: { + columnType: "number", + alias: "step", + validation: { + max: 5, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + }); + + it("should return false for editable column when value is above max", () => { + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: 6, + }, + primaryColumns: { + step: { + columnType: "number", + alias: "step", + validation: { + max: 5, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: false }); + }); + + it("should return true for editable column when value is matching all the validation criteria", () => { + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: "#1", + }, + primaryColumns: { + step: { + columnType: "text", + alias: "step", + validation: { + isColumnEditableCellValid: false, + regex: "^#1$", + isColumnEditableCellRequired: false, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: false }); + + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: "#1", + }, + primaryColumns: { + step: { + alias: "step", + columnType: "text", + validation: { + isColumnEditableCellValid: true, + regex: "^#1$", + isColumnEditableCellRequired: false, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: "#1", + }, + primaryColumns: { + step: { + alias: "step", + columnType: "text", + validation: { + isColumnEditableCellValid: true, + regex: "^#1$", + isColumnEditableCellRequired: true, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: "#1", + }, + primaryColumns: { + step: { + alias: "step", + columnType: "text", + validation: { + isColumnEditableCellValid: true, + regex: "^#2$", + isColumnEditableCellRequired: true, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: false }); + + expect( + getEditableCellValidity( + { + editableCell: { + column: "step", + value: "#1", + }, + primaryColumns: { + step: { + alias: "step", + columnType: "text", + validation: { + isColumnEditableCellValid: true, + regex: "^#2$", + isColumnEditableCellRequired: false, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: false }); + }); + }); + + describe("should test that it validates the new row against all the validation properties", () => { + it("should check that only editable columns are present in the validation object", () => { + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: "#1", + task: "test", + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "text", + alias: "step", + validation: {}, + }, + task: { + columnType: "text", + alias: "task", + validation: {}, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: "#1", + task: "test", + }, + primaryColumns: { + step: { + columnType: "text", + alias: "step", + validation: {}, + }, + task: { + isEditable: true, + columnType: "text", + alias: "task", + validation: {}, + }, + }, + }, + null, + _, + ), + ).toEqual({ task: true }); + + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: "#1", + task: "test", + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "text", + alias: "step", + validation: {}, + }, + task: { + isEditable: true, + columnType: "text", + alias: "task", + validation: {}, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true, task: true }); + }); + + it("should return true for editable columns when validation is empty", () => { + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: "#1", + task: "test", + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "text", + alias: "step", + validation: {}, + }, + task: { + isEditable: true, + columnType: "text", + alias: "task", + validation: {}, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true, task: true }); + }); + + it("should return true for editable columns when isColumnEditableCellRequired is off and there is no value", () => { + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: "#1", + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "text", + alias: "step", + validation: { + isColumnEditableCellRequired: false, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: undefined, + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "text", + alias: "step", + validation: { + isColumnEditableCellRequired: false, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: null, + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "text", + alias: "step", + validation: { + isColumnEditableCellRequired: false, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + }); + + it("should return true for editable columns when isColumnEditableCellValid is true", () => { + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: null, + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "text", + alias: "step", + validation: { + isColumnEditableCellValid: true, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + }); + + it("should return false for editable columns when isColumnEditableCellValid is false", () => { + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: "test", + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "text", + alias: "step", + validation: { + isColumnEditableCellValid: false, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: false }); + }); + + it("should return true for editable columns when regex is matching", () => { + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: "#1", + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "text", + alias: "step", + validation: { + regex: "^#1$", + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: "test", + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "text", + alias: "step", + validation: { + regex: "^test$", + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + }); + + it("should return false for editable columns when regex is not matching", () => { + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: "test", + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "text", + alias: "step", + validation: { + regex: "^#1$", + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: false }); + + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: "#1", + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "text", + alias: "step", + validation: { + regex: "^test$", + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: false }); + }); + + it("should return false for editable columns when isColumnEditableCellRequired is true and there is no value", () => { + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: "", + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "text", + alias: "step", + validation: { + isColumnEditableCellRequired: true, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: false }); + }); + + it("should return true for editable columns when isColumnEditableCellRequired and there is value", () => { + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: "test", + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "text", + alias: "step", + validation: { + isColumnEditableCellRequired: true, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + }); + + it("should return true for editable columns when value is above min", () => { + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: 1, + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "number", + alias: "step", + validation: { + min: 0, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + }); + + it("should return false for editable columns when value is below min", () => { + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: -1, + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "number", + alias: "step", + validation: { + min: 0, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: false }); + }); + + it("should return true for editable columns when value is below max", () => { + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: 2, + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "number", + alias: "step", + validation: { + max: 5, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + }); + + it("should return false for editable columns when value is above max", () => { + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: 6, + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "number", + alias: "step", + validation: { + max: 5, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: false }); + }); + + it("should return true for editable columns when value is matching all the validation criteria", () => { + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: "#1", + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "text", + alias: "step", + validation: { + isColumnEditableCellValid: false, + regex: "^#1$", + isColumnEditableCellRequired: false, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: false }); + + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: "#1", + }, + primaryColumns: { + step: { + isEditable: true, + alias: "step", + columnType: "text", + validation: { + isColumnEditableCellValid: true, + regex: "^#1$", + isColumnEditableCellRequired: false, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: "#1", + }, + primaryColumns: { + step: { + isEditable: true, + alias: "step", + columnType: "text", + validation: { + isColumnEditableCellValid: true, + regex: "^#1$", + isColumnEditableCellRequired: true, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true }); + + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: "#1", + }, + primaryColumns: { + step: { + isEditable: true, + alias: "step", + columnType: "text", + validation: { + isColumnEditableCellValid: true, + regex: "^#2$", + isColumnEditableCellRequired: true, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: false }); + + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: "#1", + }, + primaryColumns: { + step: { + isEditable: true, + alias: "step", + columnType: "text", + validation: { + isColumnEditableCellValid: true, + regex: "^#2$", + isColumnEditableCellRequired: false, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: false }); + }); + + it("should check that more than one column is validated at the same time", () => { + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: "#1", + task: "test", + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "text", + alias: "step", + validation: { + isColumnEditableCellValid: false, + regex: "^#1$", + isColumnEditableCellRequired: false, + }, + }, + task: { + isEditable: true, + columnType: "text", + alias: "task", + validation: { + isColumnEditableCellValid: true, + regex: "test", + isColumnEditableCellRequired: false, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: false, task: true }); + + expect( + getEditableCellValidity( + { + isAddRowInProgress: true, + editableCell: {}, + newRow: { + step: "#1", + task: "test", + }, + primaryColumns: { + step: { + isEditable: true, + columnType: "text", + alias: "step", + validation: { + isColumnEditableCellValid: true, + regex: "^#1$", + isColumnEditableCellRequired: false, + }, + }, + task: { + isEditable: true, + columnType: "text", + alias: "task", + validation: { + isColumnEditableCellValid: true, + regex: "test", + isColumnEditableCellRequired: false, + }, + }, + }, + }, + null, + _, + ), + ).toEqual({ step: true, task: true }); + }); + }); +}); diff --git a/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getFilteredTableData.test.js b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getFilteredTableData.test.js new file mode 100644 index 000000000000..bbf3dc841439 --- /dev/null +++ b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getFilteredTableData.test.js @@ -0,0 +1,1457 @@ +import _ from "lodash"; +import moment from "moment"; +import derivedProperty from "../../derived"; + +describe("Validates getFilteredTableData Properties", () => { + const inputWithDisplayText = { + processedTableData: [ + { url: "A.COM", __originalIndex__: 0 }, + { url: "B.COM", __originalIndex__: 1 }, + { url: "C.COM", __originalIndex__: 2 }, + { url: "D.COM", __originalIndex__: 3 }, + ], + sortOrder: { column: "url", order: "asc" }, + columnOrder: ["url"], + primaryColumns: { + url: { + index: 0, + width: 150, + id: "url", + alias: "url", + originalId: "url", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "url", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "awesome", + isAscOrder: undefined, + displayText: ["Z", "Y", "X", "W"], + computedValue: ["A.COM", "B.COM", "C.COM", "D.COM"], + }, + }, + tableColumns: [ + { + index: 0, + width: 150, + id: "url", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "url", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "awesome", + isAscOrder: undefined, + displayText: ["Z", "Y", "X", "W"], + computedValue: ["A.COM", "B.COM", "C.COM", "D.COM"], + }, + ], + }; + + it("validates generate filtered table data", () => { + const { getFilteredTableData } = derivedProperty; + const input = { + processedTableData: [ + { id: 123, name: "John Doe" }, + { id: 234, name: "Jane Doe" }, + ], + sortOrder: { column: "id", order: "desc" }, + columnOrder: ["name", "id", "extra"], + primaryColumns: { + id: { + index: 1, + width: 150, + id: "id", + originalId: "id", + alias: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + isAscOrder: false, + computedValue: [123, 234], + }, + name: { + index: 0, + width: 150, + id: "name", + originalId: "name", + alias: "name", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "awesome", + isAscOrder: undefined, + computedValue: ["John Doe", "Jane Doe"], + }, + extra: { + index: 2, + width: 150, + id: "extra", + originalId: "extra", + alias: "extra", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + label: "extra", + isAscOrder: undefined, + computedValue: ["Extra1", "Extra2"], + isDerived: true, + }, + }, + tableColumns: [ + { + index: 0, + width: 150, + id: "name", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "awesome", + isAscOrder: undefined, + computedValue: ["John Doe", "Jane Doe"], + }, + { + index: 1, + width: 150, + id: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + isAscOrder: false, + computedValue: [123, 234], + }, + { + index: 2, + width: 150, + id: "extra", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + label: "extra", + isAscOrder: undefined, + computedValue: ["Extra1", "Extra2"], + isDerived: true, + }, + ], + }; + + input.orderedTableColumns = Object.values(input.primaryColumns).sort( + (a, b) => { + return input.columnOrder[a.id] < input.columnOrder[b.id]; + }, + ); + + const expected = [ + { + id: 234, + name: "Jane Doe", + extra: "Extra2", + }, + { + id: 123, + name: "John Doe", + extra: "Extra1", + }, + ]; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + }); + + it("validates generated filtered table data for empty values", () => { + const { getFilteredTableData } = derivedProperty; + const input = { + processedTableData: [], + sortOrder: { column: "id", order: "desc" }, + columnOrder: ["name", "id"], + primaryColumns: {}, + columns: [], + orderedTableColumns: [], + }; + + const expected = []; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + }); + + it("validates generated filtered table data to be sorted correctly based on column type", () => { + const { getFilteredTableData } = derivedProperty; + const input = { + processedTableData: [ + { id: 1234, name: "Jim Doe" }, + { id: 123, name: "John Doe" }, + { id: 234, name: "Jane Doe" }, + ], + sortOrder: { column: "id", order: "desc" }, + columnOrder: ["name", "id", "extra"], + primaryColumns: { + id: { + index: 1, + width: 150, + id: "id", + alias: "id", + originalId: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "number", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + isAscOrder: false, + computedValue: [1234, 123, 234], + }, + name: { + index: 0, + width: 150, + id: "name", + alias: "name", + originalId: "name", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "awesome", + isAscOrder: undefined, + computedValue: ["Jim Doe", "John Doe", "Jane Doe"], + }, + extra: { + index: 2, + width: 150, + id: "extra", + alias: "extra", + originalId: "extra", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + label: "extra", + isAscOrder: undefined, + computedValue: ["", "Extra1", "Extra2"], + isDerived: true, + }, + }, + tableColumns: [ + { + index: 0, + width: 150, + id: "name", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "awesome", + isAscOrder: undefined, + computedValue: ["Jim Doe", "John Doe", "Jane Doe"], + }, + { + index: 1, + width: 150, + id: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "number", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + isAscOrder: false, + computedValue: [1234, 123, 234], + }, + { + index: 2, + width: 150, + id: "extra", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + label: "extra", + isAscOrder: undefined, + computedValue: ["", "Extra1", "Extra2"], + isDerived: true, + }, + ], + }; + + input.orderedTableColumns = Object.values(input.primaryColumns).sort( + (a, b) => { + return input.columnOrder[a.id] < input.columnOrder[b.id]; + }, + ); + + const expected = [ + { + id: 1234, + name: "Jim Doe", + extra: "", + }, + { + id: 234, + name: "Jane Doe", + extra: "Extra2", + }, + { + id: 123, + name: "John Doe", + extra: "Extra1", + }, + ]; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + }); + + it("validates generated filtered edited table data to be sorted correctly based on column type", () => { + const { getFilteredTableData } = derivedProperty; + const input = { + processedTableData: [ + { id: 123, name: "BAC", __originalIndex__: 0 }, + { id: 1234, name: "ABC", __originalIndex__: 1 }, + { id: 234, name: "CAB", __originalIndex__: 2 }, + ], + tableData: [ + { id: 123, name: "BAC" }, + { id: 1234, name: "ABC" }, + { id: 234, name: "CAB" }, + ], + sortOrder: { column: "name", order: "asc" }, + columnOrder: ["name", "id"], + primaryColumns: { + id: { + index: 1, + width: 150, + id: "id", + alias: "id", + originalId: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "number", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + isAscOrder: false, + }, + name: { + index: 0, + width: 150, + id: "name", + alias: "name", + originalId: "name", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "awesome", + isAscOrder: undefined, + computedValue: ["BAC", "ABC", "AAB"], + }, + }, + }; + + input.orderedTableColumns = Object.values(input.primaryColumns).sort( + (a, b) => { + return input.columnOrder[a.id] < input.columnOrder[b.id]; + }, + ); + + const expected = [ + { + id: 1234, + name: "ABC", + __originalIndex__: 1, + }, + { + id: 123, + name: "BAC", + __originalIndex__: 0, + }, + { + id: 234, + name: "AAB", + __originalIndex__: 2, + }, + ]; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + }); + + it("validates generated filtered table data with null values to be sorted correctly", () => { + const { getFilteredTableData } = derivedProperty; + const input = { + processedTableData: [ + { id: 1234, name: "Jim Doe", age: 28 }, + { id: 123, name: "John Doe" }, + { id: 234, name: "Jane Doe", age: 22 }, + { id: 2345, name: "Jane Doeson", age: 30 }, + ], + sortOrder: { column: "age", order: "desc" }, + columnOrder: ["name", "id", "age"], + primaryColumns: { + id: { + index: 1, + width: 150, + id: "id", + alias: "id", + originalId: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "number", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + isAscOrder: false, + computedValue: [1234, 123, 234, 2345], + }, + name: { + index: 0, + width: 150, + id: "name", + alias: "name", + originalId: "name", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "awesome", + isAscOrder: undefined, + computedValue: ["Jim Doe", "John Doe", "Jane Doe", "Jane Doeson"], + }, + age: { + index: 2, + width: 150, + id: "age", + alias: "age", + originalId: "age", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "number", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + label: "age", + isAscOrder: undefined, + computedValue: [28, null, 22, 30], + isDerived: true, + }, + }, + tableColumns: [ + { + index: 0, + width: 150, + id: "name", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "awesome", + isAscOrder: undefined, + computedValue: ["Jim Doe", "John Doe", "Jane Doe", "Jane Doeson"], + }, + { + index: 1, + width: 150, + id: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "number", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + isAscOrder: false, + computedValue: [1234, 123, 234], + }, + { + index: 2, + width: 150, + id: "age", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + label: "age", + isAscOrder: undefined, + computedValue: [28, null, 22, 30], + isDerived: true, + }, + ], + }; + + input.orderedTableColumns = Object.values(input.primaryColumns).sort( + (a, b) => { + return input.columnOrder[a.id] < input.columnOrder[b.id]; + }, + ); + + const expected = [ + { + id: 2345, + name: "Jane Doeson", + age: 30, + }, + { + id: 1234, + name: "Jim Doe", + age: 28, + }, + { + id: 234, + name: "Jane Doe", + age: 22, + }, + { + id: 123, + name: "John Doe", + age: null, + }, + ]; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + }); + + it("validates generated filtered table data with empty string values to be sorted correctly", () => { + const { getFilteredTableData } = derivedProperty; + const input = { + processedTableData: [ + { id: 1234, name: "Jim Doe", age: 28 }, + { id: 123, name: "" }, + { id: 234, name: "Jane Doe", age: 22 }, + { id: 2345, name: "Jane Doeson", age: 30 }, + ], + sortOrder: { column: "name", order: "desc" }, + columnOrder: ["name", "id", "age"], + primaryColumns: { + id: { + index: 1, + width: 150, + id: "id", + alias: "id", + originalId: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "number", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + isAscOrder: false, + computedValue: [1234, 123, 234, 2345], + }, + name: { + index: 0, + width: 150, + id: "name", + alias: "name", + originalId: "name", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "awesome", + isAscOrder: undefined, + computedValue: ["Jim Doe", "", "Jane Doe", "Jane Doeson"], + }, + age: { + index: 2, + width: 150, + id: "age", + alias: "age", + originalId: "age", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "number", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + label: "age", + isAscOrder: undefined, + computedValue: [28, null, 22, 30], + isDerived: true, + }, + }, + tableColumns: [ + { + index: 0, + width: 150, + id: "name", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "awesome", + isAscOrder: undefined, + computedValue: ["Jim Doe", "", "Jane Doe", "Jane Doeson"], + }, + { + index: 1, + width: 150, + id: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "number", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + isAscOrder: false, + computedValue: [1234, 123, 234], + }, + { + index: 2, + width: 150, + id: "age", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + label: "age", + isAscOrder: undefined, + computedValue: [28, null, 22, 30], + isDerived: true, + }, + ], + }; + + input.orderedTableColumns = Object.values(input.primaryColumns).sort( + (a, b) => { + return input.columnOrder[a.id] < input.columnOrder[b.id]; + }, + ); + + const expected = [ + { + id: 1234, + name: "Jim Doe", + age: 28, + }, + { + id: 2345, + name: "Jane Doeson", + age: 30, + }, + { + id: 234, + name: "Jane Doe", + age: 22, + }, + { + id: 123, + name: "", + age: null, + }, + ]; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + }); + + it("validates generated filtered table data with date values to be sorted correctly", () => { + const { getFilteredTableData } = derivedProperty; + const input = { + processedTableData: [ + { guid: "abc123", createdAt: 1678886400 }, + { guid: "def456", createdAt: 1747968000 }, + { guid: "ghi789", createdAt: 1646582400 }, + { guid: "jkl012", createdAt: 1668806400 }, + { guid: "mno345", createdAt: 1677840000 }, + { guid: "pqr678", createdAt: 1649670400 }, + { guid: "stu901", createdAt: 1683552000 }, + { guid: "vwx234", createdAt: 1642137600 }, + { guid: "yzab567", createdAt: 1661740800 }, + { guid: "cde890", createdAt: 1670563200 }, + ], + sortOrder: { column: "createdAt", order: "desc" }, + columnOrder: ["guid", "createdAt"], + primaryColumns: { + guid: { + allowCellWrapping: false, + allowSameOptionsInNewRow: true, + index: 0, + width: 150, + originalId: "guid", + id: "guid", + alias: "guid", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textSize: "0.875rem", + enableFilter: true, + enableSort: true, + isVisible: true, + isDisabled: false, + isCellEditable: false, + isEditable: false, + isCellVisible: true, + isDerived: false, + label: "guid", + isSaveVisible: true, + isDiscardVisible: true, + computedValue: [ + "abc123", + "def456", + "ghi789", + "jkl012", + "mno345", + "pqr678", + "stu901", + "vwx234", + "yzab567", + "cde890", + ], + sticky: "", + validation: {}, + currencyCode: "USD", + decimals: 0, + thousandSeparator: true, + notation: "standard", + textColor: "", + cellBackground: "", + fontStyle: "", + }, + createdAt: { + allowCellWrapping: false, + allowSameOptionsInNewRow: true, + index: 1, + width: 150, + originalId: "createdAt", + id: "createdAt", + alias: "createdAt", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "date", + textSize: "0.875rem", + enableFilter: true, + enableSort: true, + isVisible: true, + isDisabled: false, + isCellEditable: false, + isEditable: false, + isCellVisible: true, + isDerived: false, + label: "createdAt", + isSaveVisible: true, + isDiscardVisible: true, + computedValue: [ + 1678886400, 1747968000, 1646582400, 1668806400, 1677840000, + 1649670400, 1683552000, 1642137600, 1661740800, 1670563200, + ], + sticky: "", + validation: {}, + currencyCode: "USD", + decimals: 0, + thousandSeparator: true, + notation: "standard", + inputFormat: "Epoch", + textColor: "", + cellBackground: "", + fontStyle: "", + outputFormat: "", + }, + }, + }; + + input.orderedTableColumns = Object.values(input.primaryColumns).sort( + (a, b) => { + return input.columnOrder[a.id] < input.columnOrder[b.id]; + }, + ); + + const expected = input.processedTableData.sort((a, b) => { + return a.createdAt < b.createdAt ? 1 : -1; + }); + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + }); + + it("validates generated filtered table data to be filtered correctly in empty comparison", () => { + const { getFilteredTableData } = derivedProperty; + const input = { + processedTableData: [ + { id: 1234, name: "Jim Doe" }, + { id: 123, name: "John Doe" }, + { id: 234, name: "Jane Doe" }, + ], + filters: [ + { + condition: "empty", + column: "id", + value: "", + operator: "OR", + }, + ], + sortOrder: { column: "id", order: "desc" }, + columnOrder: ["name", "id"], + primaryColumns: { + id: { + index: 1, + width: 150, + id: "id", + alias: "id", + originalId: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "number", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + isAscOrder: false, + computedValue: [1234, 123, 234], + }, + name: { + index: 0, + width: 150, + id: "name", + alias: "name", + originalId: "name", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "awesome", + isAscOrder: undefined, + computedValue: ["Jim Doe", "John Doe", "Jane Doe"], + }, + extra: { + index: 2, + width: 150, + id: "extra", + alias: "extra", + originalId: "extra", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + label: "extra", + isAscOrder: undefined, + computedValue: ["", "Extra1", "Extra2"], + isDerived: true, + }, + }, + tableColumns: [ + { + index: 0, + width: 150, + id: "name", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "awesome", + isAscOrder: undefined, + computedValue: ["Jim Doe", "John Doe", "Jane Doe"], + }, + { + index: 1, + width: 150, + id: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "number", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + isAscOrder: false, + computedValue: [1234, 123, 234], + }, + { + index: 2, + width: 150, + id: "extra", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + label: "extra", + isAscOrder: undefined, + computedValue: ["", "Extra1", "Extra2"], + isDerived: true, + }, + ], + }; + + input.orderedTableColumns = Object.values(input.primaryColumns).sort( + (a, b) => { + return input.columnOrder[a.id] < input.columnOrder[b.id]; + }, + ); + + const expected = []; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + }); + + it("should filter correctly after editing a value with an applied filter", () => { + const { getFilteredTableData } = derivedProperty; + const input = { + tableData: [ + { id: 1234, name: "Jim Doe" }, + { id: 123, name: "Hamza Khafaga" }, + { id: 234, name: "Khadija Khafaga" }, + ], + processedTableData: [ + { id: 1234, name: "Jim Doe", __originalIndex__: 0 }, + { id: 123, name: "Hamza Anas", __originalIndex__: 1 }, + { id: 234, name: "Khadija Khafaga", __originalIndex__: 2 }, + ], + filters: [ + { + condition: "contains", + column: "name", + value: "Khafaga", + }, + ], + sortOrder: { column: "id", order: "desc" }, + columnOrder: ["name", "id"], + primaryColumns: { + id: { + index: 1, + width: 150, + id: "id", + alias: "id", + originalId: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "number", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + isAscOrder: false, + }, + name: { + index: 0, + width: 150, + id: "name", + alias: "name", + originalId: "name", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "awesome", + isAscOrder: undefined, + }, + }, + tableColumns: [ + { + index: 0, + width: 150, + id: "name", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "awesome", + isAscOrder: undefined, + }, + { + index: 1, + width: 150, + id: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "number", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + isAscOrder: false, + }, + ], + }; + + input.orderedTableColumns = Object.values(input.primaryColumns).sort( + (a, b) => { + return input.columnOrder[a.id] < input.columnOrder[b.id]; + }, + ); + + const expected = [ + { id: 234, name: "Khadija Khafaga", __originalIndex__: 2 }, + { id: 123, name: "Hamza Anas", __originalIndex__: 1 }, + ]; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + }); + + it("validates generated sanitized table data with valid property keys", () => { + const { getProcessedTableData } = derivedProperty; + + const input = { + transientTableData: {}, + tableData: [ + { + 1: "abc", + 2: "bcd", + 3: "cde", + Dec: "mon", + demo: "3", + demo_1: "1", + "test one": "1", + "test 3 4 9": "4", + rowIndex: "0", + "😀smile😀": "smile 1", + "🙁sad🙁": "sad 1", + "@user": "user 1", + "@name": "name 1", + ÜserÑame: "john", + }, + { + 1: "asd", + 2: "dfg", + 3: "jkl", + Dec: "mon2", + demo: "2", + demo_1: "1", + "test one": "2", + "test 3 4 9": "3", + rowIndex: "1", + "😀smile😀": "smile 2", + "🙁sad🙁": "sad 2", + "@user": "user 2", + "@name": "name 2", + ÜserÑame: "mike", + }, + ], + }; + const expected = [ + { + 1: "abc", + 2: "bcd", + 3: "cde", + Dec: "mon", + demo: "3", + demo_1: "1", + "test one": "1", + "test 3 4 9": "4", + rowIndex: "0", + "😀smile😀": "smile 1", + "🙁sad🙁": "sad 1", + "@user": "user 1", + "@name": "name 1", + ÜserÑame: "john", + __originalIndex__: 0, + __primaryKey__: undefined, + }, + { + 1: "asd", + 2: "dfg", + 3: "jkl", + Dec: "mon2", + demo: "2", + demo_1: "1", + "test one": "2", + "test 3 4 9": "3", + rowIndex: "1", + "😀smile😀": "smile 2", + "🙁sad🙁": "sad 2", + "@user": "user 2", + "@name": "name 2", + ÜserÑame: "mike", + __originalIndex__: 1, + __primaryKey__: undefined, + }, + ]; + + let result = getProcessedTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + }); + + it("validate generated sorted table data for URL columntype with display text property", () => { + const { getFilteredTableData } = derivedProperty; + const input = { ...inputWithDisplayText }; + + input.orderedTableColumns = Object.values(input.primaryColumns).sort( + (a, b) => { + return input.columnOrder[a.id] < input.columnOrder[b.id]; + }, + ); + + const expected = [ + { url: "D.COM", __originalIndex__: 3 }, + { url: "C.COM", __originalIndex__: 2 }, + { url: "B.COM", __originalIndex__: 1 }, + { url: "A.COM", __originalIndex__: 0 }, + ]; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + }); + + it("validate filters on table data for URL columntype with display text", () => { + const { getFilteredTableData } = derivedProperty; + const input = { + ...inputWithDisplayText, + filters: [ + { + condition: "contains", + column: "url", + value: "Y", + }, + ], + }; + + input.orderedTableColumns = Object.values(input.primaryColumns).sort( + (a, b) => { + return input.columnOrder[a.id] < input.columnOrder[b.id]; + }, + ); + + const expected = [{ url: "B.COM", __originalIndex__: 1 }]; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + }); + + it("validate search on table data for URL columntype with display text", () => { + const { getFilteredTableData } = derivedProperty; + const input = { + ...inputWithDisplayText, + searchText: "Y", + enableClientSideSearch: true, + }; + + input.orderedTableColumns = Object.values(input.primaryColumns).sort( + (a, b) => { + return input.columnOrder[a.id] < input.columnOrder[b.id]; + }, + ); + + const expected = [{ url: "B.COM", __originalIndex__: 1 }]; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + }); + + it("filters correctly after editing a value with an applied search key", () => { + const { getFilteredTableData } = derivedProperty; + const input = { + tableData: [ + { id: 1234, name: "Jim Doe" }, + { id: 123, name: "Hamza Khafaga" }, + { id: 234, name: "Khadija Khafaga" }, + ], + processedTableData: [ + { id: 1234, name: "Jim Doe", __originalIndex__: 0 }, + { id: 123, name: "Hamza Anas", __originalIndex__: 1 }, + { id: 234, name: "Khadija Khafaga", __originalIndex__: 2 }, + ], + searchText: "Khafaga", + sortOrder: { column: "id", order: "desc" }, + columnOrder: ["name", "id"], + primaryColumns: { + id: { + index: 1, + width: 150, + id: "id", + alias: "id", + originalId: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "number", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + isAscOrder: false, + }, + name: { + index: 0, + width: 150, + id: "name", + alias: "name", + originalId: "name", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "awesome", + isAscOrder: undefined, + }, + }, + tableColumns: [ + { + index: 0, + width: 150, + id: "name", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "awesome", + isAscOrder: undefined, + }, + { + index: 1, + width: 150, + id: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "number", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + isAscOrder: false, + }, + ], + }; + + input.orderedTableColumns = Object.values(input.primaryColumns).sort( + (a, b) => { + return input.columnOrder[a.id] < input.columnOrder[b.id]; + }, + ); + + const expected = [ + { id: 234, name: "Khadija Khafaga", __originalIndex__: 2 }, + { id: 123, name: "Hamza Anas", __originalIndex__: 1 }, + ]; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + }); +}); diff --git a/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getOrderedTableColumns.test.js b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getOrderedTableColumns.test.js new file mode 100644 index 000000000000..f4babbaa7c45 --- /dev/null +++ b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getOrderedTableColumns.test.js @@ -0,0 +1,169 @@ +import _ from "lodash"; +import moment from "moment"; +import derivedProperty from "../../derived"; + +describe("Validate getOrderedTableColumns function", () => { + it("should test tht it returns the columns array from the primaryColumn", () => { + const { getOrderedTableColumns } = derivedProperty; + + const input = { + columnOrder: ["id", "name"], + primaryColumns: { + id: { + index: 0, + id: "id", + }, + name: { + index: 1, + id: "name", + }, + }, + }; + + const expected = [ + { + index: 0, + id: "id", + isAscOrder: undefined, + }, + { + index: 1, + id: "name", + isAscOrder: undefined, + }, + ]; + + expect(getOrderedTableColumns(input, moment, _)).toStrictEqual(expected); + }); + + it("should test that it returns the columns array from the primaryColumn based on column order", () => { + const { getOrderedTableColumns } = derivedProperty; + + const input = { + columnOrder: ["name", "id"], + primaryColumns: { + id: { + index: 0, + id: "id", + }, + name: { + index: 1, + id: "name", + }, + }, + }; + + const expected = [ + { + index: 0, + id: "name", + isAscOrder: undefined, + }, + { + index: 1, + id: "id", + isAscOrder: undefined, + }, + ]; + + expect(getOrderedTableColumns(input, moment, _)).toStrictEqual(expected); + }); + + it("should test that it returns the columns array from the primaryColumn based on column order and sets sort order details", () => { + const { getOrderedTableColumns } = derivedProperty; + + let input = { + columnOrder: ["name", "id"], + primaryColumns: { + id: { + index: 0, + id: "id", + }, + name: { + index: 1, + id: "name", + }, + }, + sortOrder: { + column: "name", + order: "asc", + }, + }; + + let expected = [ + { + index: 0, + id: "name", + isAscOrder: true, + }, + { + index: 1, + id: "id", + isAscOrder: undefined, + }, + ]; + + expect(getOrderedTableColumns(input, moment, _)).toStrictEqual(expected); + + input = { + columnOrder: ["name", "id"], + primaryColumns: { + id: { + index: 0, + id: "id", + }, + name: { + index: 1, + id: "name", + }, + }, + sortOrder: { + column: "name", + order: "desc", + }, + }; + + expected = [ + { + index: 0, + id: "name", + isAscOrder: false, + }, + { + index: 1, + id: "id", + isAscOrder: undefined, + }, + ]; + + expect(getOrderedTableColumns(input, moment, _)).toStrictEqual(expected); + }); + + it("should test that it removes the column with empty name", () => { + const { getOrderedTableColumns } = derivedProperty; + + const input = { + columnOrder: ["name", ""], + primaryColumns: { + "": { + index: 0, + id: "", + }, + name: { + index: 1, + id: "name", + }, + }, + }; + + const expected = [ + { + index: 0, + id: "name", + isAscOrder: undefined, + }, + ]; + + expect(getOrderedTableColumns(input, moment, _)).toStrictEqual(expected); + }); +}); diff --git a/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getPageOffset.test.js b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getPageOffset.test.js new file mode 100644 index 000000000000..9b80b1619245 --- /dev/null +++ b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getPageOffset.test.js @@ -0,0 +1,91 @@ +import derivedProperty from "../../derived"; + +describe("getPageOffset -", () => { + it("should return 0 when pageNo is null", () => { + const { getPageOffset } = derivedProperty; + + expect( + getPageOffset({ + pageNo: null, + pageSize: 0, + }), + ).toEqual(0); + }); + + it("should return 0 when pageSize is null", () => { + const { getPageOffset } = derivedProperty; + + expect( + getPageOffset({ + pageNo: 0, + pageSize: null, + }), + ).toEqual(0); + }); + + it("should return 0 when pageSize is undefined", () => { + const { getPageOffset } = derivedProperty; + + expect( + getPageOffset({ + pageNo: 0, + pageSize: undefined, + }), + ).toEqual(0); + }); + + it("should return 0 when pageNo is undefined", () => { + const { getPageOffset } = derivedProperty; + + expect( + getPageOffset({ + pageNo: undefined, + pageSize: 0, + }), + ).toEqual(0); + }); + + it("should return 0 when pageSize is 0 and pageNo is any random number >= 0", () => { + const { getPageOffset } = derivedProperty; + + expect( + getPageOffset({ + pageNo: 10, + pageSize: 0, + }), + ).toEqual(0); + }); + + it("should return 0 when pageNo is 0 and pageSize is any random number >= 0", () => { + const { getPageOffset } = derivedProperty; + + expect( + getPageOffset({ + pageNo: 0, + pageSize: 100, + }), + ).toEqual(0); + }); + + it("should return 0 when pageNo is NaN", () => { + const { getPageOffset } = derivedProperty; + + expect( + getPageOffset({ + pageNo: NaN, + pageSize: 0, + }), + ).toEqual(0); + }); + + it("should return 10 when pageSize is 5 and pageNo is 3", () => { + const { getPageOffset } = derivedProperty; + + expect( + getPageOffset({ + pageNo: 3, + pageSize: 5, + }), + ).toEqual(10); + }); +}); diff --git a/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getSelectedRow.test.js b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getSelectedRow.test.js new file mode 100644 index 000000000000..afcbb3908fee --- /dev/null +++ b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getSelectedRow.test.js @@ -0,0 +1,244 @@ +import _ from "lodash"; +import moment from "moment"; +import derivedProperty from "../../derived"; + +import { samplePrimaryColumns, sampleProcessedTableData } from "./fixture"; +describe("Validate getSelectedRow function", () => { + it("Multple row selection, with selected rows", () => { + const { getSelectedRow } = derivedProperty; + const input = { + multiRowSelection: true, + selectedRowIndices: [0, 1], + selectedRowIndex: 1, + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getSelectedRow(input, moment, _)).toStrictEqual({ + id: 234, + name: "Jane Doe", + extra: "Extra2", + }); + }); + + it("Multple row selection, with no selected rows", () => { + const { getSelectedRow } = derivedProperty; + const input = { + multiRowSelection: true, + selectedRowIndices: [], + selectedRowIndex: 1, + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getSelectedRow(input, moment, _)).toStrictEqual({ + id: "", + name: "", + extra: "", + }); + }); + + it("Single row selection, with selected row", () => { + const { getSelectedRow } = derivedProperty; + const input = { + multiRowSelection: false, + selectedRowIndices: [], + selectedRowIndex: 1, + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getSelectedRow(input, moment, _)).toStrictEqual({ + id: 234, + name: "Jane Doe", + extra: "Extra2", + }); + }); + + it("Single row selection, without selected row", () => { + const { getSelectedRow } = derivedProperty; + const input = { + multiRowSelection: true, + selectedRowIndices: [], + selectedRowIndex: -1, + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getSelectedRow(input, moment, _)).toStrictEqual({ + id: "", + name: "", + extra: "", + }); + }); + + it("should return empty row when selectedRowIndices is a string value 'test'", () => { + const { getSelectedRow } = derivedProperty; + const input = { + multiRowSelection: true, + selectedRowIndices: ["test"], + selectedRowIndex: -1, + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getSelectedRow(input, moment, _)).toStrictEqual({ + id: "", + name: "", + extra: "", + }); + }); + + it("should return empty row when selectedRowIndices is undefined", () => { + const { getSelectedRow } = derivedProperty; + const input = { + multiRowSelection: true, + selectedRowIndices: undefined, + selectedRowIndex: -1, + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getSelectedRow(input, moment, _)).toStrictEqual({ + id: "", + name: "", + extra: "", + }); + }); + + it("should return empty row when selectedRowIndices contains undefined value", () => { + const { getSelectedRow } = derivedProperty; + const input = { + multiRowSelection: true, + selectedRowIndices: [undefined], + selectedRowIndex: -1, + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getSelectedRow(input, moment, _)).toStrictEqual({ + id: "", + name: "", + extra: "", + }); + }); + + it("should return empty row when selectedRowIndices contains null value", () => { + const { getSelectedRow } = derivedProperty; + const input = { + multiRowSelection: true, + selectedRowIndices: [null], + selectedRowIndex: -1, + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getSelectedRow(input, moment, _)).toStrictEqual({ + id: "", + name: "", + extra: "", + }); + }); + + it("should return empty row when selectedRowIndices contains string numbers", () => { + const { getSelectedRow } = derivedProperty; + const input = { + multiRowSelection: true, + selectedRowIndices: ["1", "2"], + selectedRowIndex: -1, + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getSelectedRow(input, moment, _)).toStrictEqual({ + id: "", + name: "", + extra: "", + }); + }); + + it("should return empty row when selectedRowIndices is a single string number", () => { + const { getSelectedRow } = derivedProperty; + const input = { + multiRowSelection: true, + selectedRowIndices: "1", + selectedRowIndex: -1, + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getSelectedRow(input, moment, _)).toStrictEqual({ + id: "", + name: "", + extra: "", + }); + }); + + it("should return empty row when selectedRowIndices is a non-numeric string", () => { + const { getSelectedRow } = derivedProperty; + const input = { + multiRowSelection: true, + selectedRowIndices: "test", + selectedRowIndex: -1, + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getSelectedRow(input, moment, _)).toStrictEqual({ + id: "", + name: "", + extra: "", + }); + }); + + it("Single row selection should not have non data columns", () => { + const { getSelectedRow } = derivedProperty; + + const input = { + multiRowSelection: false, + selectedRowIndices: [], + selectedRowIndex: 1, + processedTableData: sampleProcessedTableData, + primaryColumns: samplePrimaryColumns, + }; + + expect(getSelectedRow(input, moment, _)).toStrictEqual({ + step: "#2", + task: "Create a query fetch_users with the Mock DB", + status: "--", + }); + }); +}); diff --git a/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getSelectedRows.test.js b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getSelectedRows.test.js new file mode 100644 index 000000000000..b4d16bdfd4c0 --- /dev/null +++ b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getSelectedRows.test.js @@ -0,0 +1,99 @@ +import _ from "lodash"; +import moment from "moment"; +import derivedProperty from "../../derived"; +import { samplePrimaryColumns, sampleProcessedTableData } from "./fixture"; + +describe("Validate getSelectedRows function", () => { + it("with valid index", () => { + const { getSelectedRows } = derivedProperty; + const input = { + multiRowSelection: true, + selectedRowIndices: [1], + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getSelectedRows(input, moment, _)).toStrictEqual([ + { + id: 234, + name: "Jane Doe", + extra: "Extra2", + }, + ]); + }); + + it("with valid indices", () => { + const { getSelectedRows } = derivedProperty; + const input = { + multiRowSelection: true, + selectedRowIndices: [0, 1], + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getSelectedRows(input, moment, _)).toStrictEqual([ + { + id: 1234, + name: "Jim Doe", + extra: "", + }, + { + id: 234, + name: "Jane Doe", + extra: "Extra2", + }, + ]); + }); + + it("with invalid indices", () => { + const { getSelectedRows } = derivedProperty; + const input = { + selectedRowIndices: [0, "test"], + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getSelectedRows(input, moment, _)).toStrictEqual([]); + }); + + it("with no indices", () => { + const { getSelectedRows } = derivedProperty; + const input = { + selectedRowIndices: [], + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getSelectedRows(input, moment, _)).toStrictEqual([]); + }); + + it("for removal of non data columns", () => { + const { getSelectedRows } = derivedProperty; + const input = { + multiRowSelection: true, + selectedRowIndices: [1], + processedTableData: sampleProcessedTableData, + primaryColumns: samplePrimaryColumns, + }; + + expect(getSelectedRows(input, moment, _)).toStrictEqual([ + { + step: "#2", + task: "Create a query fetch_users with the Mock DB", + status: "--", + }, + ]); + }); +}); diff --git a/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getTriggeredRow.test.js b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getTriggeredRow.test.js new file mode 100644 index 000000000000..220dde96fb14 --- /dev/null +++ b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getTriggeredRow.test.js @@ -0,0 +1,111 @@ +import _ from "lodash"; +import moment from "moment"; +import derivedProperty from "../../derived"; +import { samplePrimaryColumns, sampleProcessedTableData } from "./fixture"; + +describe("Validate getTriggeredRow function", () => { + it("with valid triggered row index", () => { + const { getTriggeredRow } = derivedProperty; + const input = { + triggeredRowIndex: 1, + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getTriggeredRow(input, moment, _)).toStrictEqual({ + id: 123, + name: "John Doe", + extra: "Extra1", + }); + }); + + it("with valid triggered row index", () => { + const { getTriggeredRow } = derivedProperty; + const input = { + triggeredRowIndex: 0, + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getTriggeredRow(input, moment, _)).toStrictEqual({ + id: 1234, + name: "Jim Doe", + extra: "", + }); + }); + + it("with triggered row index -1", () => { + const { getTriggeredRow } = derivedProperty; + const input = { + triggeredRowIndex: -1, + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getTriggeredRow(input, moment, _)).toStrictEqual({ + id: "", + name: "", + extra: "", + }); + }); + + it("with invalid triggered row index", () => { + const { getTriggeredRow } = derivedProperty; + const input = { + triggeredRowIndex: "test", + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getTriggeredRow(input, moment, _)).toStrictEqual({ + id: "", + name: "", + extra: "", + }); + }); + + it("with invalid triggered row index", () => { + const { getTriggeredRow } = derivedProperty; + const input = { + triggeredRowIndex: undefined, + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getTriggeredRow(input, moment, _)).toStrictEqual({ + id: "", + name: "", + extra: "", + }); + }); + + it("for removal of non data columns", () => { + const { getTriggeredRow } = derivedProperty; + const input = { + triggeredRowIndex: 1, + processedTableData: sampleProcessedTableData, + primaryColumns: samplePrimaryColumns, + }; + + expect(getTriggeredRow(input, moment, _)).toStrictEqual({ + step: "#2", + task: "Create a query fetch_users with the Mock DB", + status: "--", + }); + }); +}); diff --git a/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getUpdatedRow.test.js b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getUpdatedRow.test.js new file mode 100644 index 000000000000..3293839f8aac --- /dev/null +++ b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getUpdatedRow.test.js @@ -0,0 +1,99 @@ +import _ from "lodash"; +import moment from "moment"; +import derivedProperty from "../../derived"; +import { samplePrimaryColumns, sampleProcessedTableData } from "./fixture"; + +describe("validate getUpdatedRow", () => { + it("should check that valid updated row index returns the valid value", () => { + const { getUpdatedRow } = derivedProperty; + const input1 = { + updatedRowIndex: 1, + processedTableData: [ + { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe1", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + const input2 = { + updatedRowIndex: 0, + processedTableData: [ + { id: 1, name: "Lorem Ipsum", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getUpdatedRow(input1, moment, _)).toStrictEqual({ + id: 123, + name: "John Doe1", + extra: "Extra1", + }); + expect(getUpdatedRow(input2, moment, _)).toStrictEqual({ + id: 1, + name: "Lorem Ipsum", + extra: "", + }); + }); + + it("should check that it returns empty values when updateRowIndex is invalid or -1", () => { + const { getUpdatedRow } = derivedProperty; + const input1 = { + updatedRowIndex: -1, + processedTableData: [ + { id: 1, name: "Lorem Ipsum", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + const input2 = { + updatedRowIndex: "dummyIndex", + processedTableData: [ + { id: 1, name: "Lorem Ipsum", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + const input3 = { + updatedRowIndex: undefined, + processedTableData: [ + { id: 1, name: "Lorem Ipsum", extra: "", __originalIndex__: 0 }, + { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, + { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, + ], + }; + + expect(getUpdatedRow(input1, moment, _)).toStrictEqual({ + id: "", + name: "", + extra: "", + }); + + expect(getUpdatedRow(input2, moment, _)).toStrictEqual({ + id: "", + name: "", + extra: "", + }); + + expect(getUpdatedRow(input3, moment, _)).toStrictEqual({ + id: "", + name: "", + extra: "", + }); + }); + + it("should check that it removes non data columns", () => { + const { getUpdatedRow } = derivedProperty; + const input = { + updatedRowIndex: 1, + processedTableData: sampleProcessedTableData, + primaryColumns: samplePrimaryColumns, + }; + + expect(getUpdatedRow(input, moment, _)).toStrictEqual({ + step: "#2", + task: "Create a query fetch_users with the Mock DB", + status: "--", + }); + }); +}); diff --git a/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getUpdatedRowIndices.test.js b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getUpdatedRowIndices.test.js new file mode 100644 index 000000000000..fbb1f28fcacb --- /dev/null +++ b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getUpdatedRowIndices.test.js @@ -0,0 +1,64 @@ +import derivedProperty from "../../derived"; + +describe("getUpdatedRowIndices -", () => { + it("should test that it returns empty array when transientTableData is empty", () => { + const { getUpdatedRowIndices } = derivedProperty; + + expect( + getUpdatedRowIndices({ + transientTableData: {}, + }), + ).toEqual([]); + }); + + it("should test that it returns empty array when transientTableData is null", () => { + const { getUpdatedRowIndices } = derivedProperty; + + expect( + getUpdatedRowIndices({ + transientTableData: null, + }), + ).toEqual([]); + }); + + it("should test that it returns empty array when transientTableData is undefined", () => { + const { getUpdatedRowIndices } = derivedProperty; + + expect( + getUpdatedRowIndices({ + transientTableData: undefined, + }), + ).toEqual([]); + }); + + it("should test that it returns empty array when transientTableData has one value", () => { + const { getUpdatedRowIndices } = derivedProperty; + + expect( + getUpdatedRowIndices({ + transientTableData: { + 1: { + column1: "newValue", + }, + }, + }), + ).toEqual([1]); + }); + + it("should test that it returns empty array when transientTableData has two value", () => { + const { getUpdatedRowIndices } = derivedProperty; + + expect( + getUpdatedRowIndices({ + transientTableData: { + 1: { + column1: "newValue", + }, + 2: { + column1: "newValue", + }, + }, + }), + ).toEqual([1, 2]); + }); +}); diff --git a/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getUpdatedRows.test.js b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getUpdatedRows.test.js new file mode 100644 index 000000000000..e4c8d3167f4c --- /dev/null +++ b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/getUpdatedRows.test.js @@ -0,0 +1,243 @@ +import _ from "lodash"; +import moment from "moment"; +import derivedProperty from "../../derived"; +import { samplePrimaryColumns, sampleProcessedTableData } from "./fixture"; + +describe("getUpdatedRows -", () => { + it("should test that it returns empty array when transientTableData is empty", () => { + const { getUpdatedRows } = derivedProperty; + + expect( + getUpdatedRows( + { + transientTableData: {}, + }, + null, + _, + ), + ).toEqual([]); + }); + + it("should test that it returns empty array when transientTableData is null", () => { + const { getUpdatedRows } = derivedProperty; + + expect( + getUpdatedRows( + { + transientTableData: null, + }, + null, + _, + ), + ).toEqual([]); + }); + + it("should test that it returns empty array when transientTableData is undefined", () => { + const { getUpdatedRows } = derivedProperty; + + expect( + getUpdatedRows( + { + transientTableData: null, + }, + null, + _, + ), + ).toEqual([]); + }); + + it("should test that it returns expected array when transientTableData has data with invalid index", () => { + const { getUpdatedRows } = derivedProperty; + + const input = { + transientTableData: { + test: { + column1: "newValue", + }, + }, + processedTableData: [ + { + column1: "oldValue", + column2: "oldValue", + __originalIndex__: 0, + }, + { + column1: "newValue", + column2: "oldValue", + __originalIndex__: 1, + }, + ], + }; + + const expected = []; + + expect(getUpdatedRows(input, null, _)).toEqual(expected); + }); + + it("should test that it returns expected array when transientTableData has data", () => { + const { getUpdatedRows } = derivedProperty; + + const input = { + transientTableData: { + 1: { + column1: "newValue", + }, + }, + processedTableData: [ + { + column1: "oldValue", + column2: "oldValue", + __originalIndex__: 0, + }, + { + column1: "newValue", + column2: "oldValue", + __originalIndex__: 1, + }, + ], + }; + + const expected = [ + { + index: 1, + updatedFields: { + column1: "newValue", + }, + allFields: { + column1: "newValue", + column2: "oldValue", + }, + }, + ]; + + expect(getUpdatedRows(input, null, _)).toEqual(expected); + }); + + it("should test that it returns expected array when transientTableData has data with primary column", () => { + const { getUpdatedRows } = derivedProperty; + + const input = { + primaryColumnId: "column2", + transientTableData: { + 1: { + column1: "newValue", + }, + }, + processedTableData: [ + { + column1: "oldValue1", + column2: "oldValue1", + __originalIndex__: 0, + }, + { + column1: "newValue", + column2: "oldValue2", + __originalIndex__: 1, + }, + ], + }; + + const expected = [ + { + index: 1, + column2: "oldValue2", + updatedFields: { + column1: "newValue", + }, + allFields: { + column1: "newValue", + column2: "oldValue2", + }, + }, + ]; + + expect(getUpdatedRows(input, null, _)).toEqual(expected); + }); + + it("should test that it returns expected array when transientTableData has data with primary column and bigger tableData", () => { + const { getUpdatedRows } = derivedProperty; + + const input = { + primaryColumnId: "column3", + transientTableData: { + 1: { + column1: "newValue", + column2: "newValue1", + }, + }, + processedTableData: [ + { + column1: "oldValue1", + column2: "oldValue1", + column3: "oldValue1", + __originalIndex__: 0, + }, + { + column1: "newValue", + column2: "newValue1", + column3: "oldValue2", + __originalIndex__: 1, + }, + { + column1: "oldValue3", + column2: "oldValue3", + column3: "oldValue3", + __originalIndex__: 2, + }, + { + column1: "oldValue3", + column2: "oldValue3", + column3: "oldValue4", + __originalIndex__: 3, + }, + ], + }; + + const expected = [ + { + index: 1, + column3: "oldValue2", + updatedFields: { + column1: "newValue", + column2: "newValue1", + }, + allFields: { + column1: "newValue", + column2: "newValue1", + column3: "oldValue2", + }, + }, + ]; + + expect(getUpdatedRows(input, null, _)).toEqual(expected); + }); + + it("Verify for removal of non data columns", () => { + const { getUpdatedRows } = derivedProperty; + const input = { + transientTableData: { + 0: { + task: "Drop a table first", + }, + }, + primaryColumnId: "step", + processedTableData: sampleProcessedTableData, + primaryColumns: samplePrimaryColumns, + }; + + expect(getUpdatedRows(input, moment, _)).toStrictEqual([ + { + index: 0, + step: "#1", + updatedFields: { + task: "Drop a table first", + }, + allFields: { + step: "#1", + task: "Drop a table", + status: "✅", + }, + }, + ]); + }); +}); diff --git a/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/htmlColumns.test.js b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/htmlColumns.test.js new file mode 100644 index 000000000000..7e40f9055e53 --- /dev/null +++ b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/htmlColumns.test.js @@ -0,0 +1,579 @@ +import _ from "lodash"; +import moment from "moment"; +import derivedProperty from "../../derived"; + +describe("HTML columns", () => { + const input = { + tableData: [ + { + id: 1, + name: "Jim Doe", + status: "Active", + }, + { + id: 2, + name: "Usain Bolt", + status: "Pending", + }, + { + id: 3, + name: "Elon Musk", + status: "Active", + }, + ], + processedTableData: [ + { + id: 1, + name: "Jim Doe", + status: "Active", + __originalIndex__: 0, + }, + { + id: 2, + name: "Usain Bolt", + status: "Pending", + __originalIndex__: 1, + }, + { + id: 3, + name: "Elon Musk", + status: "Active", + __originalIndex__: 2, + }, + ], + sortOrder: { column: "id", order: "asc" }, + columnOrder: ["id", "name", "status"], + primaryColumns: { + id: { + index: 1, + width: 150, + id: "id", + alias: "id", + originalId: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "number", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + isAscOrder: false, + }, + name: { + index: 0, + width: 150, + id: "name", + alias: "name", + originalId: "name", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "awesome", + isAscOrder: undefined, + }, + status: { + index: 0, + width: 150, + id: "status", + alias: "status", + originalId: "status", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "html", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "Status", + isAscOrder: undefined, + }, + }, + tableColumns: [ + { + index: 0, + width: 150, + id: "name", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "text", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "awesome", + isAscOrder: undefined, + }, + { + index: 1, + width: 150, + id: "id", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "number", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "id", + isAscOrder: false, + }, + { + index: 0, + width: 150, + id: "status", + alias: "status", + originalId: "status", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "html", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "Status", + isAscOrder: undefined, + }, + ], + }; + + input.orderedTableColumns = Object.values(input.primaryColumns).sort( + (a, b) => { + return input.columnOrder[a.id] < input.columnOrder[b.id]; + }, + ); + const { getFilteredTableData } = derivedProperty; + + it("validate search on table for HTML columns", () => { + input.searchText = "Pending"; + const expected = [ + { + id: 2, + name: "Usain Bolt", + status: "Pending", + __originalIndex__: 1, + }, + ]; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + delete input.searchText; + }); + + it("validates filters on table for HTML columns", () => { + input.filters = [ + { + condition: "contains", + column: "status", + value: "Active", + }, + ]; + const expected = [ + { + id: 1, + name: "Jim Doe", + status: "Active", + __originalIndex__: 0, + }, + { + id: 3, + name: "Elon Musk", + status: "Active", + __originalIndex__: 2, + }, + ]; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + delete input.filters; + }); + + it("validates sort on table for HTML columns", () => { + input.sortOrder = { column: "status", order: "desc" }; + let expected = [ + { + id: 2, + name: "Usain Bolt", + status: "Pending", + __originalIndex__: 1, + }, + { + id: 1, + name: "Jim Doe", + status: "Active", + __originalIndex__: 0, + }, + { + id: 3, + name: "Elon Musk", + status: "Active", + __originalIndex__: 2, + }, + ]; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + + input.sortOrder = { column: "status", order: "asc" }; + expected = [ + { + id: 3, + name: "Elon Musk", + status: "Active", + __originalIndex__: 2, + }, + { + id: 1, + name: "Jim Doe", + status: "Active", + __originalIndex__: 0, + }, + + { + id: 2, + name: "Usain Bolt", + status: "Pending", + __originalIndex__: 1, + }, + ]; + + result = getFilteredTableData(input, moment, _); + expect(result).toStrictEqual(expected); + }); + + it("validates tags are not filterable in html content", () => { + input.filters = [ + { + condition: "contains", + column: "status", + value: "span", + }, + ]; + const expected = []; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + + input.filters = [ + { + condition: "contains", + column: "status", + value: "color", + }, + ]; + result = getFilteredTableData(input, moment, _); + expect(result).toStrictEqual(expected); + delete input.filters; + }); + it("validates tags are not searchable in html content", () => { + input.searchText = "span"; + + const expected = []; + + let result = getFilteredTableData(input, moment, _); + + expect(result).toStrictEqual(expected); + + input.searchText = "color"; + result = getFilteredTableData(input, moment, _); + expect(result).toStrictEqual(expected); + delete input.searchText; + }); + + it("validates multiple HTML column filters with AND condition", () => { + const multiFilterInput = _.cloneDeep(input); + + multiFilterInput.processedTableData = [ + { + id: 1, + name: "Jim Doe", + status: "Active", + role: "
Admin
", + __originalIndex__: 0, + }, + { + id: 2, + name: "Usain Bolt", + status: "Pending", + role: "
User
", + __originalIndex__: 1, + }, + { + id: 3, + name: "Elon Musk", + status: "Active", + role: "
Admin
", + __originalIndex__: 2, + }, + ]; + + multiFilterInput.primaryColumns.role = { + index: 3, + width: 150, + id: "role", + alias: "role", + originalId: "role", + horizontalAlignment: "LEFT", + verticalAlignment: "CENTER", + columnType: "html", + textColor: "#231F20", + textSize: "PARAGRAPH", + fontStyle: "REGULAR", + enableFilter: true, + enableSort: true, + isVisible: true, + isDerived: false, + label: "Role", + isAscOrder: undefined, + }; + + multiFilterInput.filters = [ + { + condition: "contains", + column: "status", + value: "Active", + }, + { + condition: "contains", + column: "role", + value: "Admin", + operator: "AND", + }, + ]; + + const expected = [ + { + id: 3, + name: "Elon Musk", + status: "Active", + role: "
Admin
", + __originalIndex__: 2, + }, + { + id: 1, + name: "Jim Doe", + status: "Active", + role: "
Admin
", + __originalIndex__: 0, + }, + ]; + + let result = getFilteredTableData(multiFilterInput, moment, _); + + expect(result).toStrictEqual(expected); + delete input.filters; + }); + + it("validates complex HTML content with nested elements and attributes", () => { + const complexHTMLInput = _.cloneDeep(input); + + complexHTMLInput.processedTableData = [ + { + id: 1, + name: "Jim Doe", + status: + '
Active
', + __originalIndex__: 0, + }, + { + id: 2, + name: "Usain Bolt", + status: + '
Pending
', + __originalIndex__: 1, + }, + { + id: 3, + name: "Elon Musk", + status: + '
Active
', + __originalIndex__: 2, + }, + ]; + + // Test searching through complex HTML + complexHTMLInput.searchText = "Active"; + let expected = [ + { + id: 3, + name: "Elon Musk", + status: + '
Active
', + __originalIndex__: 2, + }, + { + id: 1, + name: "Jim Doe", + status: + '
Active
', + __originalIndex__: 0, + }, + ]; + + let result = getFilteredTableData(complexHTMLInput, moment, _); + + expect(result).toStrictEqual(expected); + delete complexHTMLInput.searchText; + + // Test sorting with complex HTML + complexHTMLInput.sortOrder = { column: "status", order: "desc" }; + expected = [ + { + id: 2, + name: "Usain Bolt", + status: + '
Pending
', + __originalIndex__: 1, + }, + { + id: 1, + name: "Jim Doe", + status: + '
Active
', + __originalIndex__: 0, + }, + { + id: 3, + name: "Elon Musk", + status: + '
Active
', + __originalIndex__: 2, + }, + ]; + + result = getFilteredTableData(complexHTMLInput, moment, _); + expect(result).toStrictEqual(expected); + }); + + it("validates HTML columns with special characters and entities", () => { + const specialCharHTMLInput = _.cloneDeep(input); + + specialCharHTMLInput.processedTableData = [ + { + id: 1, + name: "Jim Doe", + status: "© Active & Ready", + __originalIndex__: 0, + }, + { + id: 2, + name: "Usain Bolt", + status: "Pending > Review", + __originalIndex__: 1, + }, + { + id: 3, + name: "Elon Musk", + status: "© Active & Ready", + __originalIndex__: 2, + }, + ]; + + // Test filtering with HTML entities + specialCharHTMLInput.filters = [ + { + condition: "contains", + column: "status", + value: "Active & Ready", + }, + ]; + + const expected = [ + { + id: 3, + name: "Elon Musk", + status: "© Active & Ready", + __originalIndex__: 2, + }, + { + id: 1, + name: "Jim Doe", + status: "© Active & Ready", + __originalIndex__: 0, + }, + ]; + + let result = getFilteredTableData(specialCharHTMLInput, moment, _); + + expect(result).toStrictEqual(expected); + delete specialCharHTMLInput.filters; + }); + + it("validates filtering with null and undefined values in HTML columns", () => { + const nullUndefinedInput = _.cloneDeep(input); + + nullUndefinedInput.processedTableData = [ + { + id: 1, + name: "Jim Doe", + status: null, + __originalIndex__: 0, + }, + { + id: 2, + name: "Usain Bolt", + status: undefined, + __originalIndex__: 1, + }, + { + id: 3, + name: "Elon Musk", + status: "Active", + __originalIndex__: 2, + }, + ]; + + // Test filtering for null values + nullUndefinedInput.filters = [ + { + condition: "contains", + column: "status", + value: "null", + }, + ]; + + let result = getFilteredTableData(nullUndefinedInput, moment, _); + + expect(result).toStrictEqual([]); + + // Test filtering for undefined values + nullUndefinedInput.filters = [ + { + condition: "contains", + column: "status", + value: "undefined", + }, + ]; + + result = getFilteredTableData(nullUndefinedInput, moment, _); + expect(result).toStrictEqual([]); + + delete nullUndefinedInput.filters; + }); +}); diff --git a/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/tableHeaders.test.js b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/tableHeaders.test.js new file mode 100644 index 000000000000..11224ee3afc0 --- /dev/null +++ b/app/client/src/widgets/TableWidgetV2/widget/__tests__/derived.test/tableHeaders.test.js @@ -0,0 +1,111 @@ +import derivedProperty from "../../derived"; + +describe("Validate tableHeaders function", () => { + const { getTableHeaders } = derivedProperty; + + it("should test that it returns empty array when primaryColumns is undefined", () => { + expect( + getTableHeaders({ + primaryColumns: undefined, + }), + ).toEqual([]); + }); + + it("should test that it returns expected array when primaryColumns value is undefined", () => { + expect( + getTableHeaders({ + primaryColumns: { + "some value": undefined, + }, + }), + ).toEqual([ + { + id: undefined, + label: undefined, + isVisible: undefined, + }, + ]); + }); + + it("should test that it returns expected array when primaryColumns data is undefined", () => { + expect( + getTableHeaders({ + primaryColumns: { + "some value": { + id: "some value", + label: undefined, + isVisible: true, + }, + }, + }), + ).toEqual([ + { + id: "some value", + label: undefined, + isVisible: true, + }, + ]); + }); + + it("should test that it returns expected array with the same length as that of primaryColumns", () => { + expect( + getTableHeaders({ + primaryColumns: { + "some value": { + id: "some value", + label: "some value", + isVisible: true, + }, + "some other value": { + id: "some other value", + label: "some other value", + isVisible: true, + }, + }, + }).length, + ).toEqual(2); + }); + + it("should test that it returns expected array sorted", () => { + expect( + getTableHeaders({ + primaryColumns: { + "value 02": { + id: "value 02", + label: "value 02", + isVisible: true, + index: "2", + }, + "value 03": { + id: "value 03", + label: "value 03", + isVisible: true, + index: "3", + }, + "value 01": { + id: "value 01", + label: "value 01", + isVisible: true, + index: "1", + }, + }, + }), + ).toEqual([ + { + id: "value 01", + label: "value 01", + isVisible: true, + }, + { + id: "value 02", + label: "value 02", + isVisible: true, + }, + { + id: "value 03", + label: "value 03", + isVisible: true, + }, + ]); + }); +}); diff --git a/app/client/src/widgets/TableWidgetV2/widget/propertyUtils.test.ts b/app/client/src/widgets/TableWidgetV2/widget/__tests__/propertyUtils.test.ts similarity index 99% rename from app/client/src/widgets/TableWidgetV2/widget/propertyUtils.test.ts rename to app/client/src/widgets/TableWidgetV2/widget/__tests__/propertyUtils.test.ts index 98af8638ccf1..fcb13bea2612 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/propertyUtils.test.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/__tests__/propertyUtils.test.ts @@ -9,10 +9,10 @@ import { updateCustomColumnAliasOnLabelChange, selectColumnOptionsValidation, allowedFirstDayOfWeekRange, -} from "./propertyUtils"; +} from "../propertyUtils"; import _ from "lodash"; -import type { ColumnTypes, TableWidgetProps } from "../constants"; -import { StickyType } from "../component/Constants"; +import type { ColumnTypes, TableWidgetProps } from "../../constants"; +import { StickyType } from "../../component/Constants"; describe("PropertyUtils - ", () => { it("totalRecordsCountValidation - should test with all possible values", () => { diff --git a/app/client/src/widgets/TableWidgetV2/widget/utilities.test.ts b/app/client/src/widgets/TableWidgetV2/widget/__tests__/utilities.test.ts similarity index 99% rename from app/client/src/widgets/TableWidgetV2/widget/utilities.test.ts rename to app/client/src/widgets/TableWidgetV2/widget/__tests__/utilities.test.ts index d1c8adcdf0c2..381a6b4024f3 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/utilities.test.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/__tests__/utilities.test.ts @@ -1,6 +1,6 @@ -import type { ColumnProperties, TableStyles } from "../component/Constants"; -import { StickyType } from "../component/Constants"; -import { ColumnTypes } from "../constants"; +import type { ColumnProperties, TableStyles } from "../../component/Constants"; +import { StickyType } from "../../component/Constants"; +import { ColumnTypes } from "../../constants"; import { convertNumToCompactString, escapeString, @@ -17,7 +17,7 @@ import { getSourceDataAndCaluclateKeysForEventAutoComplete, getTableStyles, reorderColumns, -} from "./utilities"; +} from "../utilities"; const getCurrentRowBinding = ( entityName: string, diff --git a/app/client/src/widgets/TableWidgetV2/widget/derived.test.js b/app/client/src/widgets/TableWidgetV2/widget/derived.test.js deleted file mode 100644 index 8b306b09207d..000000000000 --- a/app/client/src/widgets/TableWidgetV2/widget/derived.test.js +++ /dev/null @@ -1,4667 +0,0 @@ -import derivedProperty from "./derived"; -import moment from "moment"; -import _ from "lodash"; - -const samplePrimaryColumns = { - step: { - index: 0, - width: 150, - id: "step", - originalId: "step", - alias: "step", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "0.875rem", - enableFilter: true, - enableSort: true, - isVisible: true, - isCellVisible: true, - isCellEditable: false, - isDerived: false, - label: "step", - computedValue: ["#1", "#2", "#3"], - labelColor: "#FFFFFF", - cellBackground: "", - textColor: "", - fontStyle: "", - }, - task: { - index: 1, - width: 150, - id: "task", - originalId: "task", - alias: "task", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "0.875rem", - enableFilter: true, - enableSort: true, - isVisible: true, - isCellVisible: true, - isCellEditable: false, - isDerived: false, - label: "task", - computedValue: [ - "Drop a table", - "Create a query fetch_users with the Mock DB", - "Bind the query using => fetch_users.data", - ], - labelColor: "#FFFFFF", - cellBackground: "", - textColor: "", - fontStyle: "", - }, - status: { - index: 2, - width: 150, - id: "status", - originalId: "status", - alias: "status", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "0.875rem", - enableFilter: true, - enableSort: true, - isVisible: true, - isCellVisible: true, - isCellEditable: false, - isDerived: false, - label: "status", - computedValue: ["✅", "--", "--"], - labelColor: "#FFFFFF", - cellBackground: "", - textColor: "", - fontStyle: "", - }, - action: { - index: 3, - width: 150, - id: "action", - originalId: "action", - alias: "action", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "button", - textSize: "0.875rem", - enableFilter: true, - enableSort: true, - isVisible: true, - isCellVisible: true, - isCellEditable: false, - isDisabled: false, - isDerived: false, - label: "action", - onClick: - "{{currentRow.step === '#1' ? showAlert('Done', 'success') : currentRow.step === '#2' ? navigateTo('https://docs.appsmith.com/core-concepts/connecting-to-data-sources/querying-a-database',undefined,'NEW_WINDOW') : navigateTo('https://docs.appsmith.com/core-concepts/displaying-data-read/display-data-tables',undefined,'NEW_WINDOW')}}", - computedValue: ["", "", ""], - labelColor: "#FFFFFF", - buttonColor: ["#553DE9", "#553DE9", "#553DE9"], - borderRadius: ["0.375rem", "0.375rem", "0.375rem"], - boxShadow: ["none", "none", "none"], - buttonLabel: ["Action", "Action", "Action"], - buttonVariant: "PRIMARY", - }, - customColumn1: { - allowCellWrapping: false, - index: 4, - width: 150, - originalId: "customColumn1", - id: "customColumn1", - alias: "customColumn1", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "menuButton", - textSize: "0.875rem", - enableFilter: true, - enableSort: true, - isVisible: true, - isDisabled: false, - isCellEditable: false, - isEditable: false, - isCellVisible: true, - isDerived: true, - label: "menu", - isSaveVisible: true, - isDiscardVisible: true, - computedValue: "", - buttonStyle: "rgb(3, 179, 101)", - labelColor: "#FFFFFF", - menuColor: ["#553DE9", "#553DE9", "#553DE9"], - borderRadius: ["0.375rem", "0.375rem", "0.375rem"], - boxShadow: ["none", "none", "none"], - customAlias: "", - menuButtonLabel: ["Open Menu", "Open Menu", "Open Menu"], - menuVariant: "PRIMARY", - menuButtoniconName: "", - }, - customColumn2: { - allowCellWrapping: false, - index: 5, - width: 150, - originalId: "customColumn2", - id: "customColumn2", - alias: "customColumn2", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "iconButton", - textSize: "0.875rem", - enableFilter: true, - enableSort: true, - isVisible: true, - isDisabled: false, - isCellEditable: false, - isEditable: false, - isCellVisible: true, - isDerived: true, - label: "icon", - isSaveVisible: true, - isDiscardVisible: true, - computedValue: "", - buttonStyle: "rgb(3, 179, 101)", - labelColor: "#FFFFFF", - buttonColor: ["#553DE9", "#553DE9", "#553DE9"], - borderRadius: ["0.375rem", "0.375rem", "0.375rem"], - boxShadow: ["none", "none", "none"], - customAlias: "", - buttonVariant: "PRIMARY", - iconName: "add", - }, -}; -const sampleProcessedTableData = [ - { - step: "#1", - task: "Drop a table", - status: "✅", - action: "", - __originalIndex__: 0, - }, - { - step: "#2", - task: "Create a query fetch_users with the Mock DB", - status: "--", - action: "", - __originalIndex__: 1, - }, - { - step: "#3", - task: "Bind the query using => fetch_users.data", - status: "--", - action: "", - __originalIndex__: 2, - }, -]; - -describe("Validates getFilteredTableData Properties", () => { - const inputWithDisplayText = { - processedTableData: [ - { url: "A.COM", __originalIndex__: 0 }, - { url: "B.COM", __originalIndex__: 1 }, - { url: "C.COM", __originalIndex__: 2 }, - { url: "D.COM", __originalIndex__: 3 }, - ], - sortOrder: { column: "url", order: "asc" }, - columnOrder: ["url"], - primaryColumns: { - url: { - index: 0, - width: 150, - id: "url", - alias: "url", - originalId: "url", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "url", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "awesome", - isAscOrder: undefined, - displayText: ["Z", "Y", "X", "W"], - computedValue: ["A.COM", "B.COM", "C.COM", "D.COM"], - }, - }, - tableColumns: [ - { - index: 0, - width: 150, - id: "url", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "url", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "awesome", - isAscOrder: undefined, - displayText: ["Z", "Y", "X", "W"], - computedValue: ["A.COM", "B.COM", "C.COM", "D.COM"], - }, - ], - }; - - it("validates generate filtered table data", () => { - const { getFilteredTableData } = derivedProperty; - const input = { - processedTableData: [ - { id: 123, name: "John Doe" }, - { id: 234, name: "Jane Doe" }, - ], - sortOrder: { column: "id", order: "desc" }, - columnOrder: ["name", "id", "extra"], - primaryColumns: { - id: { - index: 1, - width: 150, - id: "id", - originalId: "id", - alias: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - isAscOrder: false, - computedValue: [123, 234], - }, - name: { - index: 0, - width: 150, - id: "name", - originalId: "name", - alias: "name", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "awesome", - isAscOrder: undefined, - computedValue: ["John Doe", "Jane Doe"], - }, - extra: { - index: 2, - width: 150, - id: "extra", - originalId: "extra", - alias: "extra", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - label: "extra", - isAscOrder: undefined, - computedValue: ["Extra1", "Extra2"], - isDerived: true, - }, - }, - tableColumns: [ - { - index: 0, - width: 150, - id: "name", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "awesome", - isAscOrder: undefined, - computedValue: ["John Doe", "Jane Doe"], - }, - { - index: 1, - width: 150, - id: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - isAscOrder: false, - computedValue: [123, 234], - }, - { - index: 2, - width: 150, - id: "extra", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - label: "extra", - isAscOrder: undefined, - computedValue: ["Extra1", "Extra2"], - isDerived: true, - }, - ], - }; - - input.orderedTableColumns = Object.values(input.primaryColumns).sort( - (a, b) => { - return input.columnOrder[a.id] < input.columnOrder[b.id]; - }, - ); - - const expected = [ - { - id: 234, - name: "Jane Doe", - extra: "Extra2", - }, - { - id: 123, - name: "John Doe", - extra: "Extra1", - }, - ]; - - let result = getFilteredTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - }); - - it("validates generated filtered table data for empty values", () => { - const { getFilteredTableData } = derivedProperty; - const input = { - processedTableData: [], - sortOrder: { column: "id", order: "desc" }, - columnOrder: ["name", "id"], - primaryColumns: {}, - columns: [], - orderedTableColumns: [], - }; - - const expected = []; - - let result = getFilteredTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - }); - - it("validates generated filtered table data to be sorted correctly based on column type", () => { - const { getFilteredTableData } = derivedProperty; - const input = { - processedTableData: [ - { id: 1234, name: "Jim Doe" }, - { id: 123, name: "John Doe" }, - { id: 234, name: "Jane Doe" }, - ], - sortOrder: { column: "id", order: "desc" }, - columnOrder: ["name", "id", "extra"], - primaryColumns: { - id: { - index: 1, - width: 150, - id: "id", - alias: "id", - originalId: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "number", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - isAscOrder: false, - computedValue: [1234, 123, 234], - }, - name: { - index: 0, - width: 150, - id: "name", - alias: "name", - originalId: "name", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "awesome", - isAscOrder: undefined, - computedValue: ["Jim Doe", "John Doe", "Jane Doe"], - }, - extra: { - index: 2, - width: 150, - id: "extra", - alias: "extra", - originalId: "extra", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - label: "extra", - isAscOrder: undefined, - computedValue: ["", "Extra1", "Extra2"], - isDerived: true, - }, - }, - tableColumns: [ - { - index: 0, - width: 150, - id: "name", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "awesome", - isAscOrder: undefined, - computedValue: ["Jim Doe", "John Doe", "Jane Doe"], - }, - { - index: 1, - width: 150, - id: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "number", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - isAscOrder: false, - computedValue: [1234, 123, 234], - }, - { - index: 2, - width: 150, - id: "extra", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - label: "extra", - isAscOrder: undefined, - computedValue: ["", "Extra1", "Extra2"], - isDerived: true, - }, - ], - }; - - input.orderedTableColumns = Object.values(input.primaryColumns).sort( - (a, b) => { - return input.columnOrder[a.id] < input.columnOrder[b.id]; - }, - ); - - const expected = [ - { - id: 1234, - name: "Jim Doe", - extra: "", - }, - { - id: 234, - name: "Jane Doe", - extra: "Extra2", - }, - { - id: 123, - name: "John Doe", - extra: "Extra1", - }, - ]; - - let result = getFilteredTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - }); - - it("validates generated filtered edited table data to be sorted correctly based on column type", () => { - const { getFilteredTableData } = derivedProperty; - const input = { - processedTableData: [ - { id: 123, name: "BAC", __originalIndex__: 0 }, - { id: 1234, name: "ABC", __originalIndex__: 1 }, - { id: 234, name: "CAB", __originalIndex__: 2 }, - ], - tableData: [ - { id: 123, name: "BAC" }, - { id: 1234, name: "ABC" }, - { id: 234, name: "CAB" }, - ], - sortOrder: { column: "name", order: "asc" }, - columnOrder: ["name", "id"], - primaryColumns: { - id: { - index: 1, - width: 150, - id: "id", - alias: "id", - originalId: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "number", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - isAscOrder: false, - }, - name: { - index: 0, - width: 150, - id: "name", - alias: "name", - originalId: "name", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "awesome", - isAscOrder: undefined, - computedValue: ["BAC", "ABC", "AAB"], - }, - }, - }; - - input.orderedTableColumns = Object.values(input.primaryColumns).sort( - (a, b) => { - return input.columnOrder[a.id] < input.columnOrder[b.id]; - }, - ); - - const expected = [ - { - id: 1234, - name: "ABC", - __originalIndex__: 1, - }, - { - id: 123, - name: "BAC", - __originalIndex__: 0, - }, - { - id: 234, - name: "AAB", - __originalIndex__: 2, - }, - ]; - - let result = getFilteredTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - }); - - it("validates generated filtered table data with null values to be sorted correctly", () => { - const { getFilteredTableData } = derivedProperty; - const input = { - processedTableData: [ - { id: 1234, name: "Jim Doe", age: 28 }, - { id: 123, name: "John Doe" }, - { id: 234, name: "Jane Doe", age: 22 }, - { id: 2345, name: "Jane Doeson", age: 30 }, - ], - sortOrder: { column: "age", order: "desc" }, - columnOrder: ["name", "id", "age"], - primaryColumns: { - id: { - index: 1, - width: 150, - id: "id", - alias: "id", - originalId: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "number", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - isAscOrder: false, - computedValue: [1234, 123, 234, 2345], - }, - name: { - index: 0, - width: 150, - id: "name", - alias: "name", - originalId: "name", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "awesome", - isAscOrder: undefined, - computedValue: ["Jim Doe", "John Doe", "Jane Doe", "Jane Doeson"], - }, - age: { - index: 2, - width: 150, - id: "age", - alias: "age", - originalId: "age", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "number", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - label: "age", - isAscOrder: undefined, - computedValue: [28, null, 22, 30], - isDerived: true, - }, - }, - tableColumns: [ - { - index: 0, - width: 150, - id: "name", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "awesome", - isAscOrder: undefined, - computedValue: ["Jim Doe", "John Doe", "Jane Doe", "Jane Doeson"], - }, - { - index: 1, - width: 150, - id: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "number", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - isAscOrder: false, - computedValue: [1234, 123, 234], - }, - { - index: 2, - width: 150, - id: "age", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - label: "age", - isAscOrder: undefined, - computedValue: [28, null, 22, 30], - isDerived: true, - }, - ], - }; - - input.orderedTableColumns = Object.values(input.primaryColumns).sort( - (a, b) => { - return input.columnOrder[a.id] < input.columnOrder[b.id]; - }, - ); - - const expected = [ - { - id: 2345, - name: "Jane Doeson", - age: 30, - }, - { - id: 1234, - name: "Jim Doe", - age: 28, - }, - { - id: 234, - name: "Jane Doe", - age: 22, - }, - { - id: 123, - name: "John Doe", - age: null, - }, - ]; - - let result = getFilteredTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - }); - - it("validates generated filtered table data with empty string values to be sorted correctly", () => { - const { getFilteredTableData } = derivedProperty; - const input = { - processedTableData: [ - { id: 1234, name: "Jim Doe", age: 28 }, - { id: 123, name: "" }, - { id: 234, name: "Jane Doe", age: 22 }, - { id: 2345, name: "Jane Doeson", age: 30 }, - ], - sortOrder: { column: "name", order: "desc" }, - columnOrder: ["name", "id", "age"], - primaryColumns: { - id: { - index: 1, - width: 150, - id: "id", - alias: "id", - originalId: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "number", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - isAscOrder: false, - computedValue: [1234, 123, 234, 2345], - }, - name: { - index: 0, - width: 150, - id: "name", - alias: "name", - originalId: "name", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "awesome", - isAscOrder: undefined, - computedValue: ["Jim Doe", "", "Jane Doe", "Jane Doeson"], - }, - age: { - index: 2, - width: 150, - id: "age", - alias: "age", - originalId: "age", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "number", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - label: "age", - isAscOrder: undefined, - computedValue: [28, null, 22, 30], - isDerived: true, - }, - }, - tableColumns: [ - { - index: 0, - width: 150, - id: "name", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "awesome", - isAscOrder: undefined, - computedValue: ["Jim Doe", "", "Jane Doe", "Jane Doeson"], - }, - { - index: 1, - width: 150, - id: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "number", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - isAscOrder: false, - computedValue: [1234, 123, 234], - }, - { - index: 2, - width: 150, - id: "age", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - label: "age", - isAscOrder: undefined, - computedValue: [28, null, 22, 30], - isDerived: true, - }, - ], - }; - - input.orderedTableColumns = Object.values(input.primaryColumns).sort( - (a, b) => { - return input.columnOrder[a.id] < input.columnOrder[b.id]; - }, - ); - - const expected = [ - { - id: 1234, - name: "Jim Doe", - age: 28, - }, - { - id: 2345, - name: "Jane Doeson", - age: 30, - }, - { - id: 234, - name: "Jane Doe", - age: 22, - }, - { - id: 123, - name: "", - age: null, - }, - ]; - - let result = getFilteredTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - }); - - it("validates generated filtered table data with date values to be sorted correctly", () => { - const { getFilteredTableData } = derivedProperty; - const input = { - processedTableData: [ - { guid: "abc123", createdAt: 1678886400 }, - { guid: "def456", createdAt: 1747968000 }, - { guid: "ghi789", createdAt: 1646582400 }, - { guid: "jkl012", createdAt: 1668806400 }, - { guid: "mno345", createdAt: 1677840000 }, - { guid: "pqr678", createdAt: 1649670400 }, - { guid: "stu901", createdAt: 1683552000 }, - { guid: "vwx234", createdAt: 1642137600 }, - { guid: "yzab567", createdAt: 1661740800 }, - { guid: "cde890", createdAt: 1670563200 }, - ], - sortOrder: { column: "createdAt", order: "desc" }, - columnOrder: ["guid", "createdAt"], - primaryColumns: { - guid: { - allowCellWrapping: false, - allowSameOptionsInNewRow: true, - index: 0, - width: 150, - originalId: "guid", - id: "guid", - alias: "guid", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textSize: "0.875rem", - enableFilter: true, - enableSort: true, - isVisible: true, - isDisabled: false, - isCellEditable: false, - isEditable: false, - isCellVisible: true, - isDerived: false, - label: "guid", - isSaveVisible: true, - isDiscardVisible: true, - computedValue: [ - "abc123", - "def456", - "ghi789", - "jkl012", - "mno345", - "pqr678", - "stu901", - "vwx234", - "yzab567", - "cde890", - ], - sticky: "", - validation: {}, - currencyCode: "USD", - decimals: 0, - thousandSeparator: true, - notation: "standard", - textColor: "", - cellBackground: "", - fontStyle: "", - }, - createdAt: { - allowCellWrapping: false, - allowSameOptionsInNewRow: true, - index: 1, - width: 150, - originalId: "createdAt", - id: "createdAt", - alias: "createdAt", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "date", - textSize: "0.875rem", - enableFilter: true, - enableSort: true, - isVisible: true, - isDisabled: false, - isCellEditable: false, - isEditable: false, - isCellVisible: true, - isDerived: false, - label: "createdAt", - isSaveVisible: true, - isDiscardVisible: true, - computedValue: [ - 1678886400, 1747968000, 1646582400, 1668806400, 1677840000, - 1649670400, 1683552000, 1642137600, 1661740800, 1670563200, - ], - sticky: "", - validation: {}, - currencyCode: "USD", - decimals: 0, - thousandSeparator: true, - notation: "standard", - inputFormat: "Epoch", - textColor: "", - cellBackground: "", - fontStyle: "", - outputFormat: "", - }, - }, - }; - - input.orderedTableColumns = Object.values(input.primaryColumns).sort( - (a, b) => { - return input.columnOrder[a.id] < input.columnOrder[b.id]; - }, - ); - - const expected = input.processedTableData.sort((a, b) => { - return a.createdAt < b.createdAt ? 1 : -1; - }); - - let result = getFilteredTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - }); - - it("validates generated filtered table data to be filtered correctly in empty comparison", () => { - const { getFilteredTableData } = derivedProperty; - const input = { - processedTableData: [ - { id: 1234, name: "Jim Doe" }, - { id: 123, name: "John Doe" }, - { id: 234, name: "Jane Doe" }, - ], - filters: [ - { - condition: "empty", - column: "id", - value: "", - operator: "OR", - }, - ], - sortOrder: { column: "id", order: "desc" }, - columnOrder: ["name", "id"], - primaryColumns: { - id: { - index: 1, - width: 150, - id: "id", - alias: "id", - originalId: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "number", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - isAscOrder: false, - computedValue: [1234, 123, 234], - }, - name: { - index: 0, - width: 150, - id: "name", - alias: "name", - originalId: "name", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "awesome", - isAscOrder: undefined, - computedValue: ["Jim Doe", "John Doe", "Jane Doe"], - }, - extra: { - index: 2, - width: 150, - id: "extra", - alias: "extra", - originalId: "extra", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - label: "extra", - isAscOrder: undefined, - computedValue: ["", "Extra1", "Extra2"], - isDerived: true, - }, - }, - tableColumns: [ - { - index: 0, - width: 150, - id: "name", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "awesome", - isAscOrder: undefined, - computedValue: ["Jim Doe", "John Doe", "Jane Doe"], - }, - { - index: 1, - width: 150, - id: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "number", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - isAscOrder: false, - computedValue: [1234, 123, 234], - }, - { - index: 2, - width: 150, - id: "extra", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - label: "extra", - isAscOrder: undefined, - computedValue: ["", "Extra1", "Extra2"], - isDerived: true, - }, - ], - }; - - input.orderedTableColumns = Object.values(input.primaryColumns).sort( - (a, b) => { - return input.columnOrder[a.id] < input.columnOrder[b.id]; - }, - ); - - const expected = []; - - let result = getFilteredTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - }); - - it("should filter correctly after editing a value with an applied filter", () => { - const { getFilteredTableData } = derivedProperty; - const input = { - tableData: [ - { id: 1234, name: "Jim Doe" }, - { id: 123, name: "Hamza Khafaga" }, - { id: 234, name: "Khadija Khafaga" }, - ], - processedTableData: [ - { id: 1234, name: "Jim Doe", __originalIndex__: 0 }, - { id: 123, name: "Hamza Anas", __originalIndex__: 1 }, - { id: 234, name: "Khadija Khafaga", __originalIndex__: 2 }, - ], - filters: [ - { - condition: "contains", - column: "name", - value: "Khafaga", - }, - ], - sortOrder: { column: "id", order: "desc" }, - columnOrder: ["name", "id"], - primaryColumns: { - id: { - index: 1, - width: 150, - id: "id", - alias: "id", - originalId: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "number", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - isAscOrder: false, - }, - name: { - index: 0, - width: 150, - id: "name", - alias: "name", - originalId: "name", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "awesome", - isAscOrder: undefined, - }, - }, - tableColumns: [ - { - index: 0, - width: 150, - id: "name", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "awesome", - isAscOrder: undefined, - }, - { - index: 1, - width: 150, - id: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "number", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - isAscOrder: false, - }, - ], - }; - - input.orderedTableColumns = Object.values(input.primaryColumns).sort( - (a, b) => { - return input.columnOrder[a.id] < input.columnOrder[b.id]; - }, - ); - - const expected = [ - { id: 234, name: "Khadija Khafaga", __originalIndex__: 2 }, - { id: 123, name: "Hamza Anas", __originalIndex__: 1 }, - ]; - - let result = getFilteredTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - }); - - it("validates generated sanitized table data with valid property keys", () => { - const { getProcessedTableData } = derivedProperty; - - const input = { - transientTableData: {}, - tableData: [ - { - 1: "abc", - 2: "bcd", - 3: "cde", - Dec: "mon", - demo: "3", - demo_1: "1", - "test one": "1", - "test 3 4 9": "4", - rowIndex: "0", - "😀smile😀": "smile 1", - "🙁sad🙁": "sad 1", - "@user": "user 1", - "@name": "name 1", - ÜserÑame: "john", - }, - { - 1: "asd", - 2: "dfg", - 3: "jkl", - Dec: "mon2", - demo: "2", - demo_1: "1", - "test one": "2", - "test 3 4 9": "3", - rowIndex: "1", - "😀smile😀": "smile 2", - "🙁sad🙁": "sad 2", - "@user": "user 2", - "@name": "name 2", - ÜserÑame: "mike", - }, - ], - }; - const expected = [ - { - 1: "abc", - 2: "bcd", - 3: "cde", - Dec: "mon", - demo: "3", - demo_1: "1", - "test one": "1", - "test 3 4 9": "4", - rowIndex: "0", - "😀smile😀": "smile 1", - "🙁sad🙁": "sad 1", - "@user": "user 1", - "@name": "name 1", - ÜserÑame: "john", - __originalIndex__: 0, - __primaryKey__: undefined, - }, - { - 1: "asd", - 2: "dfg", - 3: "jkl", - Dec: "mon2", - demo: "2", - demo_1: "1", - "test one": "2", - "test 3 4 9": "3", - rowIndex: "1", - "😀smile😀": "smile 2", - "🙁sad🙁": "sad 2", - "@user": "user 2", - "@name": "name 2", - ÜserÑame: "mike", - __originalIndex__: 1, - __primaryKey__: undefined, - }, - ]; - - let result = getProcessedTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - }); - - it("validate generated sorted table data for URL columntype with display text property", () => { - const { getFilteredTableData } = derivedProperty; - const input = { ...inputWithDisplayText }; - - input.orderedTableColumns = Object.values(input.primaryColumns).sort( - (a, b) => { - return input.columnOrder[a.id] < input.columnOrder[b.id]; - }, - ); - - const expected = [ - { url: "D.COM", __originalIndex__: 3 }, - { url: "C.COM", __originalIndex__: 2 }, - { url: "B.COM", __originalIndex__: 1 }, - { url: "A.COM", __originalIndex__: 0 }, - ]; - - let result = getFilteredTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - }); - - it("validate filters on table data for URL columntype with display text", () => { - const { getFilteredTableData } = derivedProperty; - const input = { - ...inputWithDisplayText, - filters: [ - { - condition: "contains", - column: "url", - value: "Y", - }, - ], - }; - - input.orderedTableColumns = Object.values(input.primaryColumns).sort( - (a, b) => { - return input.columnOrder[a.id] < input.columnOrder[b.id]; - }, - ); - - const expected = [{ url: "B.COM", __originalIndex__: 1 }]; - - let result = getFilteredTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - }); - - it("validate search on table data for URL columntype with display text", () => { - const { getFilteredTableData } = derivedProperty; - const input = { - ...inputWithDisplayText, - searchText: "Y", - enableClientSideSearch: true, - }; - - input.orderedTableColumns = Object.values(input.primaryColumns).sort( - (a, b) => { - return input.columnOrder[a.id] < input.columnOrder[b.id]; - }, - ); - - const expected = [{ url: "B.COM", __originalIndex__: 1 }]; - - let result = getFilteredTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - }); - - it("filters correctly after editing a value with an applied search key", () => { - const { getFilteredTableData } = derivedProperty; - const input = { - tableData: [ - { id: 1234, name: "Jim Doe" }, - { id: 123, name: "Hamza Khafaga" }, - { id: 234, name: "Khadija Khafaga" }, - ], - processedTableData: [ - { id: 1234, name: "Jim Doe", __originalIndex__: 0 }, - { id: 123, name: "Hamza Anas", __originalIndex__: 1 }, - { id: 234, name: "Khadija Khafaga", __originalIndex__: 2 }, - ], - searchText: "Khafaga", - sortOrder: { column: "id", order: "desc" }, - columnOrder: ["name", "id"], - primaryColumns: { - id: { - index: 1, - width: 150, - id: "id", - alias: "id", - originalId: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "number", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - isAscOrder: false, - }, - name: { - index: 0, - width: 150, - id: "name", - alias: "name", - originalId: "name", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "awesome", - isAscOrder: undefined, - }, - }, - tableColumns: [ - { - index: 0, - width: 150, - id: "name", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "awesome", - isAscOrder: undefined, - }, - { - index: 1, - width: 150, - id: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "number", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - isAscOrder: false, - }, - ], - }; - - input.orderedTableColumns = Object.values(input.primaryColumns).sort( - (a, b) => { - return input.columnOrder[a.id] < input.columnOrder[b.id]; - }, - ); - - const expected = [ - { id: 234, name: "Khadija Khafaga", __originalIndex__: 2 }, - { id: 123, name: "Hamza Anas", __originalIndex__: 1 }, - ]; - - let result = getFilteredTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - }); - - describe("HTML columns", () => { - const input = { - tableData: [ - { - id: 1, - name: "Jim Doe", - status: "Active", - }, - { - id: 2, - name: "Usain Bolt", - status: "Pending", - }, - { - id: 3, - name: "Elon Musk", - status: "Active", - }, - ], - processedTableData: [ - { - id: 1, - name: "Jim Doe", - status: "Active", - __originalIndex__: 0, - }, - { - id: 2, - name: "Usain Bolt", - status: "Pending", - __originalIndex__: 1, - }, - { - id: 3, - name: "Elon Musk", - status: "Active", - __originalIndex__: 2, - }, - ], - sortOrder: { column: "id", order: "asc" }, - columnOrder: ["id", "name", "status"], - primaryColumns: { - id: { - index: 1, - width: 150, - id: "id", - alias: "id", - originalId: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "number", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - isAscOrder: false, - }, - name: { - index: 0, - width: 150, - id: "name", - alias: "name", - originalId: "name", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "awesome", - isAscOrder: undefined, - }, - status: { - index: 0, - width: 150, - id: "status", - alias: "status", - originalId: "status", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "html", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "Status", - isAscOrder: undefined, - }, - }, - tableColumns: [ - { - index: 0, - width: 150, - id: "name", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "text", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "awesome", - isAscOrder: undefined, - }, - { - index: 1, - width: 150, - id: "id", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "number", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "id", - isAscOrder: false, - }, - { - index: 0, - width: 150, - id: "status", - alias: "status", - originalId: "status", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "html", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "Status", - isAscOrder: undefined, - }, - ], - }; - - input.orderedTableColumns = Object.values(input.primaryColumns).sort( - (a, b) => { - return input.columnOrder[a.id] < input.columnOrder[b.id]; - }, - ); - const { getFilteredTableData } = derivedProperty; - - it("validate search on table for HTML columns", () => { - input.searchText = "Pending"; - const expected = [ - { - id: 2, - name: "Usain Bolt", - status: "Pending", - __originalIndex__: 1, - }, - ]; - - let result = getFilteredTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - delete input.searchText; - }); - - it("validates filters on table for HTML columns", () => { - input.filters = [ - { - condition: "contains", - column: "status", - value: "Active", - }, - ]; - const expected = [ - { - id: 1, - name: "Jim Doe", - status: "Active", - __originalIndex__: 0, - }, - { - id: 3, - name: "Elon Musk", - status: "Active", - __originalIndex__: 2, - }, - ]; - - let result = getFilteredTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - delete input.filters; - }); - - it("validates sort on table for HTML columns", () => { - input.sortOrder = { column: "status", order: "desc" }; - let expected = [ - { - id: 2, - name: "Usain Bolt", - status: "Pending", - __originalIndex__: 1, - }, - { - id: 1, - name: "Jim Doe", - status: "Active", - __originalIndex__: 0, - }, - { - id: 3, - name: "Elon Musk", - status: "Active", - __originalIndex__: 2, - }, - ]; - - let result = getFilteredTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - - input.sortOrder = { column: "status", order: "asc" }; - expected = [ - { - id: 3, - name: "Elon Musk", - status: "Active", - __originalIndex__: 2, - }, - { - id: 1, - name: "Jim Doe", - status: "Active", - __originalIndex__: 0, - }, - - { - id: 2, - name: "Usain Bolt", - status: "Pending", - __originalIndex__: 1, - }, - ]; - - result = getFilteredTableData(input, moment, _); - expect(result).toStrictEqual(expected); - }); - - it("validates tags are not filterable in html content", () => { - input.filters = [ - { - condition: "contains", - column: "status", - value: "span", - }, - ]; - const expected = []; - - let result = getFilteredTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - - input.filters = [ - { - condition: "contains", - column: "status", - value: "color", - }, - ]; - result = getFilteredTableData(input, moment, _); - expect(result).toStrictEqual(expected); - delete input.filters; - }); - it("validates tags are not searchable in html content", () => { - input.searchText = "span"; - - const expected = []; - - let result = getFilteredTableData(input, moment, _); - - expect(result).toStrictEqual(expected); - - input.searchText = "color"; - result = getFilteredTableData(input, moment, _); - expect(result).toStrictEqual(expected); - delete input.searchText; - }); - - it("validates multiple HTML column filters with AND condition", () => { - const multiFilterInput = _.cloneDeep(input); - - multiFilterInput.processedTableData = [ - { - id: 1, - name: "Jim Doe", - status: "Active", - role: "
Admin
", - __originalIndex__: 0, - }, - { - id: 2, - name: "Usain Bolt", - status: "Pending", - role: "
User
", - __originalIndex__: 1, - }, - { - id: 3, - name: "Elon Musk", - status: "Active", - role: "
Admin
", - __originalIndex__: 2, - }, - ]; - - multiFilterInput.primaryColumns.role = { - index: 3, - width: 150, - id: "role", - alias: "role", - originalId: "role", - horizontalAlignment: "LEFT", - verticalAlignment: "CENTER", - columnType: "html", - textColor: "#231F20", - textSize: "PARAGRAPH", - fontStyle: "REGULAR", - enableFilter: true, - enableSort: true, - isVisible: true, - isDerived: false, - label: "Role", - isAscOrder: undefined, - }; - - multiFilterInput.filters = [ - { - condition: "contains", - column: "status", - value: "Active", - }, - { - condition: "contains", - column: "role", - value: "Admin", - operator: "AND", - }, - ]; - - const expected = [ - { - id: 3, - name: "Elon Musk", - status: "Active", - role: "
Admin
", - __originalIndex__: 2, - }, - { - id: 1, - name: "Jim Doe", - status: "Active", - role: "
Admin
", - __originalIndex__: 0, - }, - ]; - - let result = getFilteredTableData(multiFilterInput, moment, _); - - expect(result).toStrictEqual(expected); - delete input.filters; - }); - - it("validates complex HTML content with nested elements and attributes", () => { - const complexHTMLInput = _.cloneDeep(input); - - complexHTMLInput.processedTableData = [ - { - id: 1, - name: "Jim Doe", - status: - '
Active
', - __originalIndex__: 0, - }, - { - id: 2, - name: "Usain Bolt", - status: - '
Pending
', - __originalIndex__: 1, - }, - { - id: 3, - name: "Elon Musk", - status: - '
Active
', - __originalIndex__: 2, - }, - ]; - - // Test searching through complex HTML - complexHTMLInput.searchText = "Active"; - let expected = [ - { - id: 3, - name: "Elon Musk", - status: - '
Active
', - __originalIndex__: 2, - }, - { - id: 1, - name: "Jim Doe", - status: - '
Active
', - __originalIndex__: 0, - }, - ]; - - let result = getFilteredTableData(complexHTMLInput, moment, _); - - expect(result).toStrictEqual(expected); - delete complexHTMLInput.searchText; - - // Test sorting with complex HTML - complexHTMLInput.sortOrder = { column: "status", order: "desc" }; - expected = [ - { - id: 2, - name: "Usain Bolt", - status: - '
Pending
', - __originalIndex__: 1, - }, - { - id: 1, - name: "Jim Doe", - status: - '
Active
', - __originalIndex__: 0, - }, - { - id: 3, - name: "Elon Musk", - status: - '
Active
', - __originalIndex__: 2, - }, - ]; - - result = getFilteredTableData(complexHTMLInput, moment, _); - expect(result).toStrictEqual(expected); - }); - - it("validates HTML columns with special characters and entities", () => { - const specialCharHTMLInput = _.cloneDeep(input); - - specialCharHTMLInput.processedTableData = [ - { - id: 1, - name: "Jim Doe", - status: "© Active & Ready", - __originalIndex__: 0, - }, - { - id: 2, - name: "Usain Bolt", - status: "Pending > Review", - __originalIndex__: 1, - }, - { - id: 3, - name: "Elon Musk", - status: "© Active & Ready", - __originalIndex__: 2, - }, - ]; - - // Test filtering with HTML entities - specialCharHTMLInput.filters = [ - { - condition: "contains", - column: "status", - value: "Active & Ready", - }, - ]; - - const expected = [ - { - id: 3, - name: "Elon Musk", - status: "© Active & Ready", - __originalIndex__: 2, - }, - { - id: 1, - name: "Jim Doe", - status: "© Active & Ready", - __originalIndex__: 0, - }, - ]; - - let result = getFilteredTableData(specialCharHTMLInput, moment, _); - - expect(result).toStrictEqual(expected); - delete specialCharHTMLInput.filters; - }); - - it("validates filtering with null and undefined values in HTML columns", () => { - const nullUndefinedInput = _.cloneDeep(input); - - nullUndefinedInput.processedTableData = [ - { - id: 1, - name: "Jim Doe", - status: null, - __originalIndex__: 0, - }, - { - id: 2, - name: "Usain Bolt", - status: undefined, - __originalIndex__: 1, - }, - { - id: 3, - name: "Elon Musk", - status: "Active", - __originalIndex__: 2, - }, - ]; - - // Test filtering for null values - nullUndefinedInput.filters = [ - { - condition: "contains", - column: "status", - value: "null", - }, - ]; - - let result = getFilteredTableData(nullUndefinedInput, moment, _); - - expect(result).toStrictEqual([]); - - // Test filtering for undefined values - nullUndefinedInput.filters = [ - { - condition: "contains", - column: "status", - value: "undefined", - }, - ]; - - result = getFilteredTableData(nullUndefinedInput, moment, _); - expect(result).toStrictEqual([]); - - delete nullUndefinedInput.filters; - }); - }); -}); - -describe("Validate getSelectedRow function", () => { - it("Multple row selection, with selected rows", () => { - const { getSelectedRow } = derivedProperty; - const input = { - multiRowSelection: true, - selectedRowIndices: [0, 1], - selectedRowIndex: 1, - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getSelectedRow(input, moment, _)).toStrictEqual({ - id: 234, - name: "Jane Doe", - extra: "Extra2", - }); - }); - - it("Multple row selection, with no selected rows", () => { - const { getSelectedRow } = derivedProperty; - const input = { - multiRowSelection: true, - selectedRowIndices: [], - selectedRowIndex: 1, - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getSelectedRow(input, moment, _)).toStrictEqual({ - id: "", - name: "", - extra: "", - }); - }); - - it("Single row selection, with selected row", () => { - const { getSelectedRow } = derivedProperty; - const input = { - multiRowSelection: false, - selectedRowIndices: [], - selectedRowIndex: 1, - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getSelectedRow(input, moment, _)).toStrictEqual({ - id: 234, - name: "Jane Doe", - extra: "Extra2", - }); - }); - - it("Single row selection, without selected row", () => { - const { getSelectedRow } = derivedProperty; - const input = { - multiRowSelection: true, - selectedRowIndices: [], - selectedRowIndex: -1, - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getSelectedRow(input, moment, _)).toStrictEqual({ - id: "", - name: "", - extra: "", - }); - }); - - it("Single row selection, with invalid indices", () => { - const { getSelectedRow } = derivedProperty; - const input = { - multiRowSelection: true, - selectedRowIndices: ["test"], - selectedRowIndex: -1, - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getSelectedRow(input, moment, _)).toStrictEqual({ - id: "", - name: "", - extra: "", - }); - }); - it("Single row selection, with indices undefined", () => { - const { getSelectedRow } = derivedProperty; - const input = { - multiRowSelection: true, - selectedRowIndices: undefined, - selectedRowIndex: -1, - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getSelectedRow(input, moment, _)).toStrictEqual({ - id: "", - name: "", - extra: "", - }); - }); - it("Single row selection, with invalid indices", () => { - const { getSelectedRow } = derivedProperty; - const input = { - multiRowSelection: true, - selectedRowIndices: [undefined], - selectedRowIndex: -1, - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getSelectedRow(input, moment, _)).toStrictEqual({ - id: "", - name: "", - extra: "", - }); - }); - it("Single row selection, with invalid indices", () => { - const { getSelectedRow } = derivedProperty; - const input = { - multiRowSelection: true, - selectedRowIndices: [null], - selectedRowIndex: -1, - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getSelectedRow(input, moment, _)).toStrictEqual({ - id: "", - name: "", - extra: "", - }); - }); - it("Single row selection, with invalid indices", () => { - const { getSelectedRow } = derivedProperty; - const input = { - multiRowSelection: true, - selectedRowIndices: ["1", "2"], - selectedRowIndex: -1, - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getSelectedRow(input, moment, _)).toStrictEqual({ - id: "", - name: "", - extra: "", - }); - }); - it("Single row selection, with invalid indices", () => { - const { getSelectedRow } = derivedProperty; - const input = { - multiRowSelection: true, - selectedRowIndices: "1", - selectedRowIndex: -1, - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getSelectedRow(input, moment, _)).toStrictEqual({ - id: "", - name: "", - extra: "", - }); - }); - it("Single row selection, with invalid indices", () => { - const { getSelectedRow } = derivedProperty; - const input = { - multiRowSelection: true, - selectedRowIndices: "test", - selectedRowIndex: -1, - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getSelectedRow(input, moment, _)).toStrictEqual({ - id: "", - name: "", - extra: "", - }); - }); - - it("Single row selection should not have non data columns", () => { - const { getSelectedRow } = derivedProperty; - const input = { - multiRowSelection: false, - selectedRowIndices: [], - selectedRowIndex: 1, - processedTableData: sampleProcessedTableData, - primaryColumns: samplePrimaryColumns, - }; - - expect(getSelectedRow(input, moment, _)).toStrictEqual({ - step: "#2", - task: "Create a query fetch_users with the Mock DB", - status: "--", - }); - }); -}); - -describe("Validate getTriggeredRow function", () => { - it("with valid triggered row index", () => { - const { getTriggeredRow } = derivedProperty; - const input = { - triggeredRowIndex: 1, - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getTriggeredRow(input, moment, _)).toStrictEqual({ - id: 123, - name: "John Doe", - extra: "Extra1", - }); - }); - - it("with valid triggered row index", () => { - const { getTriggeredRow } = derivedProperty; - const input = { - triggeredRowIndex: 0, - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getTriggeredRow(input, moment, _)).toStrictEqual({ - id: 1234, - name: "Jim Doe", - extra: "", - }); - }); - - it("with triggered row index -1", () => { - const { getTriggeredRow } = derivedProperty; - const input = { - triggeredRowIndex: -1, - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getTriggeredRow(input, moment, _)).toStrictEqual({ - id: "", - name: "", - extra: "", - }); - }); - - it("with invalid triggered row index", () => { - const { getTriggeredRow } = derivedProperty; - const input = { - triggeredRowIndex: "test", - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getTriggeredRow(input, moment, _)).toStrictEqual({ - id: "", - name: "", - extra: "", - }); - }); - - it("with invalid triggered row index", () => { - const { getTriggeredRow } = derivedProperty; - const input = { - triggeredRowIndex: undefined, - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getTriggeredRow(input, moment, _)).toStrictEqual({ - id: "", - name: "", - extra: "", - }); - }); - - it("for removal of non data columns", () => { - const { getTriggeredRow } = derivedProperty; - const input = { - triggeredRowIndex: 1, - processedTableData: sampleProcessedTableData, - primaryColumns: samplePrimaryColumns, - }; - - expect(getTriggeredRow(input, moment, _)).toStrictEqual({ - step: "#2", - task: "Create a query fetch_users with the Mock DB", - status: "--", - }); - }); -}); - -describe("Validate getSelectedRows function", () => { - it("with valid index", () => { - const { getSelectedRows } = derivedProperty; - const input = { - multiRowSelection: true, - selectedRowIndices: [1], - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getSelectedRows(input, moment, _)).toStrictEqual([ - { - id: 234, - name: "Jane Doe", - extra: "Extra2", - }, - ]); - }); - - it("with valid indices", () => { - const { getSelectedRows } = derivedProperty; - const input = { - multiRowSelection: true, - selectedRowIndices: [0, 1], - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getSelectedRows(input, moment, _)).toStrictEqual([ - { - id: 1234, - name: "Jim Doe", - extra: "", - }, - { - id: 234, - name: "Jane Doe", - extra: "Extra2", - }, - ]); - }); - - it("with invalid indices", () => { - const { getSelectedRows } = derivedProperty; - const input = { - selectedRowIndices: [0, "test"], - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getSelectedRows(input, moment, _)).toStrictEqual([]); - }); - - it("with no indices", () => { - const { getSelectedRows } = derivedProperty; - const input = { - selectedRowIndices: [], - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getSelectedRows(input, moment, _)).toStrictEqual([]); - }); - - it("for removal of non data columns", () => { - const { getSelectedRows } = derivedProperty; - const input = { - multiRowSelection: true, - selectedRowIndices: [1], - processedTableData: sampleProcessedTableData, - primaryColumns: samplePrimaryColumns, - }; - - expect(getSelectedRows(input, moment, _)).toStrictEqual([ - { - step: "#2", - task: "Create a query fetch_users with the Mock DB", - status: "--", - }, - ]); - }); -}); - -describe("Validate getOrderedTableColumns function", () => { - it("should test tht it returns the columns array from the primaryColumn", () => { - const { getOrderedTableColumns } = derivedProperty; - - const input = { - columnOrder: ["id", "name"], - primaryColumns: { - id: { - index: 0, - id: "id", - }, - name: { - index: 1, - id: "name", - }, - }, - }; - - const expected = [ - { - index: 0, - id: "id", - isAscOrder: undefined, - }, - { - index: 1, - id: "name", - isAscOrder: undefined, - }, - ]; - - expect(getOrderedTableColumns(input, moment, _)).toStrictEqual(expected); - }); - - it("should test that it returns the columns array from the primaryColumn based on column order", () => { - const { getOrderedTableColumns } = derivedProperty; - - const input = { - columnOrder: ["name", "id"], - primaryColumns: { - id: { - index: 0, - id: "id", - }, - name: { - index: 1, - id: "name", - }, - }, - }; - - const expected = [ - { - index: 0, - id: "name", - isAscOrder: undefined, - }, - { - index: 1, - id: "id", - isAscOrder: undefined, - }, - ]; - - expect(getOrderedTableColumns(input, moment, _)).toStrictEqual(expected); - }); - - it("should test that it returns the columns array from the primaryColumn based on column order and sets sort order details", () => { - const { getOrderedTableColumns } = derivedProperty; - - let input = { - columnOrder: ["name", "id"], - primaryColumns: { - id: { - index: 0, - id: "id", - }, - name: { - index: 1, - id: "name", - }, - }, - sortOrder: { - column: "name", - order: "asc", - }, - }; - - let expected = [ - { - index: 0, - id: "name", - isAscOrder: true, - }, - { - index: 1, - id: "id", - isAscOrder: undefined, - }, - ]; - - expect(getOrderedTableColumns(input, moment, _)).toStrictEqual(expected); - - input = { - columnOrder: ["name", "id"], - primaryColumns: { - id: { - index: 0, - id: "id", - }, - name: { - index: 1, - id: "name", - }, - }, - sortOrder: { - column: "name", - order: "desc", - }, - }; - - expected = [ - { - index: 0, - id: "name", - isAscOrder: false, - }, - { - index: 1, - id: "id", - isAscOrder: undefined, - }, - ]; - - expect(getOrderedTableColumns(input, moment, _)).toStrictEqual(expected); - }); - - it("should test that it removes the column with empty name", () => { - const { getOrderedTableColumns } = derivedProperty; - - const input = { - columnOrder: ["name", ""], - primaryColumns: { - "": { - index: 0, - id: "", - }, - name: { - index: 1, - id: "name", - }, - }, - }; - - const expected = [ - { - index: 0, - id: "name", - isAscOrder: undefined, - }, - ]; - - expect(getOrderedTableColumns(input, moment, _)).toStrictEqual(expected); - }); -}); - -describe("getUpdatedRows -", () => { - it("should test that it returns empty array when transientTableData is empty", () => { - const { getUpdatedRows } = derivedProperty; - - expect( - getUpdatedRows( - { - transientTableData: {}, - }, - null, - _, - ), - ).toEqual([]); - }); - - it("should test that it returns empty array when transientTableData is null", () => { - const { getUpdatedRows } = derivedProperty; - - expect( - getUpdatedRows( - { - transientTableData: null, - }, - null, - _, - ), - ).toEqual([]); - }); - - it("should test that it returns empty array when transientTableData is undefined", () => { - const { getUpdatedRows } = derivedProperty; - - expect( - getUpdatedRows( - { - transientTableData: null, - }, - null, - _, - ), - ).toEqual([]); - }); - - it("should test that it returns expected array when transientTableData has data with invalid index", () => { - const { getUpdatedRows } = derivedProperty; - - const input = { - transientTableData: { - test: { - column1: "newValue", - }, - }, - processedTableData: [ - { - column1: "oldValue", - column2: "oldValue", - __originalIndex__: 0, - }, - { - column1: "newValue", - column2: "oldValue", - __originalIndex__: 1, - }, - ], - }; - - const expected = []; - - expect(getUpdatedRows(input, null, _)).toEqual(expected); - }); - - it("should test that it returns expected array when transientTableData has data", () => { - const { getUpdatedRows } = derivedProperty; - - const input = { - transientTableData: { - 1: { - column1: "newValue", - }, - }, - processedTableData: [ - { - column1: "oldValue", - column2: "oldValue", - __originalIndex__: 0, - }, - { - column1: "newValue", - column2: "oldValue", - __originalIndex__: 1, - }, - ], - }; - - const expected = [ - { - index: 1, - updatedFields: { - column1: "newValue", - }, - allFields: { - column1: "newValue", - column2: "oldValue", - }, - }, - ]; - - expect(getUpdatedRows(input, null, _)).toEqual(expected); - }); - - it("should test that it returns expected array when transientTableData has data with primary column", () => { - const { getUpdatedRows } = derivedProperty; - - const input = { - primaryColumnId: "column2", - transientTableData: { - 1: { - column1: "newValue", - }, - }, - processedTableData: [ - { - column1: "oldValue1", - column2: "oldValue1", - __originalIndex__: 0, - }, - { - column1: "newValue", - column2: "oldValue2", - __originalIndex__: 1, - }, - ], - }; - - const expected = [ - { - index: 1, - column2: "oldValue2", - updatedFields: { - column1: "newValue", - }, - allFields: { - column1: "newValue", - column2: "oldValue2", - }, - }, - ]; - - expect(getUpdatedRows(input, null, _)).toEqual(expected); - }); - - it("should test that it returns expected array when transientTableData has data with primary column and bigger tableData", () => { - const { getUpdatedRows } = derivedProperty; - - const input = { - primaryColumnId: "column3", - transientTableData: { - 1: { - column1: "newValue", - column2: "newValue1", - }, - }, - processedTableData: [ - { - column1: "oldValue1", - column2: "oldValue1", - column3: "oldValue1", - __originalIndex__: 0, - }, - { - column1: "newValue", - column2: "newValue1", - column3: "oldValue2", - __originalIndex__: 1, - }, - { - column1: "oldValue3", - column2: "oldValue3", - column3: "oldValue3", - __originalIndex__: 2, - }, - { - column1: "oldValue3", - column2: "oldValue3", - column3: "oldValue4", - __originalIndex__: 3, - }, - ], - }; - - const expected = [ - { - index: 1, - column3: "oldValue2", - updatedFields: { - column1: "newValue", - column2: "newValue1", - }, - allFields: { - column1: "newValue", - column2: "newValue1", - column3: "oldValue2", - }, - }, - ]; - - expect(getUpdatedRows(input, null, _)).toEqual(expected); - }); - - it("Verify for removal of non data columns", () => { - const { getUpdatedRows } = derivedProperty; - const input = { - transientTableData: { - 0: { - task: "Drop a table first", - }, - }, - primaryColumnId: "step", - processedTableData: sampleProcessedTableData, - primaryColumns: samplePrimaryColumns, - }; - - expect(getUpdatedRows(input, moment, _)).toStrictEqual([ - { - index: 0, - step: "#1", - updatedFields: { - task: "Drop a table first", - }, - allFields: { - step: "#1", - task: "Drop a table", - status: "✅", - }, - }, - ]); - }); -}); - -describe("getUpdatedRowIndices -", () => { - it("should test that it returns empty array when transientTableData is empty", () => { - const { getUpdatedRowIndices } = derivedProperty; - - expect( - getUpdatedRowIndices({ - transientTableData: {}, - }), - ).toEqual([]); - }); - - it("should test that it returns empty array when transientTableData is null", () => { - const { getUpdatedRowIndices } = derivedProperty; - - expect( - getUpdatedRowIndices({ - transientTableData: null, - }), - ).toEqual([]); - }); - - it("should test that it returns empty array when transientTableData is undefined", () => { - const { getUpdatedRowIndices } = derivedProperty; - - expect( - getUpdatedRowIndices({ - transientTableData: undefined, - }), - ).toEqual([]); - }); - - it("should test that it returns empty array when transientTableData has one value", () => { - const { getUpdatedRowIndices } = derivedProperty; - - expect( - getUpdatedRowIndices({ - transientTableData: { - 1: { - column1: "newValue", - }, - }, - }), - ).toEqual([1]); - }); - - it("should test that it returns empty array when transientTableData has two value", () => { - const { getUpdatedRowIndices } = derivedProperty; - - expect( - getUpdatedRowIndices({ - transientTableData: { - 1: { - column1: "newValue", - }, - 2: { - column1: "newValue", - }, - }, - }), - ).toEqual([1, 2]); - }); -}); - -describe("getPageOffset -", () => { - it("should return 0 when pageNo is null", () => { - const { getPageOffset } = derivedProperty; - - expect( - getPageOffset({ - pageNo: null, - pageSize: 0, - }), - ).toEqual(0); - }); - - it("should return 0 when pageSize is null", () => { - const { getPageOffset } = derivedProperty; - - expect( - getPageOffset({ - pageNo: 0, - pageSize: null, - }), - ).toEqual(0); - }); - - it("should return 0 when pageSize is undefined", () => { - const { getPageOffset } = derivedProperty; - - expect( - getPageOffset({ - pageNo: 0, - pageSize: undefined, - }), - ).toEqual(0); - }); - - it("should return 0 when pageNo is undefined", () => { - const { getPageOffset } = derivedProperty; - - expect( - getPageOffset({ - pageNo: undefined, - pageSize: 0, - }), - ).toEqual(0); - }); - - it("should return 0 when pageSize is 0 and pageNo is any random number >= 0", () => { - const { getPageOffset } = derivedProperty; - - expect( - getPageOffset({ - pageNo: 10, - pageSize: 0, - }), - ).toEqual(0); - }); - - it("should return 0 when pageNo is 0 and pageSize is any random number >= 0", () => { - const { getPageOffset } = derivedProperty; - - expect( - getPageOffset({ - pageNo: 0, - pageSize: 100, - }), - ).toEqual(0); - }); - - it("should return 0 when pageNo is NaN", () => { - const { getPageOffset } = derivedProperty; - - expect( - getPageOffset({ - pageNo: NaN, - pageSize: 0, - }), - ).toEqual(0); - }); - - it("should return 10 when pageSize is 5 and pageNo is 3", () => { - const { getPageOffset } = derivedProperty; - - expect( - getPageOffset({ - pageNo: 3, - pageSize: 5, - }), - ).toEqual(10); - }); -}); - -describe("validate getUpdatedRow", () => { - it("should check that valid updated row index returns the valid value", () => { - const { getUpdatedRow } = derivedProperty; - const input1 = { - updatedRowIndex: 1, - processedTableData: [ - { id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe1", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - const input2 = { - updatedRowIndex: 0, - processedTableData: [ - { id: 1, name: "Lorem Ipsum", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getUpdatedRow(input1, moment, _)).toStrictEqual({ - id: 123, - name: "John Doe1", - extra: "Extra1", - }); - expect(getUpdatedRow(input2, moment, _)).toStrictEqual({ - id: 1, - name: "Lorem Ipsum", - extra: "", - }); - }); - - it("should check that it returns empty values when updateRowIndex is invalid or -1", () => { - const { getUpdatedRow } = derivedProperty; - const input1 = { - updatedRowIndex: -1, - processedTableData: [ - { id: 1, name: "Lorem Ipsum", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - const input2 = { - updatedRowIndex: "dummyIndex", - processedTableData: [ - { id: 1, name: "Lorem Ipsum", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - const input3 = { - updatedRowIndex: undefined, - processedTableData: [ - { id: 1, name: "Lorem Ipsum", extra: "", __originalIndex__: 0 }, - { id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 }, - { id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 }, - ], - }; - - expect(getUpdatedRow(input1, moment, _)).toStrictEqual({ - id: "", - name: "", - extra: "", - }); - - expect(getUpdatedRow(input2, moment, _)).toStrictEqual({ - id: "", - name: "", - extra: "", - }); - - expect(getUpdatedRow(input3, moment, _)).toStrictEqual({ - id: "", - name: "", - extra: "", - }); - }); - - it("should check that it removes non data columns", () => { - const { getUpdatedRow } = derivedProperty; - const input = { - updatedRowIndex: 1, - processedTableData: sampleProcessedTableData, - primaryColumns: samplePrimaryColumns, - }; - - expect(getUpdatedRow(input, moment, _)).toStrictEqual({ - step: "#2", - task: "Create a query fetch_users with the Mock DB", - status: "--", - }); - }); -}); -describe("getEditableCellValidity", () => { - const { getEditableCellValidity } = derivedProperty; - - it("should test that its returns empty object when editableCell is empty and isAddRowInProgess is false", () => { - expect( - getEditableCellValidity( - { - editableCell: {}, - isAddRowInProgress: false, - }, - null, - _, - ), - ).toEqual({}); - }); - - describe("should test that it validates the editableColumn against all the validation properties", () => { - it("should return true for editable column when validation is empty", () => { - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: "", - }, - primaryColumns: { - step: { - columnType: "text", - alias: "step", - validation: {}, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: "123", - }, - primaryColumns: { - step: { - columnType: "text", - alias: "step", - validation: {}, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - }); - - it("should return true for editable column when isColumnEditableCellRequired is off and there is no value", () => { - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: "", - }, - primaryColumns: { - step: { - columnType: "text", - alias: "step", - validation: { - isColumnEditableCellRequired: false, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: undefined, - }, - primaryColumns: { - step: { - columnType: "text", - alias: "step", - validation: { - isColumnEditableCellRequired: false, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: null, - }, - primaryColumns: { - step: { - columnType: "text", - alias: "step", - validation: { - isColumnEditableCellRequired: false, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - }); - - it("should return true for editable column when isColumnEditableCellValid is true", () => { - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: null, - }, - primaryColumns: { - step: { - columnType: "text", - alias: "step", - validation: { - isColumnEditableCellValid: true, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - }); - - it("should return false for editable column when isColumnEditableCellValid is false", () => { - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: "test", - }, - primaryColumns: { - step: { - columnType: "text", - alias: "step", - validation: { - isColumnEditableCellValid: false, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: false }); - }); - - it("should return true for editable column when regex is matching", () => { - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: "#1", - }, - primaryColumns: { - step: { - columnType: "text", - alias: "step", - validation: { - regex: "^#1$", - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: "test", - }, - primaryColumns: { - step: { - columnType: "text", - alias: "step", - validation: { - regex: "^test$", - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - }); - - it("should return false for editable column when regex is not matching", () => { - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: "test", - }, - primaryColumns: { - step: { - columnType: "text", - alias: "step", - validation: { - regex: "^#1$", - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: false }); - - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: "#1", - }, - primaryColumns: { - step: { - columnType: "text", - alias: "step", - validation: { - regex: "^test$", - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: false }); - }); - - it("should return false for editable column when isColumnEditableCellRequired is true and there is no value", () => { - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: "", - }, - primaryColumns: { - step: { - columnType: "text", - alias: "step", - validation: { - isColumnEditableCellRequired: true, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: false }); - }); - - it("should return true for editable column when isColumnEditableCellRequired and there is value", () => { - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: "test", - }, - primaryColumns: { - step: { - columnType: "text", - alias: "step", - validation: { - isColumnEditableCellRequired: true, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - }); - - it("should return true for editable column when value is above min", () => { - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: 1, - }, - primaryColumns: { - step: { - columnType: "number", - alias: "step", - validation: { - min: 0, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - }); - - it("should return false for editable column when value is below min", () => { - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: -1, - }, - primaryColumns: { - step: { - columnType: "number", - alias: "step", - validation: { - min: 0, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: false }); - }); - - it("should return true for editable column when value is below max", () => { - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: 2, - }, - primaryColumns: { - step: { - columnType: "number", - alias: "step", - validation: { - max: 5, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - }); - - it("should return false for editable column when value is above max", () => { - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: 6, - }, - primaryColumns: { - step: { - columnType: "number", - alias: "step", - validation: { - max: 5, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: false }); - }); - - it("should return true for editable column when value is matching all the validation criteria", () => { - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: "#1", - }, - primaryColumns: { - step: { - columnType: "text", - alias: "step", - validation: { - isColumnEditableCellValid: false, - regex: "^#1$", - isColumnEditableCellRequired: false, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: false }); - - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: "#1", - }, - primaryColumns: { - step: { - alias: "step", - columnType: "text", - validation: { - isColumnEditableCellValid: true, - regex: "^#1$", - isColumnEditableCellRequired: false, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: "#1", - }, - primaryColumns: { - step: { - alias: "step", - columnType: "text", - validation: { - isColumnEditableCellValid: true, - regex: "^#1$", - isColumnEditableCellRequired: true, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: "#1", - }, - primaryColumns: { - step: { - alias: "step", - columnType: "text", - validation: { - isColumnEditableCellValid: true, - regex: "^#2$", - isColumnEditableCellRequired: true, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: false }); - - expect( - getEditableCellValidity( - { - editableCell: { - column: "step", - value: "#1", - }, - primaryColumns: { - step: { - alias: "step", - columnType: "text", - validation: { - isColumnEditableCellValid: true, - regex: "^#2$", - isColumnEditableCellRequired: false, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: false }); - }); - }); - - describe("should test that it validates the new row against all the validation properties", () => { - it("should check that only editable columns are present in the validation object", () => { - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: "#1", - task: "test", - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "text", - alias: "step", - validation: {}, - }, - task: { - columnType: "text", - alias: "task", - validation: {}, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: "#1", - task: "test", - }, - primaryColumns: { - step: { - columnType: "text", - alias: "step", - validation: {}, - }, - task: { - isEditable: true, - columnType: "text", - alias: "task", - validation: {}, - }, - }, - }, - null, - _, - ), - ).toEqual({ task: true }); - - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: "#1", - task: "test", - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "text", - alias: "step", - validation: {}, - }, - task: { - isEditable: true, - columnType: "text", - alias: "task", - validation: {}, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true, task: true }); - }); - - it("should return true for editable columns when validation is empty", () => { - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: "#1", - task: "test", - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "text", - alias: "step", - validation: {}, - }, - task: { - isEditable: true, - columnType: "text", - alias: "task", - validation: {}, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true, task: true }); - }); - - it("should return true for editable columns when isColumnEditableCellRequired is off and there is no value", () => { - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: "#1", - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "text", - alias: "step", - validation: { - isColumnEditableCellRequired: false, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: undefined, - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "text", - alias: "step", - validation: { - isColumnEditableCellRequired: false, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: null, - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "text", - alias: "step", - validation: { - isColumnEditableCellRequired: false, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - }); - - it("should return true for editable columns when isColumnEditableCellValid is true", () => { - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: null, - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "text", - alias: "step", - validation: { - isColumnEditableCellValid: true, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - }); - - it("should return false for editable columns when isColumnEditableCellValid is false", () => { - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: "test", - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "text", - alias: "step", - validation: { - isColumnEditableCellValid: false, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: false }); - }); - - it("should return true for editable columns when regex is matching", () => { - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: "#1", - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "text", - alias: "step", - validation: { - regex: "^#1$", - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: "test", - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "text", - alias: "step", - validation: { - regex: "^test$", - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - }); - - it("should return false for editable columns when regex is not matching", () => { - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: "test", - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "text", - alias: "step", - validation: { - regex: "^#1$", - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: false }); - - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: "#1", - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "text", - alias: "step", - validation: { - regex: "^test$", - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: false }); - }); - - it("should return false for editable columns when isColumnEditableCellRequired is true and there is no value", () => { - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: "", - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "text", - alias: "step", - validation: { - isColumnEditableCellRequired: true, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: false }); - }); - - it("should return true for editable columns when isColumnEditableCellRequired and there is value", () => { - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: "test", - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "text", - alias: "step", - validation: { - isColumnEditableCellRequired: true, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - }); - - it("should return true for editable columns when value is above min", () => { - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: 1, - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "number", - alias: "step", - validation: { - min: 0, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - }); - - it("should return false for editable columns when value is below min", () => { - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: -1, - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "number", - alias: "step", - validation: { - min: 0, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: false }); - }); - - it("should return true for editable columns when value is below max", () => { - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: 2, - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "number", - alias: "step", - validation: { - max: 5, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - }); - - it("should return false for editable columns when value is above max", () => { - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: 6, - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "number", - alias: "step", - validation: { - max: 5, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: false }); - }); - - it("should return true for editable columns when value is matching all the validation criteria", () => { - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: "#1", - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "text", - alias: "step", - validation: { - isColumnEditableCellValid: false, - regex: "^#1$", - isColumnEditableCellRequired: false, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: false }); - - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: "#1", - }, - primaryColumns: { - step: { - isEditable: true, - alias: "step", - columnType: "text", - validation: { - isColumnEditableCellValid: true, - regex: "^#1$", - isColumnEditableCellRequired: false, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: "#1", - }, - primaryColumns: { - step: { - isEditable: true, - alias: "step", - columnType: "text", - validation: { - isColumnEditableCellValid: true, - regex: "^#1$", - isColumnEditableCellRequired: true, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true }); - - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: "#1", - }, - primaryColumns: { - step: { - isEditable: true, - alias: "step", - columnType: "text", - validation: { - isColumnEditableCellValid: true, - regex: "^#2$", - isColumnEditableCellRequired: true, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: false }); - - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: "#1", - }, - primaryColumns: { - step: { - isEditable: true, - alias: "step", - columnType: "text", - validation: { - isColumnEditableCellValid: true, - regex: "^#2$", - isColumnEditableCellRequired: false, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: false }); - }); - - it("should check that more than one column is validated at the same time", () => { - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: "#1", - task: "test", - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "text", - alias: "step", - validation: { - isColumnEditableCellValid: false, - regex: "^#1$", - isColumnEditableCellRequired: false, - }, - }, - task: { - isEditable: true, - columnType: "text", - alias: "task", - validation: { - isColumnEditableCellValid: true, - regex: "test", - isColumnEditableCellRequired: false, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: false, task: true }); - - expect( - getEditableCellValidity( - { - isAddRowInProgress: true, - editableCell: {}, - newRow: { - step: "#1", - task: "test", - }, - primaryColumns: { - step: { - isEditable: true, - columnType: "text", - alias: "step", - validation: { - isColumnEditableCellValid: true, - regex: "^#1$", - isColumnEditableCellRequired: false, - }, - }, - task: { - isEditable: true, - columnType: "text", - alias: "task", - validation: { - isColumnEditableCellValid: true, - regex: "test", - isColumnEditableCellRequired: false, - }, - }, - }, - }, - null, - _, - ), - ).toEqual({ step: true, task: true }); - }); - }); -}); - -describe("Validate tableHeaders function", () => { - const { getTableHeaders } = derivedProperty; - - it("should test that it returns empty array when primaryColumns is undefined", () => { - expect( - getTableHeaders({ - primaryColumns: undefined, - }), - ).toEqual([]); - }); - - it("should test that it returns expected array when primaryColumns value is undefined", () => { - expect( - getTableHeaders({ - primaryColumns: { - "some value": undefined, - }, - }), - ).toEqual([ - { - id: undefined, - label: undefined, - isVisible: undefined, - }, - ]); - }); - - it("should test that it returns expected array when primaryColumns data is undefined", () => { - expect( - getTableHeaders({ - primaryColumns: { - "some value": { - id: "some value", - label: undefined, - isVisible: true, - }, - }, - }), - ).toEqual([ - { - id: "some value", - label: undefined, - isVisible: true, - }, - ]); - }); - - it("should test that it returns expected array with the same length as that of primaryColumns", () => { - expect( - getTableHeaders({ - primaryColumns: { - "some value": { - id: "some value", - label: "some value", - isVisible: true, - }, - "some other value": { - id: "some other value", - label: "some other value", - isVisible: true, - }, - }, - }).length, - ).toEqual(2); - }); - - it("should test that it returns expected array sorted", () => { - expect( - getTableHeaders({ - primaryColumns: { - "value 02": { - id: "value 02", - label: "value 02", - isVisible: true, - index: "2", - }, - "value 03": { - id: "value 03", - label: "value 03", - isVisible: true, - index: "3", - }, - "value 01": { - id: "value 01", - label: "value 01", - isVisible: true, - index: "1", - }, - }, - }), - ).toEqual([ - { - id: "value 01", - label: "value 01", - isVisible: true, - }, - { - id: "value 02", - label: "value 02", - isVisible: true, - }, - { - id: "value 03", - label: "value 03", - isVisible: true, - }, - ]); - }); -}); diff --git a/app/client/src/workers/Evaluation/JSObject/test.ts b/app/client/src/workers/Evaluation/JSObject/JSObject.test.ts similarity index 100% rename from app/client/src/workers/Evaluation/JSObject/test.ts rename to app/client/src/workers/Evaluation/JSObject/JSObject.test.ts diff --git a/app/client/src/workers/common/DataTreeEvaluator/test.ts b/app/client/src/workers/common/DataTreeEvaluator/dataTreeEvaluator.test.ts similarity index 100% rename from app/client/src/workers/common/DataTreeEvaluator/test.ts rename to app/client/src/workers/common/DataTreeEvaluator/dataTreeEvaluator.test.ts diff --git a/app/client/src/workers/common/DependencyMap/test.ts b/app/client/src/workers/common/DependencyMap/DependencyMap.test.ts similarity index 100% rename from app/client/src/workers/common/DependencyMap/test.ts rename to app/client/src/workers/common/DependencyMap/DependencyMap.test.ts