Browse Source

refactor/Added unit test for bulk insert, update and delete apis

pull/3358/head
Muhammed Mustafa 2 years ago
parent
commit
990c8fc4b4
  1. 10
      packages/nocodb/src/__tests__/unit/rest/init/db.ts
  2. 2
      packages/nocodb/src/__tests__/unit/rest/init/index.ts
  3. 68
      packages/nocodb/src/__tests__/unit/rest/tests/factory/row.ts
  4. 134
      packages/nocodb/src/__tests__/unit/rest/tests/tableRow.test.ts

10
packages/nocodb/src/__tests__/unit/rest/init/db.ts

@ -0,0 +1,10 @@
import { DbConfig } from '../../../../interface/config';
const isSqlite = (context) =>
(context.dbConfig as DbConfig).client === 'sqlite';
const isMysql = (context) =>
(context.dbConfig as DbConfig).client === 'mysql' ||
(context.dbConfig as DbConfig).client === 'mysql2';
export { isSqlite, isMysql };

2
packages/nocodb/src/__tests__/unit/rest/init/index.ts

@ -64,5 +64,5 @@ export default async function () {
const { token } = await createUser({ app: server }, { roles: 'editor' }); const { token } = await createUser({ app: server }, { roles: 'editor' });
return { app: server, token }; return { app: server, token, dbConfig };
} }

68
packages/nocodb/src/__tests__/unit/rest/tests/factory/row.ts

@ -1,13 +1,14 @@
import { ColumnType, UITypes } from 'nocodb-sdk'; import { ColumnType, UITypes } from 'nocodb-sdk';
import request from 'supertest'; import request from 'supertest';
import Column from '../../../../../lib/models/Column'; import Column from '../../../../../lib/models/Column';
import Filter from '../../../../../lib/models/Filter';
import Model from '../../../../../lib/models/Model'; import Model from '../../../../../lib/models/Model';
import Project from '../../../../../lib/models/Project'; import Project from '../../../../../lib/models/Project';
import Sort from '../../../../../lib/models/Sort';
import NcConnectionMgrv2 from '../../../../../lib/utils/common/NcConnectionMgrv2';
const rowValue = (column: ColumnType, index: number) => { const rowValue = (column: ColumnType, index: number) => {
switch (column.uidt) { switch (column.uidt) {
case UITypes.ID:
return index;
case UITypes.Number: case UITypes.Number:
return index; return index;
case UITypes.SingleLineText: case UITypes.SingleLineText:
@ -31,6 +32,30 @@ const getRow = async (context, project, table, id) => {
return response.body; return response.body;
}; };
const listRow = async ({
project,
table,
options,
}: {
project: Project;
table: Model;
options?: {
limit?: any;
offset?: any;
filterArr?: Filter[];
sortArr?: Sort[];
};
}) => {
const baseModel = await Model.getBaseModelSQL({
id: table.id,
dbDriver: NcConnectionMgrv2.get(project.bases[0]),
});
const ignorePagination = !options;
return await baseModel.list(options, ignorePagination);
};
const getOneRow = async ( const getOneRow = async (
context, context,
{ project, table }: { project: Project; table: Model } { project, table }: { project: Project; table: Model }
@ -42,6 +67,25 @@ const getOneRow = async (
return response.body; return response.body;
}; };
const generateDefaultRowAttributes = ({
columns,
index,
}: {
columns: ColumnType[];
index: number;
}) =>
columns.reduce((acc, column) => {
if (
column.uidt === UITypes.LinkToAnotherRecord ||
column.uidt === UITypes.ForeignKey ||
column.uidt === UITypes.ID
) {
return acc;
}
acc[column.column_name] = rowValue(column, index);
return acc;
}, {});
const createRow = async ( const createRow = async (
context, context,
{ {
@ -55,16 +99,7 @@ const createRow = async (
} }
) => { ) => {
const columns = await table.getColumns(); const columns = await table.getColumns();
const rowData = columns.reduce((acc, column) => { const rowData = generateDefaultRowAttributes({ columns, index });
if (
column.uidt === UITypes.LinkToAnotherRecord ||
column.uidt === UITypes.ForeignKey
) {
return acc;
}
acc[column.column_name] = rowValue(column, index);
return acc;
}, {});
const response = await request(context.app) const response = await request(context.app)
.post(`/api/v1/db/data/noco/${project.id}/${table.id}`) .post(`/api/v1/db/data/noco/${project.id}/${table.id}`)
@ -112,4 +147,11 @@ const createRelation = async (
.set('xc-auth', context.token); .set('xc-auth', context.token);
}; };
export { createRow, getRow, createRelation, getOneRow }; export {
createRow,
getRow,
createRelation,
getOneRow,
listRow,
generateDefaultRowAttributes,
};

134
packages/nocodb/src/__tests__/unit/rest/tests/tableRow.test.ts

@ -11,7 +11,15 @@ import {
createRollupColumn, createRollupColumn,
} from './factory/column'; } from './factory/column';
import { createTable } from './factory/table'; import { createTable } from './factory/table';
import { createRelation, createRow, getOneRow, getRow } from './factory/row'; import {
createRelation,
createRow,
generateDefaultRowAttributes,
getOneRow,
getRow,
listRow,
} from './factory/row';
import { isMysql, isSqlite } from '../init/db';
const isColumnsCorrectInResponse = (row, columns: ColumnType[]) => { const isColumnsCorrectInResponse = (row, columns: ColumnType[]) => {
const responseColumnsListStr = Object.keys(row).sort().join(','); const responseColumnsListStr = Object.keys(row).sort().join(',');
@ -1263,6 +1271,130 @@ function tableTest() {
throw new Error('Should not exist'); throw new Error('Should not exist');
} }
}); });
it('Bulk insert', async function () {
const table = await createTable(context, project);
const columns = await table.getColumns();
const rowAttributes = Array(99)
.fill(0)
.map((index) => generateDefaultRowAttributes({ columns, index }));
const response = await request(context.app)
.post(`/api/v1/db/data/bulk/noco/${project.id}/${table.id}`)
.set('xc-auth', context.token)
.send(rowAttributes)
.expect(200);
const rows = await listRow({ project, table });
console.log(rows.length);
// Mysql will not return the batched inserted rows
if (!isMysql(context)) {
if (
!isSqlite(context) &&
response.body.length !== rowAttributes.length &&
rows.length !== rowAttributes.length
) {
throw new Error('Wrong number of rows inserted');
}
// Max 10 rows will be inserted in sqlite
if (isSqlite(context) && response.body.length !== 10) {
throw new Error('Wrong number of rows inserted');
}
} else {
if (rows.length !== rowAttributes.length) {
throw new Error('Wrong number of rows inserted');
}
}
});
it('Bulk insert 400 records', async function () {
const table = await createTable(context, project);
const columns = await table.getColumns();
const rowAttributes = Array(400)
.fill(0)
.map((index) => generateDefaultRowAttributes({ columns, index }));
const response = await request(context.app)
.post(`/api/v1/db/data/bulk/noco/${project.id}/${table.id}`)
.set('xc-auth', context.token)
.send(rowAttributes)
.expect(200);
const rows = await listRow({ project, table });
// Mysql will not return the batched inserted rows
if (!isMysql(context)) {
if (
!isSqlite(context) &&
response.body.length !== rowAttributes.length &&
rows.length !== rowAttributes.length
) {
throw new Error('Wrong number of rows inserted');
}
// Max 10 rows will be inserted in sqlite
if (isSqlite(context) && response.body.length !== 10) {
throw new Error('Wrong number of rows inserted');
}
} else {
if (rows.length !== rowAttributes.length) {
throw new Error('Wrong number of rows inserted');
}
}
});
it('Bulk update', async function () {
const table = await createTable(context, project);
const arr = Array(120)
.fill(0)
.map((_, index) => index);
for (const index of arr) {
await createRow(context, { project, table, index });
}
const rows = await listRow({ project, table });
await request(context.app)
.patch(`/api/v1/db/data/bulk/noco/${project.id}/${table.id}`)
.set('xc-auth', context.token)
.send(
rows.map((row) => ({ title: `new-${row['Title']}`, id: row['Id'] }))
)
.expect(200);
const updatedRows: Array<any> = await listRow({ project, table });
if (!updatedRows.every((row) => row['Title'].startsWith('new-'))) {
throw new Error('Wrong number of rows updated');
}
});
it('Bulk delete', async function () {
const table = await createTable(context, project);
const arr = Array(120)
.fill(0)
.map((_, index) => index);
for (const index of arr) {
await createRow(context, { project, table, index });
}
const rows = await listRow({ project, table });
await request(context.app)
.delete(`/api/v1/db/data/bulk/noco/${project.id}/${table.id}`)
.set('xc-auth', context.token)
.send(rows.map((row) => ({ id: row['Id'] })))
.expect(200);
const updatedRows: Array<any> = await listRow({ project, table });
if (updatedRows.length !== 0) {
throw new Error('Wrong number of rows delete');
}
});
} }
export default function () { export default function () {

Loading…
Cancel
Save