mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-08 15:09:27 +08:00
* feat: improve code * chore: update version * feat: api service * fix: api services * feat: improve code * feat: improve code * feat: improve code * feat: pm socket * fix: test errors * feat: add built-in plugins before upgrade * feat: update docs * feat: improve code * fix: after load
344 lines
7.8 KiB
TypeScript
344 lines
7.8 KiB
TypeScript
import { Database } from '@nocobase/database';
|
|
import PluginCollectionManager from '@nocobase/plugin-collection-manager';
|
|
import PluginErrorHandler from '@nocobase/plugin-error-handler';
|
|
import UiSchemaStoragePlugin, { UiSchemaRepository } from '@nocobase/plugin-ui-schema-storage';
|
|
import { mockServer, MockServer } from '@nocobase/test';
|
|
|
|
describe('server hooks', () => {
|
|
let app: MockServer;
|
|
let db: Database;
|
|
let uiSchemaRepository: UiSchemaRepository;
|
|
let uiSchemaPlugin: UiSchemaStoragePlugin;
|
|
|
|
const schema = {
|
|
'x-uid': 'root',
|
|
name: 'root',
|
|
properties: {
|
|
row: {
|
|
'x-uid': 'table',
|
|
'x-component': 'Table',
|
|
'x-collection': 'posts',
|
|
'x-server-hooks': [
|
|
{
|
|
type: 'onCollectionDestroy',
|
|
collection: 'posts',
|
|
method: 'onCollectionDestroy',
|
|
},
|
|
],
|
|
properties: {
|
|
col1: {
|
|
'x-uid': 'col1',
|
|
'x-component': 'Col',
|
|
properties: {
|
|
field1: {
|
|
'x-uid': 'field1',
|
|
'x-component': 'Input',
|
|
'x-collection-field': 'posts.title',
|
|
'x-server-hooks': [
|
|
{
|
|
type: 'onCollectionFieldDestroy',
|
|
collection: 'posts',
|
|
field: 'title',
|
|
method: 'onFieldDestroy',
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
afterEach(async () => {
|
|
await app.destroy();
|
|
});
|
|
|
|
beforeEach(async () => {
|
|
app = mockServer({
|
|
registerActions: true,
|
|
});
|
|
|
|
await app.cleanDb();
|
|
db = app.db;
|
|
|
|
app.plugin(UiSchemaStoragePlugin, { name: 'ui-schema-storage' });
|
|
app.plugin(PluginErrorHandler, { name: 'error-handler' });
|
|
app.plugin(PluginCollectionManager, { name: 'collection-manager' });
|
|
|
|
await app.loadAndInstall();
|
|
|
|
uiSchemaRepository = db.getRepository('uiSchemas');
|
|
await uiSchemaRepository.insert(schema);
|
|
|
|
uiSchemaPlugin = app.getPlugin<UiSchemaStoragePlugin>('ui-schema-storage');
|
|
});
|
|
|
|
it('should call server hooks onFieldDestroy', async () => {
|
|
const PostModel = await db.getRepository('collections').create({
|
|
values: {
|
|
name: 'posts',
|
|
},
|
|
});
|
|
|
|
const fieldModel = await db.getRepository('fields').create({
|
|
values: {
|
|
name: 'title',
|
|
type: 'string',
|
|
collectionName: 'posts',
|
|
},
|
|
});
|
|
|
|
// @ts-ignore
|
|
await PostModel.migrate();
|
|
|
|
const serverHooks = uiSchemaPlugin.serverHooks;
|
|
const hookFn = jest.fn();
|
|
|
|
serverHooks.register('onCollectionFieldDestroy', 'onFieldDestroy', hookFn);
|
|
|
|
// destroy a field
|
|
await db.getRepository('fields').destroy({
|
|
filter: {
|
|
name: 'title',
|
|
},
|
|
individualHooks: true,
|
|
});
|
|
|
|
expect(hookFn).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should call server hooks onCollectionDestroy', async () => {
|
|
const PostModel = await db.getRepository('collections').create({
|
|
values: {
|
|
name: 'posts',
|
|
},
|
|
});
|
|
|
|
const fieldModel = await db.getRepository('fields').create({
|
|
values: {
|
|
name: 'title',
|
|
type: 'string',
|
|
collectionName: 'posts',
|
|
},
|
|
});
|
|
|
|
// @ts-ignore
|
|
await PostModel.migrate();
|
|
|
|
const serverHooks = uiSchemaPlugin.serverHooks;
|
|
|
|
const hookFn = jest.fn();
|
|
|
|
serverHooks.register('onCollectionDestroy', 'onCollectionDestroy', hookFn);
|
|
|
|
// destroy a field
|
|
await db.getRepository('collections').destroy({
|
|
filter: {
|
|
name: 'posts',
|
|
},
|
|
individualHooks: true,
|
|
});
|
|
|
|
expect(hookFn).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should call server hooks onUiSchemaCreate', async () => {
|
|
const menuSchema = {
|
|
'x-uid': 'menu',
|
|
'x-server-hooks': [
|
|
{
|
|
type: 'onSelfCreate',
|
|
method: 'afterCreateMenu',
|
|
},
|
|
],
|
|
};
|
|
|
|
const serverHooks = uiSchemaPlugin.serverHooks;
|
|
const hookFn = jest.fn();
|
|
|
|
serverHooks.register('onSelfCreate', 'afterCreateMenu', hookFn);
|
|
|
|
await uiSchemaRepository.insert(menuSchema);
|
|
|
|
expect(hookFn).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should call server hooks onAnyCollectionFieldDestroy', async () => {
|
|
const menuSchema = {
|
|
'x-uid': 'menu',
|
|
'x-server-hooks': [
|
|
{
|
|
type: 'onAnyCollectionFieldDestroy',
|
|
collection: 'posts',
|
|
method: 'test1',
|
|
},
|
|
],
|
|
};
|
|
|
|
await uiSchemaRepository.insert(menuSchema);
|
|
|
|
const PostModel = await db.getRepository('collections').create({
|
|
values: {
|
|
name: 'posts',
|
|
},
|
|
});
|
|
|
|
const fieldModel = await db.getRepository('fields').create({
|
|
values: {
|
|
name: 'title',
|
|
type: 'string',
|
|
collectionName: 'posts',
|
|
},
|
|
});
|
|
|
|
// @ts-ignore
|
|
await PostModel.migrate();
|
|
|
|
const serverHooks = uiSchemaPlugin.serverHooks;
|
|
const hookFn = jest.fn();
|
|
|
|
serverHooks.register('onAnyCollectionFieldDestroy', 'test1', hookFn);
|
|
|
|
// destroy a field
|
|
await db.getRepository('fields').destroy({
|
|
filter: {
|
|
name: 'title',
|
|
},
|
|
individualHooks: true,
|
|
});
|
|
|
|
expect(hookFn).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should rollback after throw error', async () => {
|
|
const testSchema = {
|
|
'x-uid': 'test',
|
|
'x-collection-field': 'posts.title',
|
|
'x-server-hooks': [
|
|
{
|
|
type: 'onCollectionFieldDestroy',
|
|
collection: 'posts',
|
|
field: 'title',
|
|
method: 'preventDestroy',
|
|
},
|
|
],
|
|
};
|
|
|
|
await uiSchemaRepository.create({
|
|
values: {
|
|
schema: testSchema,
|
|
},
|
|
});
|
|
|
|
const PostModel = await db.getRepository('collections').create({
|
|
values: {
|
|
name: 'posts',
|
|
},
|
|
});
|
|
|
|
const fieldModel = await db.getRepository('fields').create({
|
|
values: {
|
|
name: 'title',
|
|
type: 'string',
|
|
collectionName: 'posts',
|
|
},
|
|
});
|
|
|
|
// @ts-ignore
|
|
await PostModel.migrate();
|
|
|
|
const serverHooks = uiSchemaPlugin.serverHooks;
|
|
|
|
const jestFn = jest.fn();
|
|
|
|
serverHooks.register('onCollectionFieldDestroy', 'preventDestroy', async ({ options }) => {
|
|
await options.transaction.rollback();
|
|
jestFn();
|
|
throw new Error('cant delete field');
|
|
});
|
|
|
|
try {
|
|
// destroy a field
|
|
await db.getRepository('fields').destroy({
|
|
filter: {
|
|
name: 'title',
|
|
},
|
|
individualHooks: true,
|
|
});
|
|
} catch (e) {}
|
|
|
|
expect(jestFn).toHaveBeenCalled();
|
|
expect(
|
|
await db.getRepository('fields').findOne({
|
|
filter: {
|
|
name: 'title',
|
|
},
|
|
}),
|
|
).toBeDefined();
|
|
});
|
|
|
|
it('should call onSelfMove', async () => {
|
|
const schema = {
|
|
'x-uid': 'A',
|
|
name: 'A',
|
|
properties: {
|
|
B: {
|
|
'x-uid': 'B',
|
|
properties: {
|
|
C: {
|
|
'x-uid': 'C',
|
|
properties: {
|
|
D: {
|
|
'x-uid': 'D',
|
|
'x-server-hooks': [
|
|
{
|
|
type: 'onSelfMove',
|
|
method: 'testOnSelfMove',
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
E: {
|
|
'x-uid': 'E',
|
|
},
|
|
},
|
|
};
|
|
|
|
const serverHooks = uiSchemaPlugin.serverHooks;
|
|
|
|
const jestFn = jest.fn();
|
|
|
|
serverHooks.register('onSelfMove', 'testOnSelfMove', async ({ options }) => {
|
|
jestFn();
|
|
});
|
|
|
|
await uiSchemaRepository.insert(schema);
|
|
|
|
await uiSchemaRepository.insertAdjacent(
|
|
'afterEnd',
|
|
'E',
|
|
{
|
|
'x-uid': 'D',
|
|
},
|
|
{
|
|
removeParentsIfNoChildren: true,
|
|
wrap: {
|
|
'x-uid': 'F',
|
|
name: 'F',
|
|
properties: {
|
|
G: {
|
|
'x-uid': 'G',
|
|
},
|
|
},
|
|
},
|
|
},
|
|
);
|
|
|
|
expect(jestFn).toHaveBeenCalled();
|
|
});
|
|
});
|