diff --git a/backend/src/entities/connection-properties/use-cases/update-connection-properties.use.case.ts b/backend/src/entities/connection-properties/use-cases/update-connection-properties.use.case.ts index 730d2f86d..d96c8c121 100644 --- a/backend/src/entities/connection-properties/use-cases/update-connection-properties.use.case.ts +++ b/backend/src/entities/connection-properties/use-cases/update-connection-properties.use.case.ts @@ -13,6 +13,7 @@ import { } from '../utils/build-update-connection-properties-object.js'; import { validateCreateConnectionPropertiesDs } from '../utils/validate-create-connection-properties-ds.js'; import { IUpdateConnectionProperties } from './connection-properties-use.cases.interface.js'; +import { TableCategoriesEntity } from '../../table-categories/table-categories.entity.js'; @Injectable() export class UpdateConnectionPropertiesUseCase @@ -46,30 +47,62 @@ export class UpdateConnectionPropertiesUseCase const updatePropertiesObject: IUpdateConnectionPropertiesObject = buildUpdateConnectionPropertiesObject(inputData); const updated = Object.assign(connectionPropertiesToUpdate, updatePropertiesObject); - const categoriesToRemove = await this._dbContext.tableCategoriesRepository.find({ + const foundCategories = await this._dbContext.tableCategoriesRepository.find({ where: { connection_properties_id: connectionPropertiesToUpdate.id }, }); - if (categoriesToRemove && categoriesToRemove.length > 0) { - await this._dbContext.tableCategoriesRepository.remove(categoriesToRemove); - updated.table_categories = []; - } + const newCategories: Array = []; - const updatedProperties = await this._dbContext.connectionPropertiesRepository.saveNewConnectionProperties(updated); - if (table_categories && table_categories.length) { - const createdCategories = table_categories.map((category) => { - const newCategory = this._dbContext.tableCategoriesRepository.create({ - category_name: category.category_name, - tables: category.tables, - category_color: category.category_color, - category_id: category.category_id, + if (table_categories && table_categories.length > 0) { + const categoriesToRemove = foundCategories.filter((foundCategory) => { + return !table_categories?.some((inputCategory) => inputCategory.category_id === foundCategory.category_id); + }); + if (categoriesToRemove && categoriesToRemove.length > 0) { + await this._dbContext.tableCategoriesRepository.remove(categoriesToRemove); + } + + const categoriesToCreate = table_categories.filter((inputCategory) => { + return !foundCategories.some((foundCategory) => foundCategory.category_id === inputCategory.category_id); + }); + + if (categoriesToCreate && categoriesToCreate.length > 0) { + const createdCategories = categoriesToCreate.map((category) => { + const newCategory = this._dbContext.tableCategoriesRepository.create({ + category_name: category.category_name, + tables: category.tables, + category_color: category.category_color, + category_id: category.category_id, + }); + newCategory.connection_properties = connectionPropertiesToUpdate; + return newCategory; }); - newCategory.connection_properties = updatedProperties; - return newCategory; + const savedNewCategories = await this._dbContext.tableCategoriesRepository.save(createdCategories); + newCategories.push(...savedNewCategories); + } + + const categoriesToUpdate = table_categories.filter((inputCategory) => { + return foundCategories.some((foundCategory) => foundCategory.category_id === inputCategory.category_id); }); - const savedCategories = await this._dbContext.tableCategoriesRepository.save(createdCategories); - updatedProperties.table_categories = savedCategories; + + for (const category of categoriesToUpdate) { + const categoryToUpdate = foundCategories.find( + (foundCategory) => foundCategory.category_id === category.category_id, + ); + if (categoryToUpdate) { + categoryToUpdate.category_name = category.category_name; + categoryToUpdate.category_color = category.category_color; + categoryToUpdate.tables = category.tables; + const savedUpdatedCategory = await this._dbContext.tableCategoriesRepository.save(categoryToUpdate); + newCategories.push(savedUpdatedCategory); + } + } + } else { + newCategories.push(...foundCategories); } + + const updatedProperties = await this._dbContext.connectionPropertiesRepository.saveNewConnectionProperties(updated); + updatedProperties.table_categories = newCategories; + return buildFoundConnectionPropertiesDs(updatedProperties); } } diff --git a/backend/test/ava-tests/saas-tests/connection-properties-e2e.test.ts b/backend/test/ava-tests/saas-tests/connection-properties-e2e.test.ts index 29bad3828..300f922ae 100644 --- a/backend/test/ava-tests/saas-tests/connection-properties-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/connection-properties-e2e.test.ts @@ -16,6 +16,7 @@ import { ValidationException } from '../../../src/exceptions/custom-exceptions/v import { ValidationError } from 'class-validator'; import { Cacher } from '../../../src/helpers/cache/cacher.js'; import { WinstonLogger } from '../../../src/entities/logging/winston-logger.js'; +import { CreateTableCategoryDto } from '../../../src/entities/table-categories/dto/create-table-category.dto.js'; const mockFactory = new MockFactory(); let app: INestApplication; @@ -273,7 +274,7 @@ test.serial(`${currentTest} should return created connection properties with tab updateConnectionPropertiesROWithoutCategories.default_showing_table, updatedConnectionPropertiesWithOutCategories.default_showing_table, ); - t.is(updateConnectionPropertiesROWithoutCategories.table_categories.length, 0); + t.is(updateConnectionPropertiesROWithoutCategories.table_categories.length, 1); } catch (e) { throw e; } @@ -623,9 +624,93 @@ test.serial(`${currentTest} should return updated connection properties`, async } }); -// test.serial(`${currentTest} `, async (t) => { -// try { -// } catch (e) { -// throw e; -// } -// }); +test.serial( + `${currentTest} should keep created table categories if the exists return updated connection properties`, + async (t) => { + try { + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + const secondHiddenTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + await resetPostgresTestDB(secondHiddenTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(newConnectionProperties) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); + t.is(createConnectionPropertiesResponse.status, 201); + t.is(createConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); + t.is(createConnectionPropertiesRO.connectionId, createConnectionRO.id); + + const categoriesDTO: Array = [ + { + category_name: 'Category 1', + category_color: '#FF5733', + tables: [testTableName], + category_id: 'cat-001', + }, + ]; + + const createTableCategoriesResponse = await request(app.getHttpServer()) + .put(`/table-categories/${createConnectionRO.id}`) + .send(categoriesDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createTableCategoriesRO = JSON.parse(createTableCategoriesResponse.text); + + t.is(createTableCategoriesResponse.status, 200); + + const propertiesCopy = JSON.parse(JSON.stringify(newConnectionProperties)); + propertiesCopy.hidden_tables = [testTableName, secondHiddenTableName]; + + const updateConnectionPropertiesResponse = await request(app.getHttpServer()) + .put(`/connection/properties/${createConnectionRO.id}`) + .send(propertiesCopy) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateConnectionPropertiesResponse.status, 200); + + const updateConnectionPropertiesRO = JSON.parse(updateConnectionPropertiesResponse.text); + t.is(updateConnectionPropertiesRO.hidden_tables.length, 2); + t.is(updateConnectionPropertiesRO.hidden_tables.includes(testTableName), true); + t.is(updateConnectionPropertiesRO.hidden_tables.includes(secondHiddenTableName), true); + t.is(updateConnectionPropertiesRO.connectionId, createConnectionRO.id); + t.is(updateConnectionPropertiesRO.table_categories.length, 1); + t.is(updateConnectionPropertiesRO.table_categories[0].category_name, 'Category 1'); + t.is(updateConnectionPropertiesRO.table_categories[0].tables.length, 1); + t.is(updateConnectionPropertiesRO.table_categories[0].tables[0], testTableName); + + const findTableCategoriesResponse = await request(app.getHttpServer()) + .get(`/table-categories/${createConnectionRO.id}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const findTableCategoriesRO = JSON.parse(findTableCategoriesResponse.text); + + t.is(findTableCategoriesResponse.status, 200); + + t.is(findTableCategoriesRO.length, 1); + t.is(findTableCategoriesRO[0].category_name, 'Category 1'); + t.is(findTableCategoriesRO[0].tables.length, 1); + t.is(findTableCategoriesRO[0].tables[0], testTableName); + } catch (e) { + throw e; + } + }, +);