From b756dd8cdc46104fc414991c1eff48580a6a3e26 Mon Sep 17 00:00:00 2001 From: Muhammed Mustafa Date: Fri, 2 Sep 2022 14:47:25 +0530 Subject: [PATCH] refactor/Added unit test for delete table row api --- .../unit/rest/tests/factory/column.ts | 37 +++++++++- .../__tests__/unit/rest/tests/factory/row.ts | 64 ++++++++++++++-- .../unit/rest/tests/tableRow.test.ts | 74 ++++++++++++++++--- .../lib/meta/api/dataApis/dataAliasApis.ts | 2 + 4 files changed, 161 insertions(+), 16 deletions(-) diff --git a/packages/nocodb/src/__tests__/unit/rest/tests/factory/column.ts b/packages/nocodb/src/__tests__/unit/rest/tests/factory/column.ts index 194fb5e4aa..d166269835 100644 --- a/packages/nocodb/src/__tests__/unit/rest/tests/factory/column.ts +++ b/packages/nocodb/src/__tests__/unit/rest/tests/factory/column.ts @@ -1,5 +1,6 @@ import { ColumnType, UITypes } from 'nocodb-sdk'; import request from 'supertest'; +import Column from '../../../../../lib/models/Column'; import Model from '../../../../../lib/models/Model'; const defaultColumns = [ @@ -105,7 +106,7 @@ const createColumn = async (context, table, columnAttr) => { ...columnAttr, }); - const column: ColumnType = (await table.getColumns()).find( + const column: Column = (await table.getColumns()).find( (column) => column.title === columnAttr.title ); return column; @@ -207,4 +208,36 @@ const createLookupColumn = async ( return lookupColumn; }; -export { defaultColumns, createColumn, createRollupColumn, createLookupColumn }; +const createLtarColumn = async ( + context, + { + title, + parentTable, + childTable, + type, + }: { + title: string; + parentTable: Model; + childTable: Model; + type: string; + } +) => { + const ltarColumn = await createColumn(context, parentTable, { + title: title, + column_name: title, + uidt: UITypes.LinkToAnotherRecord, + parentId: parentTable.id, + childId: childTable.id, + type: type, + }); + + return ltarColumn; +}; + +export { + defaultColumns, + createColumn, + createRollupColumn, + createLookupColumn, + createLtarColumn, +}; diff --git a/packages/nocodb/src/__tests__/unit/rest/tests/factory/row.ts b/packages/nocodb/src/__tests__/unit/rest/tests/factory/row.ts index 38ebe371c5..654a0ec0d0 100644 --- a/packages/nocodb/src/__tests__/unit/rest/tests/factory/row.ts +++ b/packages/nocodb/src/__tests__/unit/rest/tests/factory/row.ts @@ -1,5 +1,9 @@ +import console from 'console'; import { ColumnType, UITypes } from 'nocodb-sdk'; import request from 'supertest'; +import Column from '../../../../../lib/models/Column'; +import Model from '../../../../../lib/models/Model'; +import Project from '../../../../../lib/models/Project'; const rowValue = (column: ColumnType, index: number) => { switch (column.uidt) { @@ -30,12 +34,24 @@ const getRow = async (context, project, table, id) => { const createRow = async ( context, - project, - table, - columns: ColumnType[], - index + { + project, + table, + index = 0, + }: { + project: Project; + table: Model; + index?: number; + } ) => { + const columns = await table.getColumns(); const rowData = columns.reduce((acc, column) => { + if ( + column.uidt === UITypes.LinkToAnotherRecord || + column.uidt === UITypes.ForeignKey + ) { + return acc; + } acc[column.column_name] = rowValue(column, index); return acc; }, {}); @@ -48,4 +64,42 @@ const createRow = async ( return response.body; }; -export { createRow, getRow }; +// Links 2 table rows together. Will create rows if ids are not provided +const createRelation = async ( + context, + { + project, + table, + childTable, + column, + rowId, + childRowId, + type, + }: { + project: Project; + table: Model; + childTable: Model; + column: Column; + rowId?: string; + childRowId?: string; + type: string; + } +) => { + if (!rowId) { + const row = await createRow(context, { project, table }); + rowId = row['Id']; + } + + if (!childRowId) { + const row = await createRow(context, { table: childTable, project }); + childRowId = row['Id']; + } + + await request(context.app) + .post( + `/api/v1/db/data/noco/${project.id}/${table.id}/${rowId}/${type}/${column.title}/${childRowId}` + ) + .set('xc-auth', context.token); +}; + +export { createRow, getRow, createRelation }; diff --git a/packages/nocodb/src/__tests__/unit/rest/tests/tableRow.test.ts b/packages/nocodb/src/__tests__/unit/rest/tests/tableRow.test.ts index 42de8f2c64..d5b4994923 100644 --- a/packages/nocodb/src/__tests__/unit/rest/tests/tableRow.test.ts +++ b/packages/nocodb/src/__tests__/unit/rest/tests/tableRow.test.ts @@ -7,10 +7,11 @@ import { ColumnType, UITypes } from 'nocodb-sdk'; import { createColumn, createLookupColumn, + createLtarColumn, createRollupColumn, } from './factory/column'; import { createTable } from './factory/table'; -import { createRow, getRow } from './factory/row'; +import { createRelation, createRow, getRow } from './factory/row'; const isColumnsCorrectInResponse = (row, columns: ColumnType[]) => { const responseColumnsListStr = Object.keys(row).sort().join(','); @@ -1087,8 +1088,7 @@ function tableTest() { it('Update table row', async function () { const table = await createTable(context, project); - const columns = await table.getColumns(); - const row = await createRow(context, project, table, columns, 0); + const row = await createRow(context, { project, table }); const updateResponse = await request(context.app) .patch(`/api/v1/db/data/noco/${project.id}/${table.id}/${row['Id']}`) @@ -1113,8 +1113,7 @@ function tableTest() { validate: true, }, }); - const columns = await table.getColumns(); - const row = await createRow(context, project, table, columns, 0); + const row = await createRow(context, { project, table }); await request(context.app) .patch(`/api/v1/db/data/noco/${project.id}/${table.id}/${row['Id']}`) @@ -1138,8 +1137,7 @@ function tableTest() { validate: true, }, }); - const columns = await table.getColumns(); - const row = await createRow(context, project, table, columns, 0); + const row = await createRow(context, { project, table }); const response = await request(context.app) .patch(`/api/v1/db/data/noco/${project.id}/${table.id}/${row['Id']}`) @@ -1162,8 +1160,7 @@ function tableTest() { it('Delete table row', async function () { const table = await createTable(context, project); - const columns = await table.getColumns(); - const row = await createRow(context, project, table, columns, 0); + const row = await createRow(context, { project, table }); await request(context.app) .delete(`/api/v1/db/data/noco/${project.id}/${table.id}/${row['Id']}`) @@ -1176,6 +1173,65 @@ function tableTest() { throw new Error('Wrong delete'); } }); + + it('Delete table row', async function () { + const table = await createTable(context, project); + const row = await createRow(context, { project, table }); + + await request(context.app) + .delete(`/api/v1/db/data/noco/${project.id}/${table.id}/${row['Id']}`) + .set('xc-auth', context.token) + .expect(200); + + const deleteRow = await getRow(context, project, table, row['Id']); + if (deleteRow && Object.keys(deleteRow).length > 0) { + console.log(deleteRow); + throw new Error('Wrong delete'); + } + }); + + it('Delete table row with foreign key contraint', async function () { + const table = await createTable(context, project); + const relatedTable = await createTable(context, project, { + table_name: 'Table2', + title: 'Table2_Title', + }); + const ltarColumn = await createLtarColumn(context, { + title: 'Ltar', + parentTable: table, + childTable: relatedTable, + type: 'hm', + }); + + const row = await createRow(context, { project, table }); + + await createRelation(context, { + project, + table, + childTable: relatedTable, + column: ltarColumn, + type: 'hm', + rowId: row['Id'], + }); + + const response = await request(context.app) + .delete(`/api/v1/db/data/noco/${project.id}/${table.id}/${row['Id']}`) + .set('xc-auth', context.token) + .expect(200); + + const deleteRow = await getRow(context, project, table, row['Id']); + if (!deleteRow) { + throw new Error('Should not delete'); + } + + if ( + !(response.body.message[0] as string).includes( + 'is a LinkToAnotherRecord of' + ) + ) { + throw new Error('Should give ltar foreign key error'); + } + }); } export default function () { diff --git a/packages/nocodb/src/lib/meta/api/dataApis/dataAliasApis.ts b/packages/nocodb/src/lib/meta/api/dataApis/dataAliasApis.ts index 46e7e071ae..4c3f5e9163 100644 --- a/packages/nocodb/src/lib/meta/api/dataApis/dataAliasApis.ts +++ b/packages/nocodb/src/lib/meta/api/dataApis/dataAliasApis.ts @@ -81,6 +81,8 @@ async function dataDelete(req: Request, res: Response) { viewId: view?.id, dbDriver: NcConnectionMgrv2.get(base), }); + + // todo: Should have error http status code const message = await baseModel.hasLTARData(req.params.rowId, model); if (message.length) { res.json({ message });