diff --git a/packages/noco-docs/content/en/engineering/testing.md b/packages/noco-docs/content/en/engineering/testing.md index 0111ad9e70..b13e59513b 100644 --- a/packages/noco-docs/content/en/engineering/testing.md +++ b/packages/noco-docs/content/en/engineering/testing.md @@ -6,41 +6,64 @@ category: "Engineering" menuTitle: "Testing" --- -## API Tests +## Unit Tests ### Pre-requisites + - MySQL is preferrable - however we fallback to SQLite ### Setup + +- All the tests are in `packages/nocodb` folder, which will be our working directory. Use the following command to get into that folder. + +```bash +cd packages/nocodb ``` -cp scripts/.env.copy scripts/.env -open scripts/.env - -# Edit the following env variables -# `DB_USER` : mysql username -# `DB_PASSWORD` : mysql password -# `DB_HOST` : mysql host -# `DB_PORT` : mysql port + +- Install the dependencies for `nocodb` package + +```bash +npm install ``` -### Running tests +#### Environment variables + +- Add your `env` file with the following command + +``` bash +cp tests/unit/.env.sample tests/unit/.env ``` -cd packages/nocodb + +- Open the `.env` file + +``` bash +open tests/unit/.env +```` + +- Configure the following variables + +> DB_USER : mysql username
+> DB_PASSWORD : mysql password
+> DB_HOST : mysql host
+> DB_PORT : mysql port
+ +### How to run tests + +``` bash npm run test:unit ``` -### Notes +### Key points -#### Key points - All individual unit tests are independent of each other. We don't use any shared state between tests. - Test environment includes `sakila` sample database and any change to it by a test is reverted before running other tests. - While running unit tests, it tries to connect to mysql server running on `localhost:3306` with username `root` and password `password`(which can be configured) and if not found, it will use `sqlite` as a fallback, hence no requirement of any sql server to run tests. -#### Walk through of writing a unit test -We will create an `Table` test suite as an example. +### Walk through of writing a unit test +We will create an `Table` test suite as an example. -##### Configure test +#### Configure test We will configure `beforeEach` which is called before each test is executed. We will use `init` function from `nocodb/packages/tests/unit/init/index.ts`, which is a helper function which configures the test environment(i.e resetting state, etc.). @@ -64,7 +87,7 @@ beforeEach(async function () { }); ``` -##### Test case +#### Test case We will use `it` function to create a test case. We will use `supertest` to make a request to the server. We use `expect`(`chai`) to assert the response. @@ -80,7 +103,13 @@ it('Get table list', async function () { }); ``` -##### Integrating the new test suite +> NOTE: We can also run individual test by using `.only` in `describe` or `it` function and the running the test command. + +```typescript +it.only('Get table list', async () => { +``` + +#### Integrating the new test suite We create a new file `table.test.ts` in `packages/nocodb/tests/unit/rest/tests` directory. @@ -124,17 +153,7 @@ export default function () { We can then import the `Table` test suite to `Rest` test suite in `packages/nocodb/tests/unit/rest/index.test.ts` file(`Rest` test suite is imported in the root test suite file which is `packages/nocodb/tests/unit/index.test.ts`). -#### Running test - -To run tests, run `npm run test:unit` in `packages/nocodb` directory. - -> NOTE: We can also run individual test by using `.only` in `describe` or `it` function and the running the test command. - -```typescript -it.only('Get table list', async () => { -``` - -#### Folder structure +### Folder structure The root folder for unit tests is `packages/tests/unit` @@ -145,7 +164,7 @@ The root folder for unit tests is `packages/tests/unit` - `index.test.ts` is the root test suite file which imports all the test suites. - `TestDbMngr.ts` is a helper class to manage test databases (i.e. creating, dropping, etc.). -#### Patterns to follow +### Patterns to follow - **Factories** - Use factories for create/update/delete data. No data should be directly create/updated/deleted in the test. @@ -158,10 +177,35 @@ The root folder for unit tests is `packages/tests/unit` - Use one file per factory. -#### Using sakila db +### Using sakila db To use sakila db use `createSakilaProject` from `factory/project` to create a project. This project will be seeded with `sakila` tables. +```typescript + +function tableTest() { + let context; + let sakilaProject: Project; + let customerTable: Model; + beforeEach(async function () { + context = await init(); + + sakilaProject = await createSakilaProject(context); + + customerTable = await getTable({project: sakilaProject, name: 'customer'}) + }); + + it('Get table data list', async function () { + const response = await request(context.app) + .get(`/api/v1/db/data/noco/${sakilaProject.id}/${customerTable.id}`) + .set('xc-auth', context.token) + .send({}) + .expect(200); + + expect(response.body.list[0]['FirstName']).to.equal('MARY'); + }); +} +``` ## Cypress Tests diff --git a/packages/nocodb/.gitignore b/packages/nocodb/.gitignore index 7d6c6a2d14..3fbe40644f 100644 --- a/packages/nocodb/.gitignore +++ b/packages/nocodb/.gitignore @@ -17,4 +17,5 @@ noco.db* /nc/ /docker/main.js test_meta.db -test_sakila.db \ No newline at end of file +test_sakila.db +.env \ No newline at end of file diff --git a/packages/nocodb/tests/mysql-sakila-db/03-test-sakila-schema.sql b/packages/nocodb/tests/mysql-sakila-db/03-test-sakila-schema.sql index 5fe0db8812..47c8a0c94f 100644 --- a/packages/nocodb/tests/mysql-sakila-db/03-test-sakila-schema.sql +++ b/packages/nocodb/tests/mysql-sakila-db/03-test-sakila-schema.sql @@ -532,7 +532,7 @@ proc: BEGIN DROP TABLE tmpCustomer; END; -CREATE FUNCTION IF NOT EXISTS get_customer_balance(p_customer_id INT, p_effective_date DATETIME) RETURNS DECIMAL(5,2) +CREATE FUNCTION get_customer_balance(p_customer_id INT, p_effective_date DATETIME) RETURNS DECIMAL(5,2) DETERMINISTIC READS SQL DATA BEGIN @@ -608,7 +608,7 @@ BEGIN END; -CREATE FUNCTION IF NOT EXISTS inventory_held_by_customer(p_inventory_id INT) RETURNS INT +CREATE FUNCTION inventory_held_by_customer(p_inventory_id INT) RETURNS INT READS SQL DATA BEGIN DECLARE v_customer_id INT; @@ -622,7 +622,7 @@ BEGIN RETURN v_customer_id; END; -CREATE FUNCTION IF NOT EXISTS inventory_in_stock(p_inventory_id INT) RETURNS BOOLEAN +CREATE FUNCTION inventory_in_stock(p_inventory_id INT) RETURNS BOOLEAN READS SQL DATA BEGIN DECLARE v_rentals INT; diff --git a/packages/nocodb/tests/unit/.env b/packages/nocodb/tests/unit/.env deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/nocodb/tests/unit/.env.sample b/packages/nocodb/tests/unit/.env.sample new file mode 100644 index 0000000000..f3d7072553 --- /dev/null +++ b/packages/nocodb/tests/unit/.env.sample @@ -0,0 +1,4 @@ +DB_USER=root +DB_PASSWORD=password +DB_PORT=3306 +DB_HOST=localhost \ No newline at end of file diff --git a/packages/nocodb/tests/unit/TestDbMngr.ts b/packages/nocodb/tests/unit/TestDbMngr.ts index c13199de3f..fb6a707ba7 100644 --- a/packages/nocodb/tests/unit/TestDbMngr.ts +++ b/packages/nocodb/tests/unit/TestDbMngr.ts @@ -12,17 +12,37 @@ export default class TestDbMngr { public static sakilaKnex: knex; public static defaultConnection = { - user: process.env['DB_USER'] || 'root', - password: process.env['DB_PASSWORD'] || 'password', - host: process.env['DB_HOST'] || 'localhost', - port: Number(process.env['DB_PORT']) || 3306, + user: 'root', + password: 'password', + host: 'localhost', + port: 3306, client: 'mysql2', } + public static connection: { + user: string; + password: string; + host: string; + port: number; + client: string; + } = TestDbMngr.defaultConnection; + public static dbConfig: DbConfig; + static populateConnectionConfig() { + const { user, password, host, port, client } = TestDbMngr.defaultConnection; + TestDbMngr.connection = { + user: process.env['DB_USER'] || user, + password: process.env['DB_PASSWORD'] || password, + host: process.env['DB_HOST'] || host, + port: Number(process.env['DB_PORT']) || port, + client + } + } + static async testConnection(config: DbConfig) { try { + console.log('Testing connection', TestDbMngr.connection); return await SqlMgrv2.testConnection(config); } catch (e) { console.log(e); @@ -31,15 +51,18 @@ export default class TestDbMngr { } static async init() { + TestDbMngr.populateConnectionConfig() + if(await TestDbMngr.isMysqlConfigured()){ await TestDbMngr.connectMysql(); } else { + console.log('Mysql is not configured. Switching to sqlite'); await TestDbMngr.switchToSqlite(); } } static async isMysqlConfigured() { - const { user, password, host, port, client } = TestDbMngr.defaultConnection; + const { user, password, host, port, client } = TestDbMngr.connection; const config = NcConfigFactory.urlToDbConfig(`${client}://${user}:${password}@${host}:${port}`); config.connection = { user, @@ -52,7 +75,7 @@ export default class TestDbMngr { } static async connectMysql() { - const { user, password, host, port, client } = TestDbMngr.defaultConnection; + const { user, password, host, port, client } = TestDbMngr.connection; if(!process.env[`DATABASE_URL`]){ process.env[`DATABASE_URL`] = `${client}://${user}:${password}@${host}:${port}/${TestDbMngr.dbName}`; } diff --git a/packages/nocodb/tests/unit/factory/project.ts b/packages/nocodb/tests/unit/factory/project.ts index 6e94ca58cc..92dbcbfd3e 100644 --- a/packages/nocodb/tests/unit/factory/project.ts +++ b/packages/nocodb/tests/unit/factory/project.ts @@ -1,27 +1,41 @@ import request from 'supertest'; import Project from '../../../src/lib/models/Project'; -import TestDbMngr from '../TestDbMngr'; -const externalProjectConfig = { - title: 'sakila', - bases: [ - { - type: 'mysql2', +const sakilaProjectConfig = (context) => { + let base; + + if(context.sakilaDbConfig.client === 'mysql2'){ + base = { + type: context.sakilaDbConfig.client, + config: { + client: context.sakilaDbConfig.client, + connection: context.sakilaDbConfig.connection + } + }; + } else { + base = { + type: context.sakilaDbConfig.client, config: { - client: 'mysql2', + client: context.sakilaDbConfig.client, connection: { - host: 'localhost', - port: '3306', - user: 'root', - password: 'password', - database: TestDbMngr.sakilaDbName, + client: context.sakilaDbConfig.client, + connection: context.sakilaDbConfig.connection, }, }, - inflection_column: 'camelize', - inflection_table: 'camelize', - }, - ], - external: true, + }; + } + + base = { + ...base, + inflection_column: 'camelize', + inflection_table: 'camelize', + }; + + return { + title: 'sakila', + bases: [base], + external: true, + } }; const defaultProjectValue = { @@ -47,7 +61,7 @@ const createSakilaProject = async (context) => { const response = await request(context.app) .post('/api/v1/db/meta/projects/') .set('xc-auth', context.token) - .send(externalProjectConfig); + .send(sakilaProjectConfig(context)); return (await Project.getByTitleOrId(response.body.id)) as Project; }; diff --git a/packages/nocodb/tests/unit/factory/view.ts b/packages/nocodb/tests/unit/factory/view.ts index f6f49529a3..b940f0a4ef 100644 --- a/packages/nocodb/tests/unit/factory/view.ts +++ b/packages/nocodb/tests/unit/factory/view.ts @@ -19,13 +19,16 @@ const createView = async (context, {title, table, type}: {title: string, table: } }; - await request(context.app) + const response = await request(context.app) .post(`/api/v1/db/meta/tables/${table.id}/${viewTypeStr(type)}`) .set('xc-auth', context.token) .send({ title, type, }); + if(response.status !== 200) { + throw new Error('createView',response.body.message); + } const view = await View.getByTitleOrId({fk_model_id: table.id, titleOrId:title}) as View; diff --git a/packages/nocodb/tests/unit/index.test.ts b/packages/nocodb/tests/unit/index.test.ts index dd0a36273b..2e7d0d2edc 100644 --- a/packages/nocodb/tests/unit/index.test.ts +++ b/packages/nocodb/tests/unit/index.test.ts @@ -3,12 +3,17 @@ import 'mocha'; import restTests from './rest/index.test'; import modelTests from './model/index.test'; import TestDbMngr from './TestDbMngr' +import dotenv from 'dotenv'; process.env.NODE_ENV = 'test'; process.env.TEST = 'test'; process.env.NC_DISABLE_CACHE = 'true'; process.env.NC_DISABLE_TELE = 'true'; +// Load environment variables from .env file +dotenv.config({ + path: __dirname + '/.env' +}); (async function() { await TestDbMngr.init(); diff --git a/packages/nocodb/tests/unit/init/index.ts b/packages/nocodb/tests/unit/init/index.ts index 64474f8e13..55a25a926e 100644 --- a/packages/nocodb/tests/unit/init/index.ts +++ b/packages/nocodb/tests/unit/init/index.ts @@ -38,5 +38,5 @@ export default async function () { const { token } = await createUser({ app: server }, { roles: 'editor' }); - return { app: server, token, dbConfig: TestDbMngr.dbConfig }; + return { app: server, token, dbConfig: TestDbMngr.dbConfig, sakilaDbConfig: TestDbMngr.getSakilaDbConfig() }; } diff --git a/packages/nocodb/tests/unit/model/tests/baseModelSql.test.ts b/packages/nocodb/tests/unit/model/tests/baseModelSql.test.ts index d49938941a..791711921b 100644 --- a/packages/nocodb/tests/unit/model/tests/baseModelSql.test.ts +++ b/packages/nocodb/tests/unit/model/tests/baseModelSql.test.ts @@ -14,6 +14,7 @@ import { expect } from 'chai'; import Filter from '../../../../src/lib/models/Filter'; import { createLtarColumn } from '../../factory/column'; import LinkToAnotherRecordColumn from '../../../../src/lib/models/LinkToAnotherRecordColumn'; +import { isSqlite } from '../../init/db'; function baseModelSqlTests() { let context; @@ -126,6 +127,9 @@ function baseModelSqlTests() { }); it('Bulk update record', async () => { + // Since sqlite doesn't support multiple sql connections, we can't test bulk update in sqlite + if(isSqlite(context)) return + const columns = await table.getColumns(); const request = { clientIp: '::ffff:192.0.0.1', diff --git a/packages/nocodb/tests/unit/rest/tests/tableRow.test.ts b/packages/nocodb/tests/unit/rest/tests/tableRow.test.ts index 6ad6c4389f..a2afd0bf6d 100644 --- a/packages/nocodb/tests/unit/rest/tests/tableRow.test.ts +++ b/packages/nocodb/tests/unit/rest/tests/tableRow.test.ts @@ -22,6 +22,7 @@ import { import { isMysql, isSqlite } from '../../init/db'; import Model from '../../../../src/lib/models/Model'; import Project from '../../../../src/lib/models/Project'; +import { expect } from 'chai'; const isColumnsCorrectInResponse = (row, columns: ColumnType[]) => { const responseColumnsListStr = Object.keys(row).sort().join(','); @@ -353,6 +354,90 @@ function tableTest() { (c) => c.title === 'Payment List' ); + const nestedFilter = { + is_group: true, + status: 'create', + logical_op: 'and', + children: [ + { + fk_column_id: lookupColumn?.id, + status: 'create', + logical_op: 'and', + comparison_op: 'like', + value: '%a%', + }, + { + fk_column_id: paymentListColumn?.id, + status: 'create', + logical_op: 'and', + comparison_op: 'notempty', + }, + ], + }; + + const response = await request(context.app) + .get(`/api/v1/db/data/noco/${sakilaProject.id}/${rentalTable.id}`) + .set('xc-auth', context.token) + .query({ + filterArrJson: JSON.stringify([nestedFilter]), + }) + .expect(200); + + expect(response.body.pageInfo.totalRows).equal(9558) + + + const ascResponse = await request(context.app) + .get(`/api/v1/db/data/noco/${sakilaProject.id}/${rentalTable.id}`) + .set('xc-auth', context.token) + .query({ + filterArrJson: JSON.stringify([nestedFilter]), + sortArrJson: JSON.stringify([ + { + fk_column_id: lookupColumn?.id, + direction: 'asc', + }, + ]), + }) + .expect(200); + + expect(ascResponse.body.pageInfo.totalRows).equal(9558) + expect(ascResponse.body.list[0][lookupColumn.title]).equal('AARON') + + const descResponse = await request(context.app) + .get(`/api/v1/db/data/noco/${sakilaProject.id}/${rentalTable.id}`) + .set('xc-auth', context.token) + .query({ + filterArrJson: JSON.stringify([nestedFilter]), + sortArrJson: JSON.stringify([ + { + fk_column_id: lookupColumn?.id, + direction: 'desc', + }, + ]), + }) + .expect(200); + + expect(descResponse.body.pageInfo.totalRows).equal(9558) + expect(descResponse.body.list[0][lookupColumn.title]).equal('ZACHARY') + }); + + it('Get nested sorted filtered table data list with a lookup column with date comparison', async function () { + // Since sqlite doesn't support date comparison + if(isSqlite(context)) return; + const rentalTable = await getTable({project: sakilaProject, name: 'rental'}); + + const lookupColumn = await createLookupColumn(context, { + project: sakilaProject, + title: 'Lookup', + table: rentalTable, + relatedTableName: customerTable.table_name, + relatedTableColumnTitle: 'FirstName', + }); + + const paymentListColumn = (await rentalTable.getColumns()).find( + (c) => c.title === 'Payment List' + ); + const returnDateColumn = (await rentalTable.getColumns()).find( (c) => c.title === 'ReturnDate' ); @@ -483,7 +568,7 @@ function tableTest() { status: 'create', logical_op: 'and', comparison_op: 'gte', - value: '25', + value: 25, }, { is_group: true, @@ -495,7 +580,7 @@ function tableTest() { status: 'create', logical_op: 'and', comparison_op: 'lte', - value: '30', + value: 30, }, { fk_column_id: paymentListColumn?.id, @@ -512,7 +597,8 @@ function tableTest() { logical_op: 'and', fk_column_id: activeColumn?.id, status: 'create', - comparison_op: 'notempty', + comparison_op: 'eq', + value: 1 }, ], }, @@ -639,7 +725,7 @@ function tableTest() { status: 'create', logical_op: 'and', comparison_op: 'gte', - value: '25', + value: 25, }, { is_group: true, @@ -651,7 +737,7 @@ function tableTest() { status: 'create', logical_op: 'and', comparison_op: 'lte', - value: '30', + value: 30, }, { fk_column_id: paymentListColumn?.id, @@ -668,7 +754,8 @@ function tableTest() { logical_op: 'and', fk_column_id: activeColumn?.id, status: 'create', - comparison_op: 'notempty', + comparison_op: 'eq', + value: 1 }, ], }, @@ -946,7 +1033,7 @@ function tableTest() { status: 'create', logical_op: 'and', comparison_op: 'gte', - value: '25', + value: 25, }, { is_group: true, @@ -958,7 +1045,7 @@ function tableTest() { status: 'create', logical_op: 'and', comparison_op: 'lte', - value: '30', + value: 30, }, { fk_column_id: paymentListColumn?.id, @@ -975,7 +1062,8 @@ function tableTest() { logical_op: 'and', fk_column_id: activeColumn?.id, status: 'create', - comparison_op: 'notempty', + comparison_op: 'eq', + value: 1 }, ], }, @@ -1343,7 +1431,7 @@ function tableTest() { }); it('Bulk update', async function () { - // todo: Find why bulk update in sqlite is hanging + // todo: Since sqlite doesn't support multiple sql connections, we can't test bulk update in sqlite if(isSqlite(context)) { return } @@ -1375,10 +1463,6 @@ function tableTest() { }); it('Bulk delete', async function () { - // todo: Find why bulk delete in sqlite is hanging - if(isSqlite(context)) { - return - } const table = await createTable(context, project); const columns = await table.getColumns(); @@ -1766,6 +1850,9 @@ function tableTest() { }) it('Create list mm', async () => { + // todo: Foreign key has non nullable clause in sqlite sakila + if(isSqlite(context)) return + const rowId = 1; const actorTable = await getTable({project: sakilaProject, name: 'actor'}); const filmListColumn = (await actorTable.getColumns()).find( @@ -1848,6 +1935,9 @@ function tableTest() { }) it('Delete list hm with existing ref row id with non nullable clause', async () => { + // todo: Foreign key has non nullable clause in sqlite sakila + if(isSqlite(context)) return + const rowId = 1; const rentalListColumn = (await customerTable.getColumns()).find( (column) => column.title === 'Rental List' @@ -1900,10 +1990,6 @@ function tableTest() { }) it('Exclude list hm', async () => { - // todo: Find why sqlite not working with this - if(isSqlite(context)) { - return - } const rowId = 1; const rentalListColumn = (await customerTable.getColumns()).find( (column) => column.title === 'Rental List' diff --git a/packages/nocodb/tests/unit/rest/tests/viewRow.test.ts b/packages/nocodb/tests/unit/rest/tests/viewRow.test.ts index c125ec7428..282949b14d 100644 --- a/packages/nocodb/tests/unit/rest/tests/viewRow.test.ts +++ b/packages/nocodb/tests/unit/rest/tests/viewRow.test.ts @@ -10,6 +10,7 @@ import { ColumnType, UITypes, ViewTypes } from 'nocodb-sdk'; import { createView } from '../../factory/view'; import { createColumn, createLookupColumn, createLtarColumn, createRollupColumn, updateViewColumn } from '../../factory/column'; import { createChildRow, createRow, getOneRow, getRow } from '../../factory/row'; +import { expect } from 'chai'; const isColumnsCorrectInResponse = (row, columns: ColumnType[]) => { const responseColumnsListStr = Object.keys(row).sort().join(','); @@ -262,10 +263,6 @@ function viewRowTests() { (c) => c.title === 'Payment List' ); - const returnDateColumn = (await rentalTable.getColumns()).find( - (c) => c.title === 'ReturnDate' - ); - const nestedFilter = { is_group: true, status: 'create', @@ -284,20 +281,6 @@ function viewRowTests() { logical_op: 'and', comparison_op: 'notempty', }, - { - is_group: true, - status: 'create', - logical_op: 'and', - children: [ - { - logical_op: 'and', - fk_column_id: returnDateColumn?.id, - status: 'create', - comparison_op: 'gte', - value: '2005-06-02 04:33', - }, - ], - }, ], }; @@ -308,11 +291,7 @@ function viewRowTests() { filterArrJson: JSON.stringify([nestedFilter]), }); - if (response.body.pageInfo.totalRows !== 9133) - throw new Error('Wrong number of rows'); - - if (response.body.list[0][lookupColumn.title] !== 'ANDREW') - throw new Error('Wrong filter'); + expect(response.body.pageInfo.totalRows).equal(9558) const ascResponse = await request(context.app) .get(`/api/v1/db/data/noco/${sakilaProject.id}/${rentalTable.id}/views/${view.id}`) @@ -328,13 +307,8 @@ function viewRowTests() { }) .expect(200); - if (ascResponse.body.pageInfo.totalRows !== 9133) - throw new Error('Wrong number of rows asc'); - - if (ascResponse.body.list[0][lookupColumn.title] !== 'AARON') { - console.log(ascResponse.body.list[0][lookupColumn.title]); - throw new Error('Wrong filter asc'); - } + expect(ascResponse.body.pageInfo.totalRows).equal(9558) + expect(ascResponse.body.list[0][lookupColumn.title]).equal('AARON') const descResponse = await request(context.app) .get(`/api/v1/db/data/noco/${sakilaProject.id}/${rentalTable.id}/views/${view.id}`) @@ -350,11 +324,8 @@ function viewRowTests() { }) .expect(200); - if (descResponse.body.pageInfo.totalRows !== 9133) - throw new Error('Wrong number of rows desc'); - - if (descResponse.body.list[0][lookupColumn.title] !== 'ZACHARY') - throw new Error('Wrong filter desc'); + expect(descResponse.body.pageInfo.totalRows).equal(9558) + expect(descResponse.body.list[0][lookupColumn.title]).equal('ZACHARY') } it('Get nested sorted filtered table data list with a lookup column gallery', async function () { @@ -399,7 +370,7 @@ function viewRowTests() { status: 'create', logical_op: 'and', comparison_op: 'gte', - value: '25', + value: 25, }, { is_group: true, @@ -411,7 +382,7 @@ function viewRowTests() { status: 'create', logical_op: 'and', comparison_op: 'lte', - value: '30', + value: 30, }, { fk_column_id: paymentListColumn?.id, @@ -428,7 +399,8 @@ function viewRowTests() { logical_op: 'and', fk_column_id: activeColumn?.id, status: 'create', - comparison_op: 'notempty', + comparison_op: 'eq', + value: 1 }, ], }, @@ -451,8 +423,7 @@ function viewRowTests() { }) .expect(200); - if (ascResponse.body.pageInfo.totalRows !== 594) - throw new Error('Wrong number of rows'); + expect(ascResponse.body.pageInfo.totalRows).equal(594); if (ascResponse.body.list[0][rollupColumn.title] !== 12) { throw new Error('Wrong filter'); @@ -648,7 +619,7 @@ function viewRowTests() { status: 'create', logical_op: 'and', comparison_op: 'gte', - value: '25', + value: 25, }, { is_group: true, @@ -660,7 +631,7 @@ function viewRowTests() { status: 'create', logical_op: 'and', comparison_op: 'lte', - value: '30', + value: 30, }, { fk_column_id: paymentListColumn?.id, @@ -677,7 +648,8 @@ function viewRowTests() { logical_op: 'and', fk_column_id: activeColumn?.id, status: 'create', - comparison_op: 'notempty', + comparison_op: 'eq', + value: 1 }, ], },