tachybase_todo/packages/actions/src/__tests__/index.ts
Junyi b2fe087fc2
Feature: custom operators for querying (#48)
* feat: add some custom operators for querying

* feat: add some custom operators for querying

* test: fix cases

* improve custom operator function

* improve filter field component

Co-authored-by: chenos <chenlinxh@gmail.com>
2020-12-28 21:08:13 +08:00

147 lines
3.5 KiB
TypeScript

import { resolve } from 'path';
import glob from 'glob';
import Koa from 'koa';
import { Dialect } from 'sequelize';
import bodyParser from 'koa-bodyparser';
import supertest from 'supertest';
import Database, { requireModule } from '@nocobase/database';
import Resourcer from '@nocobase/resourcer';
import associated from '../middlewares/associated';
import actions from '..';
import list1 from './actions/list1';
import create1 from './actions/create1';
import create2 from './actions/create2';
import update1 from './actions/update1';
import update2 from './actions/update2';
function getTestKey() {
const { id } = require.main;
const key = id
.replace(`${process.env.PWD}/packages`, '')
.replace(/src\/__tests__/g, '')
.replace('.test.ts', '')
.replace(/[^\w]/g, '_')
.replace(/_+/g, '_')
.replace(/^_|_$/g, '');
return key
}
const connection = {
config: {
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
host: process.env.DB_HOST,
port: Number.parseInt(process.env.DB_PORT, 10),
dialect: process.env.DB_DIALECT as Dialect,
define: {
hooks: {
beforeCreate(model, options) {
},
},
},
logging: process.env.DB_LOG_SQL === 'on' ? console.log : false,
},
database: null,
create() {
this.database = new Database(this.config);
},
get() {
return this.database;
}
};
const tableFiles = glob.sync(`${resolve(__dirname, './tables')}/*.ts`);
// resourcer 在内存中是单例,需要谨慎使用
export const resourcer = new Resourcer();
resourcer.use(associated);
resourcer.registerActionHandlers({...actions.associate, ...actions.common });
resourcer.define({
name: 'posts',
actions: {
...actions.common,
list1,
create1,
create2,
update1,
update2
},
});
resourcer.define({
name: 'comments',
actions: actions.common,
});
resourcer.define({
name: 'users',
actions: actions.common,
});
resourcer.define({
name: 'profiles',
actions: actions.common,
});
resourcer.define({
type: 'hasOne',
name: 'users.profile',
actions: actions.associate,
});
resourcer.define({
type: 'hasMany',
name: 'posts.comments',
actions: actions.associate,
});
resourcer.define({
type: 'hasMany',
name: 'users.posts',
actions: actions.associate,
});
resourcer.define({
type: 'belongsTo',
name: 'posts.user',
actions: actions.associate,
});
resourcer.define({
type: 'belongsToMany',
name: 'posts.tags',
actions: actions.associate,
});
const app = new Koa();
app.use(async (ctx, next) => {
ctx.db = connection.get();
await next();
});
app.use(bodyParser());
app.use(resourcer.middleware());
// 使用 agent 可以减少部分模板代码
export const agent = supertest.agent(app.callback());
export async function initDatabase() {
if (!connection.get()) {
connection.create();
}
const database = connection.get();
// 由于 jest 每个测试文件是独立 worker 进程的机制,各个进程使用的是不同的数据库连接实例,但又对应到同一个数据库。
// 所以不同测试文件会存在表结构冲突,这里使用了基于文件唯一的 key 作为后缀区分不同进程使用的数据库表,以满足并行测试。
const key = getTestKey();
tableFiles.forEach(file => {
const options = requireModule(file);
database.table(typeof options === 'function' ? options(database) : {
...options,
tableName: `${key}_${options.tableName}`
});
});
await database.sync({
force: true,
});
return database;
}