Browse Source

refactor(nocodb): remove outdated tests

pull/4237/head
Wing-Kam Wong 2 years ago
parent
commit
c185f616ac
  1. 24
      packages/nocodb/src/__tests__/TemplateParser.test.ts
  2. 122
      packages/nocodb/src/__tests__/formula.test.ts
  3. 869
      packages/nocodb/src/__tests__/graphql.test.ts
  4. 513
      packages/nocodb/src/__tests__/meta.apisv2.test.ts
  5. 107
      packages/nocodb/src/__tests__/noco/NcConfigFactory.test.ts
  6. 18
      packages/nocodb/src/__tests__/noco/dbConfig.json
  7. 921
      packages/nocodb/src/__tests__/rest.test.ts
  8. 1539
      packages/nocodb/src/__tests__/restv2.test.ts
  9. 707
      packages/nocodb/src/__tests__/template.ts
  10. 70
      packages/nocodb/src/__tests__/tsconfig.json
  11. 80
      packages/nocodb/src/__tests__/unit/lib/meta/api/dataApis/dataAliasApis.test.ts

24
packages/nocodb/src/__tests__/TemplateParser.test.ts

@ -1,24 +0,0 @@
import { expect } from 'chai';
import 'mocha';
import NcTemplateParser from '../lib/v1-legacy/templates/NcTemplateParser';
import template from './template';
describe('Template parser', () => {
// Called once before any of the tests in this block begin.
before(function (done) {
done();
});
after((done) => {
done();
});
describe('Parse blog templates', function () {
it('Simple formula', function () {
const parser = new NcTemplateParser({ client: 'mysql', template });
const { tables } = parser.parse();
expect(tables).length(3);
});
});
});

122
packages/nocodb/src/__tests__/formula.test.ts

@ -1,122 +0,0 @@
import { expect } from 'chai';
import 'mocha';
import knex from '../lib/db/sql-data-mapper/lib/sql/CustomKnex';
import formulaQueryBuilderFromString from '../lib/db/sql-data-mapper/lib/sql/formulaQueryBuilderFromString';
process.env.TEST = 'test';
describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
let knexMysqlRef;
let knexPgRef;
let knexMssqlRef;
let knexSqliteRef;
// Called once before any of the tests in this block begin.
before(function (done) {
knexMysqlRef = knex({ client: 'mysql2' });
knexMssqlRef = knex({ client: 'mssql' });
knexPgRef = knex({ client: 'pg' });
knexSqliteRef = knex({ client: 'sqlite3' });
done();
});
after((done) => {
done();
});
describe('Formulas', function () {
it('Simple formula', function (done) {
expect(
formulaQueryBuilderFromString(
"concat(city, ' _ ',city_id+country_id)",
'a',
knexMysqlRef
).toQuery()
).eq("concat(`city`,' _ ',`city_id` + `country_id`) as a");
expect(
formulaQueryBuilderFromString(
"concat(city, ' _ ',city_id+country_id)",
'a',
knexPgRef
).toQuery()
).eq('concat("city",\' _ \',"city_id" + "country_id") as a');
expect(
formulaQueryBuilderFromString(
"concat(city, ' _ ',city_id+country_id)",
'a',
knexMssqlRef
).toQuery()
).eq("concat([city],' _ ',[city_id] + [country_id]) as a");
expect(
formulaQueryBuilderFromString(
"concat(city, ' _ ',city_id+country_id)",
'a',
knexSqliteRef
).toQuery()
).eq("`city` || ' _ ' || (`city_id` + `country_id`) as a");
done();
});
it('Addition', function (done) {
expect(
formulaQueryBuilderFromString(
'ADD(city_id,country_id,2,3,4,5,4)',
'a',
knexMysqlRef
).toQuery()
).eq('`city_id` + `country_id` + 2 + 3 + 4 + 5 + 4 as a');
expect(
formulaQueryBuilderFromString(
'ADD(city_id,country_id,2,3,4,5,4)',
'a',
knexPgRef
).toQuery()
).eq('"city_id" + "country_id" + 2 + 3 + 4 + 5 + 4 as a');
expect(
formulaQueryBuilderFromString(
'ADD(city_id,country_id,2,3,4,5,4)',
'a',
knexMssqlRef
).toQuery()
).eq('[city_id] + [country_id] + 2 + 3 + 4 + 5 + 4 as a');
expect(
formulaQueryBuilderFromString(
'ADD(city_id,country_id,2,3,4,5,4)',
'a',
knexSqliteRef
).toQuery()
).eq('`city_id` + `country_id` + 2 + 3 + 4 + 5 + 4 as a');
done();
});
it('Average', function (done) {
expect(
formulaQueryBuilderFromString(
'AVG(city_id,country_id,2,3,4,5,4)',
'a',
knexMysqlRef
).toQuery()
).eq('(`city_id` + `country_id` + 2 + 3 + 4 + 5 + 4) / 7 as a');
expect(
formulaQueryBuilderFromString(
'AVG(city_id,country_id,2,3,4,5,4)',
'a',
knexPgRef
).toQuery()
).eq('("city_id" + "country_id" + 2 + 3 + 4 + 5 + 4) / 7 as a');
expect(
formulaQueryBuilderFromString(
'AVG(city_id,country_id,2,3,4,5,4)',
'a',
knexMssqlRef
).toQuery()
).eq('([city_id] + [country_id] + 2 + 3 + 4 + 5 + 4) / 7 as a');
expect(
formulaQueryBuilderFromString(
'AVG(city_id,country_id,2,3,4,5,4)',
'a',
knexSqliteRef
).toQuery()
).eq('(`city_id` + `country_id` + 2 + 3 + 4 + 5 + 4) / 7 as a');
done();
});
});
});

869
packages/nocodb/src/__tests__/graphql.test.ts

@ -1,869 +0,0 @@
import { expect } from 'chai';
import 'mocha';
import express from 'express';
import request from 'supertest';
import { Noco } from '../lib';
import NcConfigFactory from '../lib/utils/NcConfigFactory';
process.env.TEST = 'test';
const dbConfig = NcConfigFactory.urlToDbConfig(
NcConfigFactory.extractXcUrlFromJdbc(process.env[`DATABASE_URL`]),
null,
null,
'graphql'
);
const projectCreateReqBody = {
api: 'projectCreateByWeb',
query: { skipProjectHasDb: 1 },
args: {
project: { title: 'sebulba', folder: 'config.xc.json', type: 'pg' },
projectJson: {
title: 'sebulba',
version: '0.6',
envs: {
_noco: {
db: [dbConfig],
apiClient: { data: [] },
},
},
workingEnv: '_noco',
meta: {
version: '0.6',
seedsFolder: 'seeds',
queriesFolder: 'queries',
apisFolder: 'apis',
projectType: 'graphql',
type: 'mvc',
language: 'ts',
db: { client: 'sqlite3', connection: { filename: 'noco.db' } },
},
seedsFolder: 'seeds',
queriesFolder: 'queries',
apisFolder: 'apis',
projectType: 'graphql',
type: 'docker',
language: 'ts',
apiClient: { data: [] },
auth: {
jwt: { secret: 'b8ed266d-4475-4028-8c3d-590f58bee867', dbAlias: 'db' },
},
},
},
};
describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
let app;
let token;
let projectId;
// Called once before any of the tests in this block begin.
before(function (done) {
this.timeout(10000);
(async () => {
const server = express();
server.enable('trust proxy');
server.use(await Noco.init({}));
app = server;
})()
.then(done)
.catch(done);
});
after((done) => {
done();
// process.exit();
});
//
// /**** Authentication : START ****/
// describe('Authentication', function () {
//
// const EMAIL_ID = 'abc@g.com'
// const VALID_PASSWORD = '1234566778';
//
// it('Signup with valid email', function (done) {
// request(app)
// .post('/v1-legacy/graphql')
// .send({
// query: `mutation{ SignUp(data : { email: "${EMAIL_ID}", password: "${VALID_PASSWORD}"}){ token }}`
// })
// .expect(200)
// .end(async function (err, res) {
// if (err) return done(err);
// token = res.body.data?.SignUp?.token;
//
// expect(token).to.be.a('string')
// // const payload: any = await JWT.verifyToken(token, config.auth.jwt.secret, config.auth.jwt.options)
// //
// // expect(payload.email).to.be.eq(EMAIL_ID)
//
// done();
// });
// });
//
// it('Signup with invalid email', function (done) {
// request(app)
// .post('/v1-legacy/graphql')
// .send({
// query: `mutation{ SignUp(data : { email: "test", password: "${VALID_PASSWORD}"}){ token }}`
// })
// .expect(200)
// .end(function (err, res) {
// if (err) return done(err);
// const errorMsg = res.body.errors[0].message;
// expect(errorMsg).to.be.a('string')
// done();
// });
//
// });
//
// it('Signin with valid email', function (done) {
// request(app)
// .post('/v1-legacy/graphql')
// .send({
// query: `mutation{ SignIn(data : { email: "${EMAIL_ID}", password: "${VALID_PASSWORD}"}){ token }}`
// })
// .expect(200)
// .end(async function (err, res) {
// if (err) return done(err);
// const data = res.body.data;
// expect(data.SignIn).to.be.a('object')
// token = res.body.data?.SignIn?.token;
// // const payload: any = await JWT.verifyToken(token, config.auth.jwt.secret, config.auth.jwt.options)
// expect(token).to.be.a('string')
// // expect(payload.email).to.be.equal(EMAIL_ID)
// done();
// });
//
// });
//
// it('me', function (done) {
// request(app)
// .post('/v1-legacy/graphql')
// .set({'xc-auth': token})
// .send({
// query: `{ Me{ email id }}`
// })
// .expect(200)
// .end(function (err, res) {
// if (err) done(err);
// const data = res.body.data;
// expect(data.Me).to.be.a('object')
// expect(data.Me.email).to.be.equal(EMAIL_ID)
// done();
// });
//
// });
//
//
// it('Signin with invalid email', function (done) {
// request(app)
// .post('/v1-legacy/graphql')
// .send({
// query: `mutation{ SignIn(data : { email: "abc@abcc.com", password: "randomPassord"}){ token }}`
// })
// .expect(200)
// .end(function (err, res) {
// if (err) done(err);
// const errorMsg = res.body.errors[0].message;
// expect(errorMsg.indexOf('not registered')).to.be.greaterThan(-1)
// done();
// });
//
// });
//
// it('Forgot password with a non-existing email id', function (done) {
// request(app)
// .post('/v1-legacy/graphql')
// .send({
// query: `mutation{ PasswordForgot(email: "abc@abcc.com")}`
// })
// .expect(200, function (err, res) {
// if (err) done(err);
//
// const errorMsg = res.body.errors[0].message;
// expect(errorMsg).to.be.equal("This email is not registered with us.")
// done();
// })
// });
//
// it('Forgot password with an existing email id', function (done) {
// request(app)
// .post('/v1-legacy/graphql')
// .send({
// query: `mutation{ PasswordForgot(email: "${EMAIL_ID}")}`
// })
// .expect(200)
// .end(function (err, res) {
// if (err) done(err);
// expect(res.body.data.PasswordForgot).to.be.true
// done();
// })
// });
//
// it('Email validate with an invalid token', function (done) {
// request(app)
// .post('/v1-legacy/graphql')
// .send({
// query: `mutation{ EmailValidate(tokenId: "invalid-token-id")}`
// })
// .expect(200, function (err, res) {
// if (err) done(err);
// const errorMsg = res.body.errors[0].message;
// expect(errorMsg).to.be.equal("Invalid verification url")
// done()
// })
// });
//
// it('Reset Password with an invalid token', function (done) {
// request(app)
// .post('/v1-legacy/graphql')
// .send({
// query: `mutation{ PasswordReset(password:"somePassword",tokenId: "invalid-token-id")}`
// })
// .expect(200, function (err, res) {
// if (err) done(err);
// const errorMsg = res.body.errors[0].message;
// expect(errorMsg).to.be.equal("Invalid token")
// done()
// })
// });
// });
//
// /**** Authentication : END ****/
/**************** START : Auth ****************/
describe('Authentication', function () {
this.timeout(10000);
const EMAIL_ID = 'abc@g.com';
const VALID_PASSWORD = '1234566778';
it('Signup with valid email', function (done) {
this.timeout(20000);
request(app)
.post('/auth/signup')
.send({ email: EMAIL_ID, password: VALID_PASSWORD })
.expect(200, (err, res) => {
if (err) {
expect(res.status).to.equal(400);
} else {
const token = res.body.token;
expect(token).to.be.a('string');
}
done();
});
});
it('Signup with invalid email', (done) => {
request(app)
.post('/auth/signup')
.send({ email: 'test', password: VALID_PASSWORD })
.expect(400, done);
});
it('Signin with valid credentials', function (done) {
request(app)
.post('/auth/signin')
.send({ email: EMAIL_ID, password: VALID_PASSWORD })
.expect(200, async function (err, res) {
if (err) {
return done(err);
}
token = res.body.token;
expect(token).to.be.a('string');
// todo: verify jwt token payload
// const payload: any = await JWT.verifyToken(token, config.auth.jwt.secret, config.auth.jwt.options)
// expect(payload.email).to.eq(EMAIL_ID)
// expect(payload.roles).to.eq('owner,creator,editor')
done();
});
});
it('me', function (done) {
request(app)
.get('/user/me')
.set('xc-auth', token)
.expect(200, function (err, res) {
if (err) {
return done(err);
}
const email = res.body.email;
expect(email).to.equal(EMAIL_ID);
done();
});
});
it('Change password', function (done) {
request(app)
.post('/user/password/change')
.set('xc-auth', token)
.send({ currentPassword: 'password', newPassword: 'password' })
.expect(400, done);
});
it('Change password - after logout', function (done) {
// todo:
request(app)
.post('/user/password/change')
.send({ currentPassword: 'password', newPassword: 'password' })
.expect(500, function (_err, _res) {
done();
});
});
it('Signin with invalid credentials', function (done) {
request(app)
.post('/auth/signin')
.send({ email: 'abc@abc.com', password: VALID_PASSWORD })
.expect(400, done);
});
it('Signin with invalid password', function (done) {
request(app)
.post('/auth/signin')
.send({ email: EMAIL_ID, password: 'wrongPassword' })
.expect(400, done);
});
it('Forgot password with a non-existing email id', function (done) {
request(app)
.post('/auth/password/forgot')
.send({ email: 'abc@abc.com' })
.expect(200, done);
});
it('Forgot password with an existing email id', function (done) {
this.timeout(10000);
request(app)
.post('/auth/password/forgot')
.send({ email: EMAIL_ID })
.expect(200, done);
});
it('Email validate with an invalid token', function (done) {
request(app)
.post('/auth/email/validate/someRandomValue')
.send({ email: EMAIL_ID })
.expect(400, done);
});
it('Email validate with a valid token', function (done) {
console.log('eeee');
// todo :
done();
// request(app)
// .post('/auth/email/validate/someRandomValue')
// .send({email: EMAIL_ID})
// .expect(500, done);
});
it('Forgot password validate with an invalid token', function (done) {
request(app)
.post('/auth/token/validate/someRandomValue')
.send({ email: EMAIL_ID })
.expect(400, done);
});
it('Forgot password validate with a valid token', function (done) {
// todo
done();
// request(app)
// .post('/auth/token/validate/someRandomValue')
// .send({email: EMAIL_ID})
// .expect(500, done);
});
it('Reset Password with an invalid token', function (done) {
request(app)
.post('/auth/password/reset/someRandomValue')
.send({ password: 'anewpassword' })
.expect(400, done);
});
it('Reset Password with an valid token', function (done) {
//todo
done();
// request(app)
// .post('/auth/password/reset/someRandomValue')
// .send({password: 'anewpassword'})
// .expect(500, done);
});
});
describe('Project', function () {
const EMAIL_ID = 'abc@g.com';
const VALID_PASSWORD = '1234566778';
before(function (done) {
this.timeout(120000);
request(app)
.post('/auth/signin')
.send({ email: EMAIL_ID, password: VALID_PASSWORD })
.expect(200, async function (_err, res) {
token = res.body.token;
request(app)
.post('/dashboard')
.set('xc-auth', token)
.send(projectCreateReqBody)
.expect(200, (err, res) => {
if (err) {
return done(err);
}
projectId = res.body.id;
done();
});
});
});
/**** country : START ****/
describe('country', function () {
/**** Query : START ****/
it('countryList', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryList(limit:5){ country_id country } }`,
})
.expect(200, function (err, res) {
if (err) done(err);
const list = res.body.data.countryList;
expect(list).length.to.be.most(5);
expect(list[0]).to.have.all.keys(['country_id', 'country']);
done();
});
});
it('countryList - with sort', function (done) {
// todo: order -> sort
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryList(sort:"-country_id"){ country_id country } }`,
})
.expect(200, function (err, res) {
if (err) done(err);
const list = res.body.data.countryList;
expect(list[0]).to.have.all.keys(['country_id', 'country']);
expect(list).satisfy((array) => {
let i = array.length;
while (--i) {
if (array[i].country_id > array[i - 1].country_id) return false;
}
return true;
}, 'Should be in descending order');
done();
});
});
it('countryList - with limit', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryList(limit:6){ country_id country } }`,
})
.expect(200, function (err, res) {
if (err) done(err);
const list = res.body.data.countryList;
expect(list[0]).to.have.all.keys(['country_id', 'country']);
expect(list).to.have.length.most(6);
done();
});
});
it('countryList - with offset', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryList(offset:0,limit:6){ country_id country } }`,
})
.expect(200, function (err, res) {
if (err) done(err);
const list1 = res.body.data.countryList;
expect(list1[0]).to.have.all.keys(['country_id', 'country']);
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryList(offset:1,limit:5){ country_id country } }`,
})
.expect(200, function (err, res1) {
if (err) done(err);
const list2 = res1.body.data.countryList;
expect(list2[0]).to.have.all.keys(['country_id', 'country']);
expect(list2).satisfy(
(arr) =>
arr.every(
({ country, country_id }, i) =>
country === list1[i + 1].country &&
country_id === list1[i + 1].country_id
),
'Both data should need to be equal where offset vary with 1'
);
done();
});
});
});
it('countryList - nested count', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryList{ country_id country cityCount} }`,
})
.expect(200, function (err, res) {
if (err) done(err);
const list = res.body.data.countryList;
expect(list[0]).to.have.all.keys([
'country_id',
'country',
'cityCount',
]);
expect(list[0].cityCount).to.be.a('number');
expect(list[0].cityCount % 1).to.be.equal(0);
done();
});
});
it('countryList - nested cityList', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryList{ country_id country cityList { city country_id }} }`,
})
.expect(200, function (err, res) {
if (err) done(err);
const list = res.body.data.countryList;
expect(list[0]).to.have.all.keys([
'country_id',
'country',
'cityList',
]);
expect(list[0].cityList).to.be.a('Array');
if (dbConfig.client !== 'mssql') {
expect(list[0].cityList[0]).to.be.a('object');
expect(list[0].cityList[0]).to.have.all.keys([
'country_id',
'city',
]);
expect(Object.keys(list[0].cityList[0])).to.have.length(2);
expect(list[0].cityList[0].country_id).to.be.equal(
list[0].country_id
);
}
done();
});
});
it('countryRead', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryRead(id: "1"){ country_id country } } `,
})
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryRead;
expect(data).to.be.a('object');
expect(data).to.have.all.keys(['country_id', 'country']);
done();
});
});
it('countryExists', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryExists(id: "1") } `,
})
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryExists;
expect(data).to.be.a('boolean');
expect(data).to.be.equal(true);
done();
});
});
it('countryExists - with non-existing id', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryExists(id: "30000") } `,
})
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryExists;
expect(data).to.be.a('boolean');
expect(data).to.be.equal(false);
done();
});
});
it('countryFindOne', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryFindOne (where: "(country_id,eq,1)"){ country country_id } } `,
})
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryFindOne;
expect(data).to.be.a('object');
expect(data).to.have.all.keys(['country', 'country_id']);
expect(data.country_id).to.be.equal(1);
done();
});
});
it('countryCount - filter by id', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryCount (where: "(country_id,eq,1)") } `,
})
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryCount;
expect(data).to.be.a('number');
expect(data).to.be.equal(1);
done();
});
});
it('countryDistinct', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryDistinct(column_name: "last_update") { last_update } } `,
})
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryDistinct;
expect(data).to.be.a('array');
expect(data[0]).to.be.a('object');
expect(data[0]).to.have.all.keys(['last_update']);
expect(data[0].last_update).to.be.match(/\d+/);
done();
});
});
if (dbConfig.client !== 'mssql') {
it('countryGroupBy', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryGroupBy(fields: "last_update",limit:5) { last_update count } } `,
})
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryGroupBy;
expect(data.length).to.be.most(5);
expect(data[0].count).to.be.greaterThan(0);
expect(data[0].last_update).to.be.a('string');
expect(Object.keys(data[0]).length).to.be.equal(2);
done();
});
});
it('countryGroupBy - Multiple', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryGroupBy(fields: "last_update,country",limit:5) { last_update country count } } `,
})
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryGroupBy;
expect(data.length).to.be.most(5);
expect(data[0].count).to.be.greaterThan(0);
expect(data[0].last_update).to.be.a('string');
expect(data[0].country).to.be.a('string');
expect(Object.keys(data[0]).length).to.be.equal(3);
done();
});
});
it('countryAggregate', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryAggregate(func: "sum,avg,min,max,count", column_name : "country_id") { sum avg min max count } } `,
})
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryAggregate;
expect(data).to.be.a('array');
if (data.length) {
expect(data[0].min).to.be.a('number');
expect(data[0].max).to.be.a('number');
expect(data[0].avg).to.be.a('number');
expect(data[0].sum).to.be.a('number');
expect(data[0].count)
.to.be.a('number')
.and.satisfy(
(num) => num === parseInt(num),
'count should be an integer'
);
expect(Object.keys(data[0]).length).to.be.equal(5);
}
done();
});
});
it('countryDistribution', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryDistribution(column_name : "country_id") { range count } } `,
})
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryDistribution;
expect(data).to.be.a('array');
expect(data[0].count).to.be.a('number');
expect(data[0].count).satisfies(
(num) => num === parseInt(num) && num >= 0,
'should be a positive integer'
);
expect(data[0].range).to.be.a('string');
expect(data[0].range).to.be.match(
/^\d+-\d+$/,
'should match {num start}-{num end} format'
);
done();
});
});
}
/**** Query : END ****/
/**** Mutation : START ****/
describe('Mutation', function () {
const COUNTRY_ID = 9999;
// const COUNTRY_CREATE_ID = 9998;
// const COUNTRY_NAME = 'test-name';
before(function (done) {
// create table entry for update and delete
// let db = knex(config.envs.dev.db[0])('country');
// db.insert({
// country_id: COUNTRY_ID,
// country: COUNTRY_NAME
// }).finally(() => done())
done();
});
after(function (done) {
// delete table entries which is created for the test
// let db = knex(config.envs.dev.db[0])('country');
// db.whereIn('country_id', [COUNTRY_ID, COUNTRY_CREATE_ID])
// .del()
// .finally(() => done())
done();
});
it('countryCreate', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `mutation{ countryCreate( data : { country: "abcd" ${
dbConfig.client === 'sqlite3' ? ' country_id : 999 ' : ''
} }) { country_id country } } `,
})
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryCreate;
expect(data).to.be.a('object');
expect(data.country_id).to.be.a('number');
expect(data.country).to.be.equal('abcd');
done();
});
});
it('countryUpdate', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `mutation{ countryUpdate( id : "${COUNTRY_ID}", data : { country: "abcd" }){ country } } `,
})
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryUpdate;
expect(data).to.be.a('object');
// todo:
done();
});
});
it('countryDelete', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `mutation{ countryDelete( id : "${COUNTRY_ID}") } `,
})
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryDelete;
expect(data).to.be.a('number');
// todo:
done();
});
});
});
/**** Mutation : END ****/
// countryCreateBulk(data: [countryInput]): [Int]
// countryUpdateBulk(data: [countryInput]): [Int]
// countryDeleteBulk(data: [countryInput]): [Int]
// },
});
/**** country : END ****/
});
});

513
packages/nocodb/src/__tests__/meta.apisv2.test.ts

@ -1,513 +0,0 @@
// import chai from 'chai';
// import chaiAsPromised from 'chai-as-promised';
// const expect = chai.expect;
//
// chai.use(chaiAsPromised);
// import 'mocha';
// import NcConfigFactory from '../lib/utils/NcConfigFactory';
// import express from 'express';
// import Noco from '../lib';
// import UITypes from '../lib/sqlUi/UITypes';
// import { Api } from 'nc-common';
//
// const knex = require('knex');
//
// process.env.NODE_ENV = 'test';
// process.env.TEST = 'test';
// const dbName = `test_meta`;
// process.env[`DATABASE_URL`] = `mysql2://root:password@localhost:3306/${dbName}`;
// // process.env[`DATABASE_URL`] = `pg://postgres:password@localhost:5432/${dbName}`;
// // process.env[
// // `DATABASE_URL`
// // ] = `mssql://sa:Password123.@localhost:1433/${dbName}`;
//
// const dbConfig = NcConfigFactory.urlToDbConfig(
// NcConfigFactory.extractXcUrlFromJdbc(
// // 'sqlite:////Users/pranavc/xgene/nc/packages/nocodb/tests/sqlite-dump/sakila.db')
// process.env[`DATABASE_URL`]
// )
// );
//
// describe('Noco v2 Tests', function() {
// const api = new Api({
// baseURL: 'http://localhost:8080'
// });
//
// // Called once before any of the tests in this block begin.
// before(async function() {
// this.timeout(200000);
// try {
// await knex(dbConfig).raw(`DROP DATABASE test_db_12345`);
// } catch {}
// try {
// await knex(dbConfig).raw(`DROP DATABASE test_meta`);
// } catch {}
//
// const server = express();
// server.use(await Noco.init());
// server.listen('8080');
// });
//
// after(done => {
// done();
// process.exit();
// });
//
// describe('Meta API Tests', function() {
// this.timeout(10000);
//
// it('Project create - existing external DB', async function() {
// this.timeout(120000);
//
// const { data: project } = await api.meta.projectCreate({
// title: 'test',
// bases: [
// {
// type: 'mysql2',
// host: 'localhost',
// port: 3306,
// username: 'root',
// password: 'password',
// database: 'sakila'
// }
// ]
// });
//
// const {
// data: {
// tables: { list: tablesList }
// }
// } = await api.meta.tableList({
// projectId: project.id,
// baseId: project.bases[0].id
// });
// const filmTableId = tablesList.find(t => t.tn === 'film')?.id;
// const countryTableId = tablesList.find(t => t.tn === 'country')?.id;
//
// const { data: filmData } = await api.data.list(filmTableId);
//
// expect(filmData).length.gt(0);
//
// const { data: countryData } = await api.data.list(countryTableId);
//
// expect(countryData).length.gt(0);
// });
//
// it('Project create & table create - v2', async function() {
// this.timeout(120000);
//
// const projectRes = await api.meta.projectCreate({
// title: 'test',
// bases: [
// {
// type: 'mysql2',
// host: 'localhost',
// port: 3306,
// username: 'root',
// password: 'password',
// database: 'test_db_12345'
// }
// ]
// });
//
// // const projectId = projectRes.data.id;
// // const baseId = projectRes.data.bases[0].id;
//
// const tableRes = await api.meta.tableCreate(
// projectRes.data.id,
// projectRes.data.bases[0].id,
// {
// tn: 'abc',
// _tn: 'Abc',
// columns: [
// {
// column_name:'id',
// _cn: 'Id',
// dt: 'int',
// dtx: 'integer',
// ct: 'int(11)',
// nrqd: false,
// rqd: true,
// ck: false,
// pk: true,
// un: false,
// ai: true,
// cdf: null,
// clen: null,
// np: null,
// ns: 0,
// dtxp: '',
// dtxs: '',
// altered: 1,
// uidt: 'ID',
// uip: '',
// uicn: ''
// },
// {
// column_name:'title',
// _cn: 'Title',
// dt: 'varchar',
// dtx: 'specificType',
// ct: 'varchar(45)',
// nrqd: true,
// rqd: false,
// ck: false,
// pk: false,
// un: false,
// ai: false,
// cdf: null,
// clen: 45,
// np: null,
// ns: null,
// dtxp: '45',
// dtxs: '',
// altered: 1,
// uidt: 'SingleLineText',
// uip: '',
// uicn: ''
// }
// ]
// }
// );
//
// console.log(projectRes.data, tableRes.data);
//
// const tableId = tableRes.data.id;
//
// const data = await api.data.list(tableId);
// console.log(data.data);
// expect(data.data).to.have.length(0);
//
// const createData = await api.data.create(tableId, {
// Title: 'test'
// });
//
// console.log(createData.data);
// const listData = await api.data.list(tableId);
// expect(listData.data).to.have.length(1);
//
// const readData = await api.data.read(tableId, createData.data.Id);
//
// console.log(readData.data);
//
// await api.data.update(tableId, createData.data.Id, {
// Title: 'new val'
// });
//
// const updatedData = await api.data.read(tableId, createData.data.Id);
//
// console.log(updatedData.data);
//
// expect(updatedData.data);
//
// await api.data.delete(tableId, createData.data.Id);
//
// const listData1 = await api.data.list(tableId);
// expect(listData1.data).to.have.length(0);
// const tableDelRes = await api.meta.tableDelete(tableId);
// await expect(
// api.data.list(tableId)
// // @ts-ignore
// ).to.be.rejectedWith(Error);
//
// console.log(tableDelRes.data);
// });
//
// it('Table update - column add', async function() {
// this.timeout(120000);
//
// const projectRes = await api.meta.projectCreate({
// title: 'test',
// bases: [
// {
// type: 'mysql2',
// host: 'localhost',
// port: 3306,
// username: 'root',
// password: 'password',
// database: 'test_db_12345'
// }
// ]
// });
//
// const projectId = projectRes.data.id;
// const baseId = projectRes.data.bases[0].id;
//
// const { data: table } = await api.meta.tableCreate(projectId, baseId, {
// tn: 'abc',
// _tn: 'Abc',
// columns: [
// {
// column_name:'id',
// _cn: 'Id',
// dt: 'int',
// dtx: 'integer',
// ct: 'int(11)',
// nrqd: false,
// rqd: true,
// ck: false,
// pk: true,
// un: false,
// ai: true,
// cdf: null,
// clen: null,
// np: null,
// ns: 0,
// dtxp: '',
// dtxs: '',
// altered: 1,
// uidt: 'ID',
// uip: '',
// uicn: ''
// }
// ]
// });
//
// const { data: tableMeta }: any = await api.meta.columnCreate(table.id, {
// column_name:'title1',
// _cn: 'Title1',
// dt: 'varchar',
// dtxp: '45',
// uidt: UITypes.SingleLineText
// });
//
// await api.data.create(tableMeta.id, {
// Title1: 'test'
// });
// await api.data.create(tableMeta.id, {
// Title1: 'test1'
// });
//
// console.log(tableMeta);
//
// const { data: tableFormulaMeta }: any = await api.meta.columnCreate(
// table.id,
// {
// _cn: 'formula',
// uidt: UITypes.Formula,
// formula: 'Id + 1'
// } as any
// );
//
// console.log(tableFormulaMeta);
//
// const { data: listData } = await api.data.list(tableMeta.id);
//
// console.log(listData);
//
// const { data: tableMetaAfterUpdate } = await api.meta.columnUpdate(
// table.id,
// tableMeta.columns.find(c => c.cn === 'title1')?.id,
// {
// column_name:'title1',
// _cn: 'Title1',
// dt: 'text',
// dtxp: '',
// uidt: UITypes.LongText
// }
// );
//
// console.log(tableMetaAfterUpdate);
//
// // delete column
// const { data: tableMetaAfterDel } = await api.meta.columnDelete(
// table.id,
// tableMeta.columns.find(c => c.cn === 'title1')?.id
// );
//
// console.log(tableMetaAfterDel);
// });
// });
//
// it('Table relation create', async function() {
// this.timeout(120000);
//
// const projectRes = await api.meta.projectCreate({
// title: 'test',
// bases: [
// {
// type: 'mysql2',
// host: 'localhost',
// port: 3306,
// username: 'root',
// password: 'password',
// database: 'test_db_12345'
// }
// ]
// });
//
// const projectId = projectRes.data.id;
// const baseId = projectRes.data.bases[0].id;
//
// const { data: table1 } = await api.meta.tableCreate(projectId, baseId, {
// tn: 'abc',
// _tn: 'Abc',
// columns: [
// {
// column_name:'id',
// _cn: 'Id',
// dt: 'int',
// dtx: 'integer',
// ct: 'int(11)',
// nrqd: false,
// rqd: true,
// ck: false,
// pk: true,
// un: false,
// ai: true,
// cdf: null,
// clen: null,
// np: null,
// ns: 0,
// dtxp: '',
// dtxs: '',
// altered: 1,
// uidt: 'ID',
// uip: '',
// uicn: ''
// }
// ]
// });
// const { data: table2 } = await api.meta.tableCreate(projectId, baseId, {
// tn: 'def',
// _tn: 'Def',
// columns: [
// {
// column_name:'id',
// _cn: 'Id',
// dt: 'int',
// dtx: 'integer',
// ct: 'int(11)',
// nrqd: false,
// rqd: true,
// ck: false,
// pk: true,
// un: false,
// ai: true,
// cdf: null,
// clen: null,
// np: null,
// ns: 0,
// dtxp: '',
// dtxs: '',
// altered: 1,
// uidt: 'ID',
// uip: '',
// uicn: ''
// }
// ]
// });
//
// const { data: res } = await api.meta.columnCreate(table1.id, {
// uidt: UITypes.LinkToAnotherRecord,
// parentId: table1.id,
// childId: table2.id,
// type: 'hm',
// _cn: 'test'
// } as any);
// console.log(res);
// });
//
// it('Table relation(mm) create', async function() {
// this.timeout(120000);
//
// const projectRes = await api.meta.projectCreate({
// title: 'test',
// bases: [
// {
// type: 'mysql2',
// host: 'localhost',
// port: 3306,
// username: 'root',
// password: 'password',
// database: 'test_db_12345'
// }
// ]
// });
//
// const projectId = projectRes.data.id;
// const baseId = projectRes.data.bases[0].id;
//
// const { data: table1 } = await api.meta.tableCreate(projectId, baseId, {
// tn: 'abc',
// _tn: 'Abc',
// columns: [
// {
// column_name:'id',
// _cn: 'Id',
// dt: 'int',
// dtx: 'integer',
// ct: 'int(11)',
// nrqd: false,
// rqd: true,
// ck: false,
// pk: true,
// un: false,
// ai: true,
// cdf: null,
// clen: null,
// np: null,
// ns: 0,
// dtxp: '',
// dtxs: '',
// altered: 1,
// uidt: 'ID',
// uip: '',
// uicn: ''
// }
// ]
// });
// const { data: table2 } = await api.meta.tableCreate(projectId, baseId, {
// tn: 'def',
// _tn: 'Def',
// columns: [
// {
// column_name:'id',
// _cn: 'Id',
// dt: 'int',
// dtx: 'integer',
// ct: 'int(11)',
// nrqd: false,
// rqd: true,
// ck: false,
// pk: true,
// un: false,
// ai: true,
// cdf: null,
// clen: null,
// np: null,
// ns: 0,
// dtxp: '',
// dtxs: '',
// altered: 1,
// uidt: 'ID',
// uip: '',
// uicn: ''
// }
// ]
// });
//
// const { data: res } = await api.meta.columnCreate(table1.id, {
// uidt: UITypes.LinkToAnotherRecord,
// parentId: table1.id,
// childId: table2.id,
// type: 'mm',
// _cn: 'test'
// } as any);
//
// console.log(res);
//
// await api.data.create(table1.id, {
// Title1: 'test1'
// });
// await api.data.create(table1.id, {
// Title1: 'test2'
// });
// await api.data.create(table2.id, {
// Title1: 'test3'
// });
//
// const { data } = await api.data.list(table1.id);
// console.log(data);
// });
// });

107
packages/nocodb/src/__tests__/noco/NcConfigFactory.test.ts

@ -1,107 +0,0 @@
import { expect } from 'chai';
import 'mocha';
import { NcConfigFactory } from '../../lib';
describe('Config Factory Tests', () => {
const storedDbConfig = {
client: 'pg',
connection: {
database: 'abcde',
user: 'postgres',
password: 'xgene',
host: 'localhost',
port: 5432,
},
ssl: {
rejectUnauthorized: false,
},
pool: {
min: 1,
max: 2,
},
acquireConnectionTimeout: 600000,
};
before(function (done) {
done();
});
after((done) => {
done();
});
it('Generate config from string', function (done) {
const dbConfig = NcConfigFactory.metaUrlToDbConfig(
`pg://localhost:5432?u=postgres&p=xgene&d=abcde`
);
const { pool, ssl, ...rest } = storedDbConfig;
expect(dbConfig).to.deep.equal(rest);
done();
});
it('Generate config from DATABASE_URL', function (done) {
// postgres url
const ncDbUrl = NcConfigFactory.extractXcUrlFromJdbc(
'postgres://username:password@host:5432/db'
);
expect(ncDbUrl).to.be.equal('pg://host:5432?u=username&p=password&d=db&');
// postgres url without port
const ncDbUrl1 = NcConfigFactory.extractXcUrlFromJdbc(
'postgres://username:password@host/db'
);
expect(ncDbUrl1).to.be.equal('pg://host:5432?u=username&p=password&d=db&');
// mysql url
const ncDbUrl2 = NcConfigFactory.extractXcUrlFromJdbc(
'jdbc:mysql://localhost/sample_db'
);
expect(ncDbUrl2).to.be.equal('mysql2://localhost:3306?d=sample_db&');
// mariadb url
const ncDbUrl3 = NcConfigFactory.extractXcUrlFromJdbc(
'jdbc:mariadb://localhost/sample_db'
);
expect(ncDbUrl3).to.be.equal('mysql2://localhost:3306?d=sample_db&');
done();
});
it('Connection string with nested property', function (done) {
const dbConfig = NcConfigFactory.metaUrlToDbConfig(
`pg://localhost:5432?u=postgres&p=xgene&d=abcde&pool.min=1&pool.max=2&ssl.rejectUnauthorized=false`
);
expect(dbConfig).to.deep.equal(storedDbConfig);
done();
});
it('Allow creating config from JSON string', function (done) {
try {
process.env.NC_DB_JSON = JSON.stringify(storedDbConfig);
const {
meta: { db: dbConfig },
} = NcConfigFactory.make();
expect(dbConfig).to.deep.equal(storedDbConfig);
done();
} finally {
delete process.env.NC_DB_JSON;
}
});
it('Allow creating config from JSON file', function (done) {
try {
process.env.NC_DB_JSON_FILE = `${__dirname}/dbConfig.json`;
const {
meta: { db: dbConfig },
} = NcConfigFactory.make();
expect(dbConfig).to.deep.equal(storedDbConfig);
done();
} finally {
delete process.env.NC_DB_JSON_FILE;
}
});
});

18
packages/nocodb/src/__tests__/noco/dbConfig.json

@ -1,18 +0,0 @@
{
"client": "pg",
"connection": {
"user": "postgres",
"password": "xgene",
"database": "abcde",
"host": "localhost",
"port": 5432
},
"ssl": {
"rejectUnauthorized": false
},
"pool": {
"min": 1,
"max": 2
},
"acquireConnectionTimeout": 600000
}

921
packages/nocodb/src/__tests__/rest.test.ts

@ -1,921 +0,0 @@
import { expect } from 'chai';
import 'mocha';
import express from 'express';
import request from 'supertest';
import { Noco } from '../lib';
import NcConfigFactory from '../lib/utils/NcConfigFactory';
process.env.TEST = 'test';
let projectId;
let token;
const dbConfig = NcConfigFactory.urlToDbConfig(
NcConfigFactory.extractXcUrlFromJdbc(process.env[`DATABASE_URL`])
);
const projectCreateReqBody = {
api: 'projectCreateByWeb',
query: { skipProjectHasDb: 1 },
args: {
project: { title: 'sebulba', folder: 'config.xc.json', type: 'pg' },
projectJson: {
title: 'sebulba',
version: '0.6',
envs: {
_noco: {
db: [
dbConfig,
// {
// "client": "mysql2",
// "connection": {
// "host": "localhost",
// "port": "3306",
// "user": "root",
// "password": "password",
// "database": "sakila",
// "multipleStatements": true
// },
// "meta": {
// "tn": "nc_evolutions",
// "dbAlias": "db",
// "api": {"type": "rest", "prefix": "", "graphqlDepthLimit": 10},
// "inflection": {"tn": "none", "cn": "none"}
// }
// }
],
apiClient: { data: [] },
},
},
workingEnv: '_noco',
meta: {
version: '0.6',
seedsFolder: 'seeds',
queriesFolder: 'queries',
apisFolder: 'apis',
projectType: 'rest',
type: 'mvc',
language: 'ts',
db: { client: 'sqlite3', connection: { filename: 'noco.db' } },
},
seedsFolder: 'seeds',
queriesFolder: 'queries',
apisFolder: 'apis',
projectType: 'rest',
type: 'docker',
language: 'ts',
apiClient: { data: [] },
auth: {
jwt: { secret: 'b8ed266d-4475-4028-8c3d-590f58bee867', dbAlias: 'db' },
},
},
},
};
// console.log(JSON.stringify(dbConfig, null, 2));
// process.exit();
describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
let app;
// Called once before any of the tests in this block begin.
before(function (done) {
this.timeout(200000);
(async () => {
const server = express();
server.enable('trust proxy');
server.use(await Noco.init());
app = server;
// await knex(config.envs[process.env.NODE_ENV || 'dev'].db[0])('xc_users').del();
})()
.then(done)
.catch((e) => {
done(e);
});
});
after((done) => {
done();
// process.exit();
});
/**************** START : Auth ****************/
describe('Authentication', function () {
this.timeout(10000);
const EMAIL_ID = 'abc@g.com';
const VALID_PASSWORD = '1234566778';
it('Signup with valid email', function (done) {
this.timeout(60000);
request(app)
.post('/auth/signup')
.send({ email: EMAIL_ID, password: VALID_PASSWORD })
.expect(200, (err, res) => {
if (err) {
expect(res.status).to.equal(400);
} else {
const token = res.body.token;
expect(token).to.be.a('string');
}
done();
});
});
it('Signup with invalid email', (done) => {
request(app)
.post('/auth/signup')
.send({ email: 'test', password: VALID_PASSWORD })
.expect(400, done);
});
it('Signin with valid credentials', function (done) {
request(app)
.post('/auth/signin')
.send({ email: EMAIL_ID, password: VALID_PASSWORD })
.expect(200, async function (err, res) {
if (err) {
return done(err);
}
token = res.body.token;
expect(token).to.be.a('string');
// todo: verify jwt token payload
// const payload: any = await JWT.verifyToken(token, config.auth.jwt.secret, config.auth.jwt.options)
// expect(payload.email).to.eq(EMAIL_ID)
// expect(payload.roles).to.eq('owner,creator,editor')
done();
});
});
it('me', function (done) {
request(app)
.get('/user/me')
.set('xc-auth', token)
.expect(200, function (err, res) {
if (err) {
return done(err);
}
const email = res.body.email;
expect(email).to.equal(EMAIL_ID);
done();
});
});
it('Change password', function (done) {
request(app)
.post('/user/password/change')
.set('xc-auth', token)
.send({ currentPassword: 'password', newPassword: 'password' })
.expect(400, done);
});
it('Change password - after logout', function (done) {
// todo:
request(app)
.post('/user/password/change')
.send({ currentPassword: 'password', newPassword: 'password' })
.expect(500, function (_err, _res) {
done();
});
});
it('Signin with invalid credentials', function (done) {
request(app)
.post('/auth/signin')
.send({ email: 'abc@abc.com', password: VALID_PASSWORD })
.expect(400, done);
});
it('Signin with invalid password', function (done) {
request(app)
.post('/auth/signin')
.send({ email: EMAIL_ID, password: 'wrongPassword' })
.expect(400, done);
});
it('Signup without email and password', (done) => {
request(app)
.post('/auth/signin')
// pass empty data in request
.send({})
.expect(400, done);
});
it('Forgot password with a non-existing email id', function (done) {
request(app)
.post('/auth/password/forgot')
.send({ email: 'abc@abc.com' })
.expect(200, done);
});
it('Forgot password with an existing email id', function (done) {
this.timeout(10000);
request(app)
.post('/auth/password/forgot')
.send({ email: EMAIL_ID })
.expect(200, done);
});
it('Email validate with an invalid token', function (done) {
request(app)
.post('/auth/email/validate/someRandomValue')
.send({ email: EMAIL_ID })
.expect(400, done);
});
it('Email validate with a valid token', function (done) {
console.log('eeee');
// todo :
done();
// request(app)
// .post('/auth/email/validate/someRandomValue')
// .send({email: EMAIL_ID})
// .expect(500, done);
});
it('Forgot password validate with an invalid token', function (done) {
request(app)
.post('/auth/token/validate/someRandomValue')
.send({ email: EMAIL_ID })
.expect(400, done);
});
it('Forgot password validate with a valid token', function (done) {
// todo
done();
// request(app)
// .post('/auth/token/validate/someRandomValue')
// .send({email: EMAIL_ID})
// .expect(500, done);
});
it('Reset Password with an invalid token', function (done) {
request(app)
.post('/auth/password/reset/someRandomValue')
.send({ password: 'anewpassword' })
.expect(400, done);
});
it('Reset Password with an valid token', function (done) {
//todo
done();
// request(app)
// .post('/auth/password/reset/someRandomValue')
// .send({password: 'anewpassword'})
// .expect(500, done);
});
});
describe('Project', function () {
const EMAIL_ID = 'abc@g.com';
const VALID_PASSWORD = '1234566778';
before(function (done) {
this.timeout(120000);
request(app)
.post('/auth/signin')
.send({ email: EMAIL_ID, password: VALID_PASSWORD })
.expect(200, async function (_err, res) {
token = res.body.token;
request(app)
.post('/dashboard')
.set('xc-auth', token)
.send(projectCreateReqBody)
.expect(200, (err, res) => {
if (err) {
return done(err);
}
projectId = res.body.id;
done();
});
});
});
/**************** START : CRUD ****************/
describe('CRUD', function () {
let COUNTRY_ID_RET;
const COUNTRY_ID = 9999;
const COUNTRY_NAME = 'IN';
this.timeout(5000);
it('list + limit : GET - /api/v1/country?limit=6', function (done) {
console.log(`/nc/${projectId}/api/v1/country?limit=6`);
request(app)
.get(`/nc/${projectId}/api/v1/country?limit=6`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body.length).to.be.lessThan(7);
done();
});
});
it('list + where : GET - /api/v1/country?where=(country,like,b%)', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country?where=(country,like,b%)`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
if (res.body.length)
expect(res.body[0].country.toLowerCase())
.to.be.a('string')
.and.satisfy((msg) => {
return msg.startsWith('b');
}, 'Should start with "b"');
done();
});
});
it('list + sort : GET - /api/v1/country?sort=-country_id', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country?sort=-country_id`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
expect(res.body).satisfy((array) => {
let i = array.length;
while (--i) {
if (array[i].country_id > array[i - 1].country_id) return false;
}
return true;
}, 'Should be in descending order');
done();
});
});
it('list + fields : GET - /api/v1/country?fields=country,country_id', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country?fields=country,country_id`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
expect(Object.keys(res.body[0]).length).to.be.equal(3);
expect(res.body[0]).to.have.all.keys(
'country_id',
'country',
'cityList'
);
done();
});
});
it('list + offset : GET - /api/v1/country?offset=0', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country?offset=0&limit=6`)
.set('xc-auth', token)
.expect(200, (err, res1) => {
if (err) done(err);
request(app)
.get(`/nc/${projectId}/api/v1/country?offset=1&limit=5`)
.set('xc-auth', token)
.expect(200, (err, res2) => {
if (err) done(err);
expect(res2.body).satisfy(
(arr) =>
arr.every(
({ country, country_id }, i) =>
country === res1.body[i + 1].country &&
country_id === res1.body[i + 1].country_id
),
'Both data should need to be equal where offset vary with 1'
);
done();
});
});
});
describe('CRUD', function () {
it('create - POST - /api/v1/country', function (done) {
request(app)
.delete(`/nc/${projectId}/api/v1/country/` + COUNTRY_ID)
.set('xc-auth', token)
.set('xc-auth', token)
.expect(200, (_err, _res) => {
request(app)
.post(`/nc/${projectId}/api/v1/country`)
.set('xc-auth', token)
.set('xc-auth', token)
.send({
country: COUNTRY_NAME,
...(dbConfig.client === 'mssql'
? {}
: { country_id: COUNTRY_ID }),
})
.expect(200, (err, res) => {
if (err) done(err);
COUNTRY_ID_RET = res.body.country_id;
expect(res.body).to.be.a('object');
expect(res.body.country).to.be.equal(COUNTRY_NAME);
done();
});
});
});
it('read - GET - /api/v1/country/:id', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country/1`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
// expect(res.body).to.be.a('array');
expect(res.body).to.be.a('object');
expect(res.body.country).to.be.equal('Afghanistan');
done();
});
});
it('update - PUT - /api/v1/country/:id', function (done) {
request(app)
.put(
`/nc/${projectId}/api/v1/country/` +
(dbConfig.client === 'mssql' ? COUNTRY_ID_RET : COUNTRY_ID)
)
.set('xc-auth', token)
.set('xc-auth', token)
.send({ country: COUNTRY_NAME + 'a' })
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('object');
request(app)
.get(
`/nc/${projectId}/api/v1/country/` +
(dbConfig.client === 'mssql' ? COUNTRY_ID_RET : COUNTRY_ID)
)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('object');
expect(res.body.country).to.be.equal(COUNTRY_NAME + 'a');
done();
});
});
});
it('exists - GET - /api/v1/country/:id/exists', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country/1/exists`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.true;
done();
});
});
it('findOne - GET - /api/v1/country/findOne', function (done) {
request(app)
.get(
`/nc/${projectId}/api/v1/country/findOne?where=(country,eq,${
COUNTRY_NAME + 'a'
})`
)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('object');
expect(res.body.country).to.be.equal(COUNTRY_NAME + 'a');
done();
});
});
it('delete - DELETE - /api/v1/country/:id', function (done) {
request(app)
.delete(
`/nc/${projectId}/api/v1/country/` +
(dbConfig.client === 'mssql' ? COUNTRY_ID_RET : COUNTRY_ID)
)
.set('xc-auth', token)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.equal(1);
request(app)
.get(
`/nc/${projectId}/api/v1/country/` +
(dbConfig.client === 'mssql' ? COUNTRY_ID_RET : COUNTRY_ID)
)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('object');
expect(Object.keys(res.body)).to.have.length(0);
done();
});
});
});
});
if (dbConfig.client !== 'mssql') {
it('groupBy - GET - /api/v1/country/groupby/:cn', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country/groupby/country?limit=5`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
if (res.body.length) {
expect(res.body.length).to.be.most(5);
expect(+res.body[0].count).to.be.greaterThan(0);
expect(res.body[0].country).to.be.a('string');
expect(Object.keys(res.body[0]).length).to.be.equal(2);
}
done();
});
});
it('groupBy multiple - GET - /api/v1/country/groupby/:cn', function (done) {
request(app)
.get(
`/nc/${projectId}/api/v1/country/groupby/country?fields=country_id&limit=5`
)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
expect(res.body.length).to.be.most(5);
if (res.body.length) {
expect(+res.body[0].count).to.be.greaterThan(0);
expect(res.body[0].country).to.be.a('string');
expect(+res.body[0].country_id).to.be.a('number');
expect(Object.keys(res.body[0]).length).to.be.equal(3);
}
done();
});
});
// todo: change distribute => distribution
it('distribution - GET - /api/v1/country/distribute', function (done) {
request(app)
.get(
`/nc/${projectId}/api/v1/country/distribute?column_name=country_id&steps=1,34,50`
)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
expect(+res.body[0].count).to.be.a('number');
expect(+res.body[0].count).satisfies(
(num) => num === parseInt(num) && num >= 0,
'should be a positive integer'
);
expect(res.body[0].range).to.be.a('string');
expect(res.body[0].range).to.be.match(
/^\d+-\d+$/,
'should match {num start}-{num end} format'
);
done();
});
});
it('distinct - GET - /api/v1/country/distinct', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country/distinct?cn=country&limit=5`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
if (res.body.length) {
expect(res.body[0].country).to.be.a('string');
expect(Object.keys(res.body[0]).length).to.be.equal(1);
}
expect(res.body.length).to.be.most(5);
done();
});
});
it('distinct multiple - GET - /api/v1/country/distinct/:cn', function (done) {
request(app)
.get(
`/nc/${projectId}/api/v1/country/distinct?cn=country&fields=country_id&limit=5`
)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
if (res.body.length) {
expect(res.body[0].country).to.be.a('string');
expect(Object.keys(res.body[0]).length).to.be.equal(2);
}
expect(res.body.length).to.be.most(5);
done();
});
});
it('aggregate - GET - /api/v1/country/aggregate', function (done) {
request(app)
.get(
`/nc/${projectId}/api/v1/country/aggregate?column_name=country_id&func=sum,avg,min,max,count`
)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
if (res.body.length) {
expect(+res.body[0].min).to.be.a('number');
expect(+res.body[0].max).to.be.a('number');
expect(+res.body[0].avg).to.be.satisfy(
(num) => !isNaN(parseInt(num)),
'count should be an number'
);
expect(+res.body[0].sum).to.be.satisfy(
(num) => !isNaN(parseInt(num)),
'count should be an number'
);
expect(+res.body[0].count)
.to.be.a('number')
.and.satisfy(
(num) => num === parseInt(num),
'count should be an integer'
);
// expect(Object.keys(res.body[0]).length).to.be.equal(7);
}
expect(res.body.length).to.be.most(20);
done();
});
});
it('count - GET - /api/v1/country/count', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country/count`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('object');
expect(+res.body.count)
.to.be.a('number')
.and.satisfy(
(num) => num === parseInt(num),
'count should be an integer'
);
done();
});
});
if (dbConfig.client !== 'sqlite3') {
it('bulk insert - POST - /api/v1/country/bulk', function (done) {
request(app)
.post(`/nc/${projectId}/api/v1/country/bulk`)
.set('xc-auth', token)
.send([
{ country: 'a' },
{ country: 'b' },
{ country: 'c' },
{ country: 'd' },
{ country: 'e' },
])
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
expect(res.body[0]).to.be.a('number');
request(app)
.get(`/nc/${projectId}/api/v1/country/${res.body.pop()}`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
// expect(res.body).to.be.a('array');
expect(res.body).to.be.a('object');
// in mysql it will be a and in pg : e
expect(
['a', 'e'].indexOf(res.body.country)
).to.be.greaterThan(-1);
done();
});
});
});
it('bulk update - PUT - /api/v1/country/bulk', function (done) {
// get last inserted 5 entry by sorting db data in reverse order based on id
request(app)
.get(`/nc/${projectId}/api/v1/country?sort=-country_id&limit=5`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
expect(res.body[0]).to.be.a('object');
expect(res.body[0].country).to.be.a('string');
request(app)
.put(`/nc/${projectId}/api/v1/country/bulk`)
.set('xc-auth', token)
.send(
res.body.map(({ country, country_id }) => ({
country_id,
country: country + 1,
}))
)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
expect(res.body[0]).to.be.a('number');
expect(res.body[0]).to.be.equal(1);
expect(res.body.length).to.be.equal(5);
done();
});
});
});
it('bulk delete - DELETE - /api/v1/country/bulk', function (done) {
// get last inserted 5 entry by sorting db data in reverse order based on id
request(app)
.get(`/nc/${projectId}/api/v1/country?sort=-country_id&limit=5`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
expect(res.body[0]).to.be.a('object');
expect(res.body[0].country).to.be.a('string');
request(app)
.delete(`/nc/${projectId}/api/v1/country/bulk`)
.set('xc-auth', token)
.send(res.body.map(({ country_id }) => ({ country_id })))
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
expect(res.body[0]).to.be.a('number');
expect(res.body[0]).to.be.equal(1);
expect(res.body.length).to.be.equal(5);
done();
});
});
});
}
}
});
/**************** END : CRUD ****************/
if (dbConfig.client !== 'mssql' && dbConfig.client !== 'sqlite3') {
/**************** START : hasMany ****************/
describe('Country HasMany City Api', function () {
const CITY_NAME = 'testCity',
CITY_ID = '9999';
it('has city - GET - /api/v1/country/has/city(:childs)?', function (done) {
// get last inserted 5 entry by sorting db data in reverse order based on id
request(app)
.get(`/nc/${projectId}/api/v1/country/has/city`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
expect(res.body[0]).to.be.a('object');
expect(res.body[0].country).to.be.a('string');
expect(res.body[0].cityList).to.be.a('array');
expect(res.body[0].cityList[0]).to.be.a('object');
expect(res.body[0].cityList[0].city).to.be.a('string');
done();
});
});
it('cities under a single parent - GET - /api/v1/country/:parentId/city', function (done) {
// get last inserted 5 entry by sorting db data in reverse order based on id
request(app)
.get(`/nc/${projectId}/api/v1/country/1/city?limit=5`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
expect(res.body[0]).to.be.a('object');
expect(res.body[0].city).to.be.a('string');
expect(res.body.length).to.be.most(5);
done();
});
});
it('create - POST - /api/v1/country/:parentId/city/:id', function (done) {
request(app)
.delete(`/nc/${projectId}/api/v1/country/1/city/${CITY_ID}`)
.set('xc-auth', token)
.set('xc-auth', token)
.expect(200, (_err, _res) => {
request(app)
.post(`/nc/${projectId}/api/v1/country/1/city`)
.set('xc-auth', token)
.send({ city: CITY_NAME, city_id: CITY_ID })
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('object');
expect(res.body.city).to.be.equal(CITY_NAME);
expect(res.body.country_id + '').to.be.equal('1');
done();
});
});
});
it('get city by id - GET - /api/v1/country/:parentId/city/:id', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country/1/city/${CITY_ID}`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
expect(res.body[0].city).to.be.equal(CITY_NAME);
expect(res.body[0].country_id).to.be.equal(1);
done();
});
});
it('get count - GET - /api/v1/country/:parentId/city/count', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country/1/city/count`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('object');
expect(+res.body.count).to.be.a('number');
done();
});
});
it('update - PUT - /api/v1/country/:parentId/city/:id', function (done) {
request(app)
.put(`/nc/${projectId}/api/v1/country/1/city/${CITY_ID}`)
.set('xc-auth', token)
.send({ city: CITY_NAME + 'a' })
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.equal(1);
request(app)
.get(`/nc/${projectId}/api/v1/country/1/city/${CITY_ID}`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
expect(res.body[0].city).to.be.equal(CITY_NAME + 'a');
expect(res.body[0].country_id).to.be.equal(1);
done();
});
});
});
it('findOne city - GET - /api/v1/country/:parentId/city/findOne', function (done) {
request(app)
.get(
`/nc/${projectId}/api/v1/country/1/city/findOne?where=(city,eq,${
CITY_NAME + 'a'
})`
)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('object');
expect(res.body.city).to.be.equal(CITY_NAME + 'a');
expect(res.body.country_id + '').to.be.equal('1');
done();
});
});
it('exists city - GET - /api/v1/country/1/city/${CITY_ID}/exists', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country/1/city/${CITY_ID}/exists`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.true;
done();
});
});
it('delete - DELETE - /api/v1/country/:parentId/city', function (done) {
this.timeout(10000);
request(app)
.delete(`/nc/${projectId}/api/v1/country/1/city/${CITY_ID}`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.equal(1);
done();
});
});
});
/**************** END : hasMany ****************/
/**************** START : belongsTo ****************/
describe('City BelngsTo Country Api', function () {
it('city belongs to country - GET - /api/v1/city/belongs/country', function (done) {
// get last inserted 5 entry by sorting db data in reverse order based on id
request(app)
.get(`/nc/${projectId}/api/v1/city/belongs/country?limit=10`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
expect(res.body[0]).to.be.a('object');
expect(res.body[0].city).to.be.a('string');
expect(res.body[0].countryRead).to.be.a('object');
expect(res.body.length).to.be.most(10);
done();
});
});
});
/**************** END : belongsTo ****************/
}
});
});

1539
packages/nocodb/src/__tests__/restv2.test.ts

File diff suppressed because it is too large Load Diff

707
packages/nocodb/src/__tests__/template.ts

@ -1,707 +0,0 @@
export default {
name: 'Project name',
tables: [
{
tn: 'blog',
columns: [
{
cn: 'title',
uidt: 'SingleLineText',
},
{
cn: 'body',
uidt: 'LongText',
},
],
hasMany: [
{
tn: 'comment',
},
],
manyToMany: [
{
rtn: 'tag',
},
],
},
{
tn: 'comment',
columns: [
{
cn: 'body',
uidt: 'LongText',
},
],
},
{
tn: 'tag',
columns: [
{
cn: 'title',
uidt: 'SingleLineText',
},
],
},
],
};
export const blog = {
tn: 'blog',
_tn: 'blog',
columns: [
{
validate: {
func: [],
args: [],
msg: [],
},
cn: 'id',
_cn: 'Id',
type: 'integer',
dt: 'int',
uidt: 'ID',
uip: '',
uicn: '',
dtx: 'integer',
ct: 'int(11)',
nrqd: false,
rqd: true,
ck: false,
pk: true,
un: true,
ai: true,
cdf: null,
clen: null,
np: 11,
ns: 0,
dtxp: '11',
dtxs: '',
tn: 'blog',
},
{
validate: {
func: [],
args: [],
msg: [],
},
cn: 'title',
_cn: 'Title',
type: 'string',
dt: 'varchar',
uidt: 'SingleLineText',
uip: '',
uicn: '',
dtx: 'specificType',
ct: 'varchar(45)',
nrqd: true,
rqd: false,
ck: false,
pk: false,
un: false,
ai: false,
cdf: null,
clen: 45,
np: null,
ns: null,
dtxp: '45',
dtxs: '',
pv: true,
alias: 'Title',
},
{
validate: {
func: [],
args: [],
msg: [],
},
cn: 'created_at',
_cn: 'CreatedAt',
type: 'timestamp',
dt: 'timestamp',
uidt: 'CreateTime',
uip: '',
uicn: '',
dtx: 'specificType',
ct: 'varchar(45)',
nrqd: true,
rqd: false,
ck: false,
pk: false,
un: false,
ai: false,
cdf: 'CURRENT_TIMESTAMP',
clen: 45,
np: null,
ns: null,
dtxp: '',
dtxs: '',
default: 'CURRENT_TIMESTAMP',
columnDefault: 'CURRENT_TIMESTAMP',
},
{
validate: {
func: [],
args: [],
msg: [],
},
cn: 'updated_at',
_cn: 'UpdatedAt',
type: 'timestamp',
dt: 'timestamp',
uidt: 'LastModifiedTime',
uip: '',
uicn: '',
dtx: 'specificType',
ct: 'varchar(45)',
nrqd: true,
rqd: false,
ck: false,
pk: false,
un: false,
ai: false,
cdf: 'CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP',
clen: 45,
np: null,
ns: null,
dtxp: '',
dtxs: '',
default: 'CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP',
columnDefault: 'CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP',
},
{
validate: {
func: [],
args: [],
msg: [],
},
cn: 'body',
_cn: 'body',
type: 'text',
dt: 'text',
uidt: 'LongText',
uip: '',
uicn: '',
dtx: 'specificType',
ct: 'integer(11)',
nrqd: true,
rqd: false,
ck: false,
pk: false,
un: false,
ai: false,
cdf: null,
clen: 45,
np: null,
ns: null,
dtxp: '',
dtxs: ' ',
cno: 'title5',
tn: 'blog',
alias: 'body',
},
],
pks: [],
hasMany: [
{
id: 3,
project_id: 'worrying_sloth_jum4',
db_alias: 'db',
tn: '_nc_m2m_tag_blog',
rtn: 'blog',
_tn: 'm2mtag_blog',
_rtn: 'blog',
cn: 'blog_c_id',
rcn: 'id',
_cn: null,
_rcn: null,
referenced_db_alias: null,
type: 'real',
db_type: 'mysql2',
ur: 'NO ACTION',
dr: 'NO ACTION',
created_at: '2021-10-29 07:28:12',
updated_at: '2021-10-29 07:28:12',
fkn: 'tag_blo_Dneo90_c_fk',
enabled: true,
},
{
id: 1,
project_id: 'worrying_sloth_jum4',
db_alias: 'db',
tn: 'comment',
rtn: 'blog',
_tn: 'comment',
_rtn: 'blog',
cn: 'title5',
rcn: 'id',
_cn: null,
_rcn: null,
referenced_db_alias: null,
type: 'real',
db_type: 'mysql2',
ur: 'NO ACTION',
dr: 'NO ACTION',
created_at: '2021-10-29 07:27:54',
updated_at: '2021-10-29 07:27:54',
fkn: null,
enabled: true,
},
],
belongsTo: [],
type: 'table',
v: [
{
hm: {
id: 1,
project_id: 'worrying_sloth_jum4',
db_alias: 'db',
tn: 'comment',
rtn: 'blog',
_tn: 'comment',
_rtn: 'blog',
cn: 'title5',
rcn: 'id',
_cn: null,
_rcn: null,
referenced_db_alias: null,
type: 'real',
db_type: 'mysql2',
ur: 'NO ACTION',
dr: 'NO ACTION',
created_at: '2021-10-29 07:27:54',
updated_at: '2021-10-29 07:27:54',
fkn: null,
enabled: true,
},
_cn: 'blog => comment',
},
{
mm: {
tn: 'blog',
cn: 'id',
vtn: '_nc_m2m_tag_blog',
vcn: 'blog_c_id',
vrcn: 'tag_p_id',
rtn: 'tag',
rcn: 'id',
_tn: 'blog',
_cn: null,
_rtn: 'tag',
_rcn: null,
},
_cn: 'blog <=> tag',
},
],
manyToMany: [
{
tn: 'blog',
cn: 'id',
vtn: '_nc_m2m_tag_blog',
vcn: 'blog_c_id',
vrcn: 'tag_p_id',
rtn: 'tag',
rcn: 'id',
_tn: 'blog',
_cn: null,
_rtn: 'tag',
_rcn: null,
},
],
};
export const comment = {
tn: 'comment',
_tn: 'comment',
columns: [
{
validate: {
func: [],
args: [],
msg: [],
},
cn: 'id',
_cn: 'Id',
type: 'integer',
dt: 'int',
uidt: 'ID',
uip: '',
uicn: '',
dtx: 'integer',
ct: 'int(11)',
nrqd: false,
rqd: true,
ck: false,
pk: true,
un: true,
ai: true,
cdf: null,
clen: null,
np: 11,
ns: 0,
dtxp: '11',
dtxs: '',
tn: 'comment',
},
{
validate: {
func: [],
args: [],
msg: [],
},
cn: 'created_at',
_cn: 'CreatedAt',
type: 'timestamp',
dt: 'timestamp',
uidt: 'CreateTime',
uip: '',
uicn: '',
dtx: 'specificType',
ct: 'varchar(45)',
nrqd: true,
rqd: false,
ck: false,
pk: false,
un: false,
ai: false,
cdf: 'CURRENT_TIMESTAMP',
clen: 45,
np: null,
ns: null,
dtxp: '',
dtxs: '',
default: 'CURRENT_TIMESTAMP',
columnDefault: 'CURRENT_TIMESTAMP',
pv: true,
},
{
validate: {
func: [],
args: [],
msg: [],
},
cn: 'updated_at',
_cn: 'UpdatedAt',
type: 'timestamp',
dt: 'timestamp',
uidt: 'LastModifiedTime',
uip: '',
uicn: '',
dtx: 'specificType',
ct: 'varchar(45)',
nrqd: true,
rqd: false,
ck: false,
pk: false,
un: false,
ai: false,
cdf: 'CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP',
clen: 45,
np: null,
ns: null,
dtxp: '',
dtxs: '',
default: 'CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP',
columnDefault: 'CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP',
},
{
validate: {
func: [],
args: [],
msg: [],
},
cn: 'body',
_cn: 'body',
type: 'text',
dt: 'text',
uidt: 'LongText',
uip: '',
uicn: '',
dtx: 'specificType',
ct: 'integer(11)',
nrqd: true,
rqd: false,
ck: false,
pk: false,
un: false,
ai: false,
cdf: null,
clen: 45,
np: null,
ns: null,
dtxp: '',
dtxs: ' ',
cno: 'title4',
tn: 'comment',
alias: 'body',
},
{
validate: {
func: [],
args: [],
msg: [],
},
cn: 'title5',
_cn: 'title5',
type: 'integer',
dt: 'int',
uidt: 'ForeignKey',
uip: '',
uicn: '',
dtx: 'specificType',
ct: 'integer(11)',
nrqd: true,
rqd: false,
ck: false,
pk: false,
un: true,
ai: false,
cdf: null,
clen: 45,
np: null,
ns: null,
dtxp: '11',
dtxs: '',
cno: 'title5',
tn: 'comment',
},
],
pks: [],
hasMany: [],
belongsTo: [
{
id: 1,
project_id: 'worrying_sloth_jum4',
db_alias: 'db',
tn: 'comment',
rtn: 'blog',
_tn: 'comment',
_rtn: 'blog',
cn: 'title5',
rcn: 'id',
_cn: null,
_rcn: null,
referenced_db_alias: null,
type: 'real',
db_type: 'mysql2',
ur: 'NO ACTION',
dr: 'NO ACTION',
created_at: '2021-10-29 07:27:54',
updated_at: '2021-10-29 07:27:54',
fkn: null,
enabled: true,
},
],
type: 'table',
v: [
{
bt: {
id: 1,
project_id: 'worrying_sloth_jum4',
db_alias: 'db',
tn: 'comment',
rtn: 'blog',
_tn: 'comment',
_rtn: 'blog',
cn: 'title5',
rcn: 'id',
_cn: null,
_rcn: null,
referenced_db_alias: null,
type: 'real',
db_type: 'mysql2',
ur: 'NO ACTION',
dr: 'NO ACTION',
created_at: '2021-10-29 07:27:54',
updated_at: '2021-10-29 07:27:54',
fkn: null,
enabled: true,
},
_cn: 'blog <= comment',
},
],
};
export const tag = {
tn: 'tag',
_tn: 'tag',
columns: [
{
validate: {
func: [],
args: [],
msg: [],
},
cn: 'id',
_cn: 'Id',
type: 'integer',
dt: 'int',
uidt: 'ID',
uip: '',
uicn: '',
dtx: 'integer',
ct: 'int(11)',
nrqd: false,
rqd: true,
ck: false,
pk: true,
un: true,
ai: true,
cdf: null,
clen: null,
np: 11,
ns: 0,
dtxp: '11',
dtxs: '',
},
{
validate: {
func: [],
args: [],
msg: [],
},
cn: 'title',
_cn: 'Title',
type: 'string',
dt: 'varchar',
uidt: 'SingleLineText',
uip: '',
uicn: '',
dtx: 'specificType',
ct: 'varchar(45)',
nrqd: true,
rqd: false,
ck: false,
pk: false,
un: false,
ai: false,
cdf: null,
clen: 45,
np: null,
ns: null,
dtxp: '45',
dtxs: '',
pv: true,
alias: 'Title',
},
{
validate: {
func: [],
args: [],
msg: [],
},
cn: 'created_at',
_cn: 'CreatedAt',
type: 'timestamp',
dt: 'timestamp',
uidt: 'CreateTime',
uip: '',
uicn: '',
dtx: 'specificType',
ct: 'varchar(45)',
nrqd: true,
rqd: false,
ck: false,
pk: false,
un: false,
ai: false,
cdf: 'CURRENT_TIMESTAMP',
clen: 45,
np: null,
ns: null,
dtxp: '',
dtxs: '',
default: 'CURRENT_TIMESTAMP',
columnDefault: 'CURRENT_TIMESTAMP',
},
{
validate: {
func: [],
args: [],
msg: [],
},
cn: 'updated_at',
_cn: 'UpdatedAt',
type: 'timestamp',
dt: 'timestamp',
uidt: 'LastModifiedTime',
uip: '',
uicn: '',
dtx: 'specificType',
ct: 'varchar(45)',
nrqd: true,
rqd: false,
ck: false,
pk: false,
un: false,
ai: false,
cdf: 'CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP',
clen: 45,
np: null,
ns: null,
dtxp: '',
dtxs: '',
default: 'CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP',
columnDefault: 'CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP',
},
],
pks: [],
hasMany: [
{
id: 2,
project_id: 'worrying_sloth_jum4',
db_alias: 'db',
tn: '_nc_m2m_tag_blog',
rtn: 'tag',
_tn: 'm2mtag_blog',
_rtn: 'tag',
cn: 'tag_p_id',
rcn: 'id',
_cn: null,
_rcn: null,
referenced_db_alias: null,
type: 'real',
db_type: 'mysql2',
ur: 'NO ACTION',
dr: 'NO ACTION',
created_at: '2021-10-29 07:28:11',
updated_at: '2021-10-29 07:28:11',
fkn: 'tag_blo_rKb7Gq_p_fk',
enabled: true,
},
],
belongsTo: [],
type: 'table',
v: [
{
mm: {
tn: 'tag',
cn: 'id',
vtn: '_nc_m2m_tag_blog',
vcn: 'tag_p_id',
vrcn: 'blog_c_id',
rtn: 'blog',
rcn: 'id',
_tn: 'tag',
_cn: null,
_rtn: 'blog',
_rcn: null,
},
_cn: 'tag <=> blog',
},
],
manyToMany: [
{
tn: 'tag',
cn: 'id',
vtn: '_nc_m2m_tag_blog',
vcn: 'tag_p_id',
vrcn: 'blog_c_id',
rtn: 'blog',
rcn: 'id',
_tn: 'tag',
_cn: null,
_rtn: 'blog',
_rcn: null,
},
],
};

70
packages/nocodb/src/__tests__/tsconfig.json

@ -1,70 +0,0 @@
{
"compilerOptions": {
"skipLibCheck": true,
"composite": true,
"target": "es2017",
"outDir": "build/main",
"rootDir": "src",
"moduleResolution": "node",
"module": "commonjs",
"declaration": true,
"inlineSourceMap": true,
"esModuleInterop": true
/* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
"allowJs": false,
// "strict": true /* Enable all strict type-checking options. */,
/* Strict Type-Checking Options */
// "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
// "strictNullChecks": true /* Enable strict null checks. */,
// "strictFunctionTypes": true /* Enable strict checking of function types. */,
// "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */,
// "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */,
// "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */,
"resolveJsonModule": true,
/* Additional Checks */
"noUnusedLocals": false
/* Report errors on unused locals. */,
"noUnusedParameters": false
/* Report errors on unused parameters. */,
"noImplicitReturns": false
/* Report error when not all code paths in function return a value. */,
"noFallthroughCasesInSwitch": false
/* Report errors for fallthrough cases in switch statement. */,
/* Debugging Options */
"traceResolution": false
/* Report module resolution log messages. */,
"listEmittedFiles": false
/* Print names of generated files part of the compilation. */,
"listFiles": false
/* Print names of files part of the compilation. */,
"pretty": true
/* Stylize errors and messages using color and context. */,
/* Experimental Options */
// "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */,
// "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */,
"lib": [
"es2017"
],
"types": [
"mocha", "node"
],
"typeRoots": [
"node_modules/@types",
"src/types"
]
},
"include": [
"src/**/*.ts",
// "src/lib/xgene/migrations/*.js",
"src/**/*.json"
],
"exclude": [
"node_modules/**",
"node_modules",
"../../../xc-lib-private/**",
"../../../xc-lib-private"
],
"compileOnSave": false
}

80
packages/nocodb/src/__tests__/unit/lib/meta/api/dataApis/dataAliasApis.test.ts

@ -1,80 +0,0 @@
'use strict';
import rewire from 'rewire';
import sinon from 'sinon';
import { expect } from 'chai';
import Base from '../../../../../../lib/models/Base';
import Model from '../../../../../../lib/models/Model';
import NcConnectionMgrv2 from '../../../../../../lib/utils/common/NcConnectionMgrv2';
import * as getAstObject from '../../../../../../lib/db/sql-data-mapper/lib/sql/helpers/getAst';
const dataAliasApis = rewire(
'../../../../../../lib/meta/api/dataApis/dataAliasApis'
);
const getFindOne = dataAliasApis.__get__('getFindOne');
describe('getFindOne', () => {
const model = {
id: 'modelId',
base_id: 'baseId',
};
const view = {
id: 'viewId',
};
const base = {
id: 'baseId',
};
const dbDriver = {
id: 'dbDriverId',
};
const req = { query: {} };
const baseModel = {
findOne: sinon.fake.returns(undefined),
};
const baseGetFake = sinon.replace(Base, 'get', sinon.fake.returns(base));
const baseModelFake = sinon.replace(
Model,
'getBaseModelSQL',
sinon.fake.returns(baseModel)
);
sinon.replace(NcConnectionMgrv2, 'get', sinon.fake.returns(dbDriver));
const getAstFake = sinon.fake.returns({ id: 1 });
sinon.replace(getAstObject, 'default', getAstFake);
it('calls Base.get to find base', async () => {
await getFindOne(model, view, req);
expect(baseGetFake.calledWith(model.base_id)).to.be.true;
});
it('call Model.getBaseModelSQL to find baseModel', async () => {
await getFindOne(model, view, req);
expect(
baseModelFake.calledWith({
id: model.id,
viewId: view.id,
dbDriver: dbDriver,
})
).to.be.true;
});
it('calls baseModel.findOne', async () => {
await getFindOne(model, view, req);
expect(baseModel.findOne.calledWith({ ...req.query })).to.be.true;
});
describe('when data is not found', () => {
it('should return empty object', async () => {
expect(await getFindOne(model, view, req)).to.be.empty;
});
});
describe('when data is found', () => {
it('returns data', async () => {
const findOneResult = {
id: 'dataId',
};
baseModel.findOne = sinon.fake.returns(findOneResult);
expect(await getFindOne(model, view, req)).eql(findOneResult);
});
});
});
Loading…
Cancel
Save