diff --git a/backend/src/entities/table-settings/application/data-structures/create-table-settings.ds.ts b/backend/src/entities/table-settings/application/data-structures/create-table-settings.ds.ts index 11d435d58..4743c25ed 100644 --- a/backend/src/entities/table-settings/application/data-structures/create-table-settings.ds.ts +++ b/backend/src/entities/table-settings/application/data-structures/create-table-settings.ds.ts @@ -77,4 +77,7 @@ export class CreateTableSettingsDs { @ApiProperty({ required: false }) ordering_field?: string; + + @ApiProperty({ isArray: true, type: 'string', required: false }) + columns_view?: Array; } diff --git a/backend/src/entities/table-settings/common-table-settings/dto/create-table-settings.dto.ts b/backend/src/entities/table-settings/common-table-settings/dto/create-table-settings.dto.ts index 8d5d7414b..d6219a47f 100644 --- a/backend/src/entities/table-settings/common-table-settings/dto/create-table-settings.dto.ts +++ b/backend/src/entities/table-settings/common-table-settings/dto/create-table-settings.dto.ts @@ -2,16 +2,17 @@ import { CustomFieldsEntity } from '../../../custom-field/custom-fields.entity.j import { TableWidgetEntity } from '../../../widget/table-widget.entity.js'; export class CreateTableSettingsDto { - connection_id: string; - table_name: string; - display_name: string; - search_fields: string[]; - excluded_fields: string[]; - identification_fields: string[]; - identity_column; - readonly_fields: string[]; - sortable_by: string[]; - autocomplete_columns: string[]; - custom_fields?: CustomFieldsEntity[]; - table_widgets?: TableWidgetEntity[]; + connection_id: string; + table_name: string; + display_name: string; + search_fields: string[]; + excluded_fields: string[]; + identification_fields: string[]; + identity_column; + readonly_fields: string[]; + sortable_by: string[]; + autocomplete_columns: string[]; + custom_fields?: CustomFieldsEntity[]; + table_widgets?: TableWidgetEntity[]; + columns_view?: string[]; } diff --git a/backend/src/entities/table-settings/common-table-settings/table-settings.controller.ts b/backend/src/entities/table-settings/common-table-settings/table-settings.controller.ts index 303affe04..253d56f1a 100644 --- a/backend/src/entities/table-settings/common-table-settings/table-settings.controller.ts +++ b/backend/src/entities/table-settings/common-table-settings/table-settings.controller.ts @@ -118,6 +118,7 @@ export class TableSettingsController { @Body('list_fields') list_fields: string[], @Body('ordering') ordering: string, @Body('ordering_field') ordering_field: string, + @Body('columns_view') columns_view: string[], @UserId() userId: string, @MasterPassword() masterPwd: string, ): Promise { @@ -147,6 +148,7 @@ export class TableSettingsController { list_fields: list_fields, ordering: ordering, ordering_field: ordering_field, + columns_view: columns_view, }; const errors = this.validateParameters(inputData); @@ -195,6 +197,7 @@ export class TableSettingsController { @Body('list_fields') list_fields: string[], @Body('ordering') ordering: string, @Body('ordering_field') ordering_field: string, + @Body('columns_view') columns_view: string[], @UserId() userId: string, @MasterPassword() masterPwd: string, ): Promise { @@ -223,6 +226,7 @@ export class TableSettingsController { list_per_page, ordering, ordering_field, + columns_view, }; const errors = this.validateParameters(inputData); diff --git a/backend/src/entities/table-settings/common-table-settings/utils/build-new-table-settings-entity.ts b/backend/src/entities/table-settings/common-table-settings/utils/build-new-table-settings-entity.ts index 219e5e9e2..85536deeb 100644 --- a/backend/src/entities/table-settings/common-table-settings/utils/build-new-table-settings-entity.ts +++ b/backend/src/entities/table-settings/common-table-settings/utils/build-new-table-settings-entity.ts @@ -32,6 +32,7 @@ export function buildNewTableSettingsEntity( list_fields, ordering, ordering_field, + columns_view, } = settings; newSettings.connection_id = connection; newSettings.display_name = display_name; @@ -57,5 +58,6 @@ export function buildNewTableSettingsEntity( newSettings.list_fields = list_fields; newSettings.ordering = ordering as QueryOrderingEnum; newSettings.ordering_field = ordering_field; + newSettings.columns_view = columns_view; return newSettings; } diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-table-settings-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-table-settings-e2e.test.ts index 452d3f9d2..e23907561 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-table-settings-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-table-settings-e2e.test.ts @@ -785,90 +785,82 @@ test.serial( currentTest = 'GET /table/rows/:slug personal settings priority'; -test.skip( - `${currentTest} should use personal table settings over common table settings when both exist`, - async (t) => { - try { - const newConnection = getTestData(mockFactory).newConnectionToTestDB; - const { token } = await registerUserAndReturnUserInfo(app); +test.skip(`${currentTest} should use personal table settings over common table settings when both exist`, async (t) => { + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); - const createdConnection = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const connectionId = JSON.parse(createdConnection.text).id; - const tableName = 'connection'; + const connectionId = JSON.parse(createdConnection.text).id; + const tableName = 'connection'; - // Create common table settings with specific list_fields - const createTableSettingsDTO = mockFactory.generateTableSettings( - connectionId, - tableName, - ['title'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - createTableSettingsDTO.list_fields = ['id', 'title', 'type']; - createTableSettingsDTO.list_per_page = 10; - createTableSettingsDTO.ordering = QueryOrderingEnum.ASC; - createTableSettingsDTO.ordering_field = 'id'; + const createTableSettingsDTO = mockFactory.generateTableSettings( + connectionId, + tableName, + ['title'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + createTableSettingsDTO.list_fields = ['id', 'title', 'type']; + createTableSettingsDTO.list_per_page = 10; + createTableSettingsDTO.ordering = QueryOrderingEnum.ASC; + createTableSettingsDTO.ordering_field = 'id'; - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) - .send(createTableSettingsDTO) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) + .send(createTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); - // Create personal table settings with different values - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - ['id', 'title'], // different list_fields - 5, // different list_per_page - QueryOrderingEnum.DESC, // different ordering - 'title', // different ordering_field - ); + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + ['id', 'title'], + 5, + QueryOrderingEnum.DESC, + 'title', + ); - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${connectionId}`) - .query({ tableName: tableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${connectionId}`) + .query({ tableName: tableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(createPersonalTableSettingsResponse.status, 200); + t.is(createPersonalTableSettingsResponse.status, 200); - // Get table rows and verify personal settings are applied - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${connectionId}?tableName=${tableName}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${connectionId}?tableName=${tableName}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - // Verify that personal settings list_per_page is used (5 instead of 10) - t.is(getTableRowsRO.pagination.perPage, 5); + t.is(getTableRowsRO.pagination.perPage, 5); - // Verify that personal list_fields are used - rows should only have id and title - const rowKeys = Object.keys(getTableRowsRO.rows[0]); - t.true(rowKeys.includes('id')); - t.true(rowKeys.includes('title')); - t.false(rowKeys.includes('type')); // type was in common settings but not in personal - } catch (e) { - console.error(e); - throw e; - } - }, -); + const rowKeys = Object.keys(getTableRowsRO.rows[0]); + t.true(rowKeys.includes('id')); + t.true(rowKeys.includes('title')); + t.false(rowKeys.includes('type')); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial(`${currentTest} should use common table settings when personal table settings do not exist`, async (t) => { try { @@ -885,7 +877,6 @@ test.serial(`${currentTest} should use common table settings when personal table const connectionId = JSON.parse(createdConnection.text).id; const tableName = 'connection'; - // Create only common table settings with specific list_fields const createTableSettingsDTO = mockFactory.generateTableSettings( connectionId, tableName, @@ -910,9 +901,6 @@ test.serial(`${currentTest} should use common table settings when personal table .set('Accept', 'application/json'); t.is(createTableSettingsResponse.status, 201); - // No personal table settings created - - // Get table rows and verify common settings are applied const getTableRowsResponse = await request(app.getHttpServer()) .get(`/table/rows/${connectionId}?tableName=${tableName}`) .set('Cookie', token) @@ -922,10 +910,8 @@ test.serial(`${currentTest} should use common table settings when personal table t.is(getTableRowsResponse.status, 200); const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - // Verify that common settings list_per_page is used (7) t.is(getTableRowsRO.pagination.perPage, 7); - // Verify that common list_fields are used - rows should have id, title, and type const rowKeys = Object.keys(getTableRowsRO.rows[0]); t.true(rowKeys.includes('id')); t.true(rowKeys.includes('title')); @@ -953,7 +939,6 @@ test.serial( const connectionId = JSON.parse(createdConnection.text).id; const tableName = 'connection'; - // Create common table settings with specific list_fields const createTableSettingsDTO = mockFactory.generateTableSettings( connectionId, tableName, @@ -976,10 +961,9 @@ test.serial( .set('Accept', 'application/json'); t.is(createTableSettingsResponse.status, 201); - // Create personal table settings with empty list_fields but different list_per_page const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - [], // empty list_fields - should fall back to common - 4, // different list_per_page + [], + 4, QueryOrderingEnum.DESC, 'title', ); @@ -994,7 +978,6 @@ test.serial( t.is(createPersonalTableSettingsResponse.status, 200); - // Get table rows and verify settings are applied correctly const getTableRowsResponse = await request(app.getHttpServer()) .get(`/table/rows/${connectionId}?tableName=${tableName}`) .set('Cookie', token) @@ -1004,10 +987,8 @@ test.serial( t.is(getTableRowsResponse.status, 200); const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - // Verify that personal settings list_per_page is used (4) t.is(getTableRowsRO.pagination.perPage, 4); - // Verify that common list_fields are used since personal was empty const rowKeys = Object.keys(getTableRowsRO.rows[0]); t.true(rowKeys.includes('id')); t.true(rowKeys.includes('title')); @@ -1017,3 +998,207 @@ test.serial( } }, ); + +currentTest = 'GET /table/rows/:slug columns_view priority'; + +test.serial( + `${currentTest} should use personal table settings columns_view over common table settings when both exist`, + async (t) => { + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); + + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = JSON.parse(createdConnection.text).id; + const tableName = 'connection'; + + // Create common table settings with specific columns_view + const createTableSettingsDTO = mockFactory.generateTableSettings( + connectionId, + tableName, + ['title'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + createTableSettingsDTO.columns_view = ['id', 'title', 'type', 'host']; + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) + .send(createTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 5, + QueryOrderingEnum.DESC, + 'title', + ['id', 'title'], + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${connectionId}`) + .query({ tableName: tableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${connectionId}?tableName=${tableName}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.deepEqual(getTableRowsRO.table_settings.columns_view, ['id', 'title']); + } catch (e) { + console.error(e); + throw e; + } + }, +); + +test.serial( + `${currentTest} should use common table settings columns_view when personal columns_view does not exist`, + async (t) => { + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); + + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = JSON.parse(createdConnection.text).id; + const tableName = 'connection'; + + const createTableSettingsDTO = mockFactory.generateTableSettings( + connectionId, + tableName, + ['title'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + createTableSettingsDTO.columns_view = ['id', 'title', 'type']; + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) + .send(createTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${connectionId}?tableName=${tableName}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.deepEqual(getTableRowsRO.table_settings.columns_view, ['id', 'title', 'type']); + } catch (e) { + console.error(e); + throw e; + } + }, +); + +test.serial( + `${currentTest} should use common table settings columns_view when personal columns_view is empty array`, + async (t) => { + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); + + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = JSON.parse(createdConnection.text).id; + const tableName = 'connection'; + + const createTableSettingsDTO = mockFactory.generateTableSettings( + connectionId, + tableName, + ['title'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + createTableSettingsDTO.columns_view = ['id', 'title', 'host']; + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) + .send(createTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 5, + QueryOrderingEnum.DESC, + 'title', + [], + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${connectionId}`) + .query({ tableName: tableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${connectionId}?tableName=${tableName}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.deepEqual(getTableRowsRO.table_settings.columns_view, ['id', 'title', 'host']); + } catch (e) { + console.error(e); + throw e; + } + }, +); diff --git a/backend/test/ava-tests/saas-tests/table-settings-e2e.test.ts b/backend/test/ava-tests/saas-tests/table-settings-e2e.test.ts index 772d37176..b4c749ecb 100644 --- a/backend/test/ava-tests/saas-tests/table-settings-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/table-settings-e2e.test.ts @@ -26,600 +26,804 @@ let _testUtils: TestUtils; let currentTest; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /settings/'; test.serial(`${currentTest} should throw an exception when tableName is missing`, async (t) => { - try { - const { token } = await registerUserAndReturnUserInfo(app); - const newConnection = getTestData(mockFactory).newConnectionToTestDB; - const createdConnection = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const connectionId = JSON.parse(createdConnection.text).id; - - const tableName = ''; - const findSettingsResponce = await request(app.getHttpServer()) - .get(`/settings/?connectionId=${connectionId}&tableName=${tableName}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(findSettingsResponce.status, 400); - const findSettingsRO = JSON.parse(findSettingsResponce.text); - t.is(findSettingsRO.message, Messages.TABLE_NAME_MISSING); - } catch (e) { - console.error(e); - } + try { + const { token } = await registerUserAndReturnUserInfo(app); + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = JSON.parse(createdConnection.text).id; + + const tableName = ''; + const findSettingsResponce = await request(app.getHttpServer()) + .get(`/settings/?connectionId=${connectionId}&tableName=${tableName}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(findSettingsResponce.status, 400); + const findSettingsRO = JSON.parse(findSettingsResponce.text); + t.is(findSettingsRO.message, Messages.TABLE_NAME_MISSING); + } catch (e) { + console.error(e); + } }); test.serial(`${currentTest} should throw an exception when connectionId is missing`, async (t) => { - try { - const newConnection = getTestData(mockFactory).newConnectionToTestDB; - const { token } = await registerUserAndReturnUserInfo(app); - - const _createdConnection = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const connectionId = ''; - const tableName = faker.lorem.words(); - const findSettingsResponce = await request(app.getHttpServer()) - .get(`/settings/?connectionId=${connectionId}&tableName=${tableName}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(findSettingsResponce.status, 400); - const findSettingsRO = JSON.parse(findSettingsResponce.text); - t.is(findSettingsRO.message, Messages.CONNECTION_ID_MISSING); - } catch (e) { - console.error(e); - } + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); + + const _createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = ''; + const tableName = faker.lorem.words(); + const findSettingsResponce = await request(app.getHttpServer()) + .get(`/settings/?connectionId=${connectionId}&tableName=${tableName}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(findSettingsResponce.status, 400); + const findSettingsRO = JSON.parse(findSettingsResponce.text); + t.is(findSettingsRO.message, Messages.CONNECTION_ID_MISSING); + } catch (e) { + console.error(e); + } }); test.serial( - `${currentTest} should return an empty connection settings object, when setting does not exists for this table in connection`, - async (t) => { - try { - const newConnection = getTestData(mockFactory).newConnectionToTestDB; - const { token } = await registerUserAndReturnUserInfo(app); - - const createdConnection = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const connectionId = JSON.parse(createdConnection.text).id; - - const tableName = faker.lorem.words(); - const findSettingsResponce = await request(app.getHttpServer()) - .get(`/settings/?connectionId=${connectionId}&tableName=${tableName}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(findSettingsResponce.status, 200); - const findSettingsRO = JSON.parse(findSettingsResponce.text); - t.deepEqual(findSettingsRO, {}); - } catch (e) { - console.error(e); - } - }, + `${currentTest} should return an empty connection settings object, when setting does not exists for this table in connection`, + async (t) => { + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); + + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = JSON.parse(createdConnection.text).id; + + const tableName = faker.lorem.words(); + const findSettingsResponce = await request(app.getHttpServer()) + .get(`/settings/?connectionId=${connectionId}&tableName=${tableName}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(findSettingsResponce.status, 200); + const findSettingsRO = JSON.parse(findSettingsResponce.text); + t.deepEqual(findSettingsRO, {}); + } catch (e) { + console.error(e); + } + }, ); test.serial(`${currentTest} should return connection settings object`, async (t) => { - try { - const newConnection = getTestData(mockFactory).newConnectionToTestDB; - const { token } = await registerUserAndReturnUserInfo(app); - - const createdConnection = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const connectionId = JSON.parse(createdConnection.text).id; - - const tableName = 'connection'; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connectionId, - tableName, - ['title'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) - .send(createTableSettingsDTO) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const findSettingsResponce = await request(app.getHttpServer()) - .get(`/settings/?connectionId=${connectionId}&tableName=connection`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const findSettingsRO = JSON.parse(findSettingsResponce.text); - t.is(Object.hasOwn(findSettingsRO, 'id'), true); - t.is(findSettingsRO.table_name, 'connection'); - t.is(findSettingsRO.display_name, createTableSettingsDTO.display_name); - t.deepEqual(findSettingsRO.search_fields, ['title']); - t.deepEqual(findSettingsRO.excluded_fields, []); - t.deepEqual(findSettingsRO.readonly_fields, []); - t.deepEqual(findSettingsRO.sortable_by, []); - t.deepEqual(findSettingsRO.autocomplete_columns, []); - t.deepEqual(findSettingsRO.identification_fields, []); - t.is(findSettingsRO.connection_id, connectionId); - } catch (e) { - console.error(e); - } + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); + + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = JSON.parse(createdConnection.text).id; + + const tableName = 'connection'; + const createTableSettingsDTO = mockFactory.generateTableSettings( + connectionId, + tableName, + ['title'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) + .send(createTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const findSettingsResponce = await request(app.getHttpServer()) + .get(`/settings/?connectionId=${connectionId}&tableName=connection`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const findSettingsRO = JSON.parse(findSettingsResponce.text); + t.is(Object.hasOwn(findSettingsRO, 'id'), true); + t.is(findSettingsRO.table_name, 'connection'); + t.is(findSettingsRO.display_name, createTableSettingsDTO.display_name); + t.deepEqual(findSettingsRO.search_fields, ['title']); + t.deepEqual(findSettingsRO.excluded_fields, []); + t.deepEqual(findSettingsRO.readonly_fields, []); + t.deepEqual(findSettingsRO.sortable_by, []); + t.deepEqual(findSettingsRO.autocomplete_columns, []); + t.deepEqual(findSettingsRO.identification_fields, []); + t.is(findSettingsRO.connection_id, connectionId); + } catch (e) { + console.error(e); + } }); currentTest = 'POST /settings/'; test.serial(`${currentTest} should return created table settings`, async (t) => { - try { - const newConnection = getTestData(mockFactory).newConnectionToTestDB; - const { token } = await registerUserAndReturnUserInfo(app); - - const createdConnection = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const connectionId = JSON.parse(createdConnection.text).id; - - const createTableSettingsDTO = mockFactory.generateTableSettings( - connectionId, - 'connection', - ['title'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${connectionId}&tableName=connection`) - .send(createTableSettingsDTO) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const findSettingsResponce = await request(app.getHttpServer()) - .get(`/settings/?connectionId=${connectionId}&tableName=connection`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const findSettingsRO = JSON.parse(findSettingsResponce.text); - t.is(Object.hasOwn(findSettingsRO, 'id'), true); - t.is(findSettingsRO.table_name, 'connection'); - t.is(findSettingsRO.display_name, createTableSettingsDTO.display_name); - t.deepEqual(findSettingsRO.search_fields, ['title']); - t.deepEqual(findSettingsRO.excluded_fields, []); - t.deepEqual(findSettingsRO.readonly_fields, []); - t.deepEqual(findSettingsRO.sortable_by, []); - t.deepEqual(findSettingsRO.autocomplete_columns, []); - t.is(findSettingsRO.connection_id, connectionId); - } catch (e) { - console.error(e); - } + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); + + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = JSON.parse(createdConnection.text).id; + + const createTableSettingsDTO = mockFactory.generateTableSettings( + connectionId, + 'connection', + ['title'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connectionId}&tableName=connection`) + .send(createTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const findSettingsResponce = await request(app.getHttpServer()) + .get(`/settings/?connectionId=${connectionId}&tableName=connection`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const findSettingsRO = JSON.parse(findSettingsResponce.text); + t.is(Object.hasOwn(findSettingsRO, 'id'), true); + t.is(findSettingsRO.table_name, 'connection'); + t.is(findSettingsRO.display_name, createTableSettingsDTO.display_name); + t.deepEqual(findSettingsRO.search_fields, ['title']); + t.deepEqual(findSettingsRO.excluded_fields, []); + t.deepEqual(findSettingsRO.readonly_fields, []); + t.deepEqual(findSettingsRO.sortable_by, []); + t.deepEqual(findSettingsRO.autocomplete_columns, []); + t.is(findSettingsRO.connection_id, connectionId); + } catch (e) { + console.error(e); + } }); test.serial(`${currentTest} should throw exception when tableName is missing`, async (t) => { - try { - const newConnection = getTestData(mockFactory).newConnectionToTestDB; - const { token } = await registerUserAndReturnUserInfo(app); - - const createdConnection = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const connectionId = JSON.parse(createdConnection.text).id; - - const createTableSettingsDTO = mockFactory.generateTableSettings( - connectionId, - 'connection', - ['title'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const tableName = ''; - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) - .send(createTableSettingsDTO) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 400); - const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); - t.is(createTableSettingsRO.message, Messages.TABLE_NAME_MISSING); - } catch (e) { - console.error(e); - } + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); + + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = JSON.parse(createdConnection.text).id; + + const createTableSettingsDTO = mockFactory.generateTableSettings( + connectionId, + 'connection', + ['title'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const tableName = ''; + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) + .send(createTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 400); + const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); + t.is(createTableSettingsRO.message, Messages.TABLE_NAME_MISSING); + } catch (e) { + console.error(e); + } }); test.serial(`${currentTest} should throw exception when connectionId is missing`, async (t) => { - try { - const newConnection = getTestData(mockFactory).newConnectionToTestDB; - const { token } = await registerUserAndReturnUserInfo(app); - - const _createdConnection = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const connectionId = ''; - - const createTableSettingsDTO = mockFactory.generateTableSettings( - connectionId, - 'connection', - ['title'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const tableName = faker.lorem.words(1); - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) - .send(createTableSettingsDTO) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 400); - const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); - t.is(createTableSettingsRO.message, Messages.CONNECTION_ID_MISSING); - } catch (e) { - console.error(e); - } + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); + + const _createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = ''; + + const createTableSettingsDTO = mockFactory.generateTableSettings( + connectionId, + 'connection', + ['title'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const tableName = faker.lorem.words(1); + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) + .send(createTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 400); + const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); + t.is(createTableSettingsRO.message, Messages.CONNECTION_ID_MISSING); + } catch (e) { + console.error(e); + } }); test.serial(`${currentTest} should throw exception when search_fields is not an array`, async (t) => { - try { - const newConnection = getTestData(mockFactory).newConnectionToTestDB; - const { token } = await registerUserAndReturnUserInfo(app); - - const createdConnection = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const connectionId = JSON.parse(createdConnection.text).id; - - const createTableSettingsDTO = mockFactory.generateTableSettingsWithoutTypes( - connectionId, - 'connection', - 'title', - undefined, - undefined, - undefined, - undefined, - ); - - const tableName = 'connection'; - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) - .send(createTableSettingsDTO) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 400); - const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); - t.is(createTableSettingsRO.message, 'The field "search_fields" must be an array'); - } catch (e) { - console.error(e); - } + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); + + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = JSON.parse(createdConnection.text).id; + + const createTableSettingsDTO = mockFactory.generateTableSettingsWithoutTypes( + connectionId, + 'connection', + 'title', + undefined, + undefined, + undefined, + undefined, + ); + + const tableName = 'connection'; + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) + .send(createTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 400); + const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); + t.is(createTableSettingsRO.message, 'The field "search_fields" must be an array'); + } catch (e) { + console.error(e); + } }); test.serial(`${currentTest} should throw exception when excluded_fields is not an array`, async (t) => { - try { - const newConnection = getTestData(mockFactory).newConnectionToTestDB; - const { token } = await registerUserAndReturnUserInfo(app); - - const createdConnection = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const connectionId = JSON.parse(createdConnection.text).id; - - const createTableSettingsDTO = mockFactory.generateTableSettingsWithoutTypes( - connectionId, - 'connection', - ['title'], - 'type', - undefined, - undefined, - undefined, - ); - - const tableName = 'connection'; - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) - .send(createTableSettingsDTO) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 400); - const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); - t.is(createTableSettingsRO.message, 'The field "excluded_fields" must be an array'); - } catch (e) { - console.error(e); - } + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); + + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = JSON.parse(createdConnection.text).id; + + const createTableSettingsDTO = mockFactory.generateTableSettingsWithoutTypes( + connectionId, + 'connection', + ['title'], + 'type', + undefined, + undefined, + undefined, + ); + + const tableName = 'connection'; + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) + .send(createTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 400); + const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); + t.is(createTableSettingsRO.message, 'The field "excluded_fields" must be an array'); + } catch (e) { + console.error(e); + } }); test.serial(`${currentTest} should throw exception when readonly_fields is not an array`, async (t) => { - try { - const newConnection = getTestData(mockFactory).newConnectionToTestDB; - const { token } = await registerUserAndReturnUserInfo(app); - - const createdConnection = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const connectionId = JSON.parse(createdConnection.text).id; - - const createTableSettingsDTO = mockFactory.generateTableSettingsWithoutTypes( - connectionId, - 'connection', - ['title'], - undefined, - 'type', - undefined, - undefined, - ); - - const tableName = 'connection'; - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) - .send(createTableSettingsDTO) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 400); - const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); - t.is(createTableSettingsRO.message, 'The field "readonly_fields" must be an array'); - } catch (e) { - console.error(e); - } + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); + + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = JSON.parse(createdConnection.text).id; + + const createTableSettingsDTO = mockFactory.generateTableSettingsWithoutTypes( + connectionId, + 'connection', + ['title'], + undefined, + 'type', + undefined, + undefined, + ); + + const tableName = 'connection'; + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) + .send(createTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 400); + const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); + t.is(createTableSettingsRO.message, 'The field "readonly_fields" must be an array'); + } catch (e) { + console.error(e); + } }); test.serial(`${currentTest} should throw exception when sortable_by is not an array`, async (t) => { - try { - const newConnection = getTestData(mockFactory).newConnectionToTestDB; - const { token } = await registerUserAndReturnUserInfo(app); - - const createdConnection = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const connectionId = JSON.parse(createdConnection.text).id; - - const createTableSettingsDTO = mockFactory.generateTableSettingsWithoutTypes( - connectionId, - 'connection', - ['title'], - undefined, - undefined, - 'type', - undefined, - ); - - const tableName = 'connection'; - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) - .send(createTableSettingsDTO) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 400); - const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); - t.is(createTableSettingsRO.message, 'The field "sortable_by" must be an array'); - } catch (e) { - console.error(e); - } + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); + + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = JSON.parse(createdConnection.text).id; + + const createTableSettingsDTO = mockFactory.generateTableSettingsWithoutTypes( + connectionId, + 'connection', + ['title'], + undefined, + undefined, + 'type', + undefined, + ); + + const tableName = 'connection'; + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) + .send(createTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 400); + const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); + t.is(createTableSettingsRO.message, 'The field "sortable_by" must be an array'); + } catch (e) { + console.error(e); + } }); test.serial( - `${currentTest} should throw exception when there are no such field in the table for searching`, - async (t) => { - try { - const newConnection = getTestData(mockFactory).newConnectionToTestDB; - const { token } = await registerUserAndReturnUserInfo(app); - - const createdConnection = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const connectionId = JSON.parse(createdConnection.text).id; - - const createTableSettingsDTO = mockFactory.generateTableSettingsWithoutTypes( - connectionId, - 'connection', - ['testField'], - undefined, - undefined, - undefined, - undefined, - ); - - const tableName = 'connection'; - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) - .send(createTableSettingsDTO) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 400); - const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); - t.is(createTableSettingsRO.message, 'There are no such fields: testField - in the table "connection"'); - } catch (e) { - console.error(e); - } - }, + `${currentTest} should throw exception when there are no such field in the table for searching`, + async (t) => { + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); + + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = JSON.parse(createdConnection.text).id; + + const createTableSettingsDTO = mockFactory.generateTableSettingsWithoutTypes( + connectionId, + 'connection', + ['testField'], + undefined, + undefined, + undefined, + undefined, + ); + + const tableName = 'connection'; + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) + .send(createTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 400); + const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); + t.is(createTableSettingsRO.message, 'There are no such fields: testField - in the table "connection"'); + } catch (e) { + console.error(e); + } + }, ); test.serial( - `${currentTest} should throw exception when there are no such field in the table for excluding`, - async (t) => { - try { - const newConnection = getTestData(mockFactory).newConnectionToTestDB; - const { token } = await registerUserAndReturnUserInfo(app); - - const createdConnection = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const connectionId = JSON.parse(createdConnection.text).id; - - const createTableSettingsDTO = mockFactory.generateTableSettingsWithoutTypes( - connectionId, - 'connection', - ['type'], - ['testField'], - undefined, - undefined, - undefined, - ); - - const tableName = 'connection'; - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) - .send(createTableSettingsDTO) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 400); - const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); - t.is(createTableSettingsRO.message, 'There are no such fields: testField - in the table "connection"'); - } catch (e) { - console.error(e); - } - }, + `${currentTest} should throw exception when there are no such field in the table for excluding`, + async (t) => { + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); + + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = JSON.parse(createdConnection.text).id; + + const createTableSettingsDTO = mockFactory.generateTableSettingsWithoutTypes( + connectionId, + 'connection', + ['type'], + ['testField'], + undefined, + undefined, + undefined, + ); + + const tableName = 'connection'; + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) + .send(createTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 400); + const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); + t.is(createTableSettingsRO.message, 'There are no such fields: testField - in the table "connection"'); + } catch (e) { + console.error(e); + } + }, ); test.serial( - `${currentTest} should throw exception when there are no such field in the table for read only`, - async (t) => { - try { - const newConnection = getTestData(mockFactory).newConnectionToTestDB; - const { token } = await registerUserAndReturnUserInfo(app); - - const createdConnection = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const connectionId = JSON.parse(createdConnection.text).id; - - const createTableSettingsDTO = mockFactory.generateTableSettingsWithoutTypes( - connectionId, - 'connection', - ['type'], - undefined, - ['testField'], - undefined, - undefined, - ); - - const tableName = 'connection'; - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) - .send(createTableSettingsDTO) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createTableSettingsResponse.status, 400); - const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); - t.is(createTableSettingsRO.message, 'There are no such fields: testField - in the table "connection"'); - } catch (e) { - console.error(e); - } - }, + `${currentTest} should throw exception when there are no such field in the table for read only`, + async (t) => { + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); + + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = JSON.parse(createdConnection.text).id; + + const createTableSettingsDTO = mockFactory.generateTableSettingsWithoutTypes( + connectionId, + 'connection', + ['type'], + undefined, + ['testField'], + undefined, + undefined, + ); + + const tableName = 'connection'; + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) + .send(createTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 400); + const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); + t.is(createTableSettingsRO.message, 'There are no such fields: testField - in the table "connection"'); + } catch (e) { + console.error(e); + } + }, +); + +currentTest = 'GET /table/rows/:slug columns_view priority'; + +test.serial( + `${currentTest} should use personal table settings columns_view over common table settings when both exist`, + async (t) => { + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); + + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = JSON.parse(createdConnection.text).id; + const tableName = 'connection'; + + // Create common table settings with specific columns_view + const createTableSettingsDTO = mockFactory.generateTableSettings( + connectionId, + tableName, + ['title'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + createTableSettingsDTO.columns_view = ['id', 'title', 'type', 'host']; + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) + .send(createTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 5, + QueryOrderingEnum.DESC, + 'title', + ['id', 'title'], + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${connectionId}`) + .query({ tableName: tableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${connectionId}?tableName=${tableName}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.deepEqual(getTableRowsRO.table_settings.columns_view, ['id', 'title']); + } catch (e) { + console.error(e); + throw e; + } + }, +); + +test.serial( + `${currentTest} should use common table settings columns_view when personal columns_view does not exist`, + async (t) => { + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); + + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = JSON.parse(createdConnection.text).id; + const tableName = 'connection'; + + const createTableSettingsDTO = mockFactory.generateTableSettings( + connectionId, + tableName, + ['title'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + createTableSettingsDTO.columns_view = ['id', 'title', 'type']; + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) + .send(createTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${connectionId}?tableName=${tableName}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.deepEqual(getTableRowsRO.table_settings.columns_view, ['id', 'title', 'type']); + } catch (e) { + console.error(e); + throw e; + } + }, +); + +test.serial( + `${currentTest} should use common table settings columns_view when personal columns_view is empty array`, + async (t) => { + try { + const newConnection = getTestData(mockFactory).newConnectionToTestDB; + const { token } = await registerUserAndReturnUserInfo(app); + + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const connectionId = JSON.parse(createdConnection.text).id; + const tableName = 'connection'; + + const createTableSettingsDTO = mockFactory.generateTableSettings( + connectionId, + tableName, + ['title'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + createTableSettingsDTO.columns_view = ['id', 'title', 'host']; + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connectionId}&tableName=${tableName}`) + .send(createTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 5, + QueryOrderingEnum.DESC, + 'title', + [], + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${connectionId}`) + .query({ tableName: tableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${connectionId}?tableName=${tableName}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.deepEqual(getTableRowsRO.table_settings.columns_view, ['id', 'title', 'host']); + } catch (e) { + console.error(e); + throw e; + } + }, );