feat: improve mock server agent

This commit is contained in:
chenos 2022-01-23 15:04:50 +08:00
parent f0eb2eee20
commit 2a2d67e38b
11 changed files with 106 additions and 87 deletions

View File

@ -1,8 +1,8 @@
import { mockServer } from './index'; import { mockServer, MockServer } from './index';
import { registerActions } from '@nocobase/actions'; import { registerActions } from '@nocobase/actions';
describe('add action', () => { describe('add action', () => {
let app; let app: MockServer;
let Post; let Post;
let Comment; let Comment;
let Tag; let Tag;
@ -80,9 +80,8 @@ describe('add action', () => {
const response = await app const response = await app
.agent() .agent()
.resource('posts.tags') .resource('posts.tags', p1.get('id'))
.add({ .add({
associatedIndex: p1.get('id'),
values: [t1.get('id'), t2.get('id')], values: [t1.get('id'), t2.get('id')],
}); });
@ -91,9 +90,8 @@ describe('add action', () => {
// add with through values // add with through values
await app await app
.agent() .agent()
.resource('posts.tags') .resource('posts.tags', p1.get('id'))
.add({ .add({
associatedIndex: p1.get('id'),
values: [ values: [
[ [
t3.get('id'), t3.get('id'),

View File

@ -71,9 +71,8 @@ describe('create action', () => {
const response = await app const response = await app
.agent() .agent()
.resource('posts.comments') .resource('posts.comments', p1.get('id'))
.create({ .create({
associatedIndex: p1.get('id'),
values: { values: {
content: 'hello', content: 'hello',
}, },
@ -95,9 +94,8 @@ describe('create action', () => {
expect(await Tag.repository.findOne()).toBeNull(); expect(await Tag.repository.findOne()).toBeNull();
const response = await app const response = await app
.agent() .agent()
.resource('posts.tags') .resource('posts.tags', p1.get('id'))
.create({ .create({
associatedIndex: p1.get('id'),
values: { values: {
name: 'hello', name: 'hello',
}, },

View File

@ -1,8 +1,8 @@
import { mockServer } from './index'; import { MockServer, mockServer } from './index';
import { registerActions } from '@nocobase/actions'; import { registerActions } from '@nocobase/actions';
describe('destroy action', () => { describe('destroy action', () => {
let app; let app: MockServer;
let Post; let Post;
let Comment; let Comment;
let Tag; let Tag;
@ -71,7 +71,7 @@ describe('destroy action', () => {
.agent() .agent()
.resource('posts') .resource('posts')
.destroy({ .destroy({
resourceIndex: p1.get('id'), filterByTk: p1.get('id'),
}); });
expect(await Post.repository.count()).toEqual(0); expect(await Post.repository.count()).toEqual(0);
@ -93,10 +93,9 @@ describe('destroy action', () => {
const response = await app const response = await app
.agent() .agent()
.resource('posts.comments') .resource('posts.comments', p1.get('id'))
.destroy({ .destroy({
resourceIndex: c1.get('id'), filterByTk: c1.get('id'),
associatedIndex: p1.get('id'),
}); });
expect(await Comment.repository.count()).toEqual(0); expect(await Comment.repository.count()).toEqual(0);
@ -123,10 +122,9 @@ describe('destroy action', () => {
const response = await app const response = await app
.agent() .agent()
.resource('posts.tags') .resource('posts.tags', p1t1.get('id'))
.destroy({ .destroy({
resourceIndex: p1.get('id'), filterByTk: p1.get('id'),
associatedIndex: p1t1.get('id'),
}); });
expect(await Tag.repository.count()).toEqual(0); expect(await Tag.repository.count()).toEqual(0);
@ -146,10 +144,8 @@ describe('destroy action', () => {
const response = await app const response = await app
.agent() .agent()
.resource('posts.profile') .resource('posts.profile', p1.get('id'))
.destroy({ .destroy();
associatedIndex: p1.get('id'),
});
expect(await Profile.repository.count()).toEqual(0); expect(await Profile.repository.count()).toEqual(0);
}); });

View File

@ -1,8 +1,8 @@
import { mockServer } from './index'; import { MockServer, mockServer } from './index';
import { registerActions } from '@nocobase/actions'; import { registerActions } from '@nocobase/actions';
describe('get action', () => { describe('get action', () => {
let app; let app: MockServer;
let Post; let Post;
let Comment; let Comment;
let Tag; let Tag;
@ -77,7 +77,7 @@ describe('get action', () => {
.agent() .agent()
.resource('posts') .resource('posts')
.get({ .get({
resourceIndex: p1.get('id'), filterByTk: p1.get('id'),
}); });
const body = response.body; const body = response.body;
@ -100,10 +100,9 @@ describe('get action', () => {
const response = await app const response = await app
.agent() .agent()
.resource('posts.comments') .resource('posts.comments', p1.get('id'))
.get({ .get({
resourceIndex: c1.get('id'), filterByTk: c1.get('id'),
associatedIndex: p1.get('id'),
}); });
expect(response.body['id']).toEqual(c1.get('id')); expect(response.body['id']).toEqual(c1.get('id'));
@ -123,10 +122,8 @@ describe('get action', () => {
const response = await app const response = await app
.agent() .agent()
.resource('posts.profile') .resource('posts.profile', p1.get('id'))
.get({ .get();
associatedIndex: p1.get('id'),
});
expect(response.body['id']).toEqual(postProfile.get('id')); expect(response.body['id']).toEqual(postProfile.get('id'));
}); });

View File

@ -48,21 +48,28 @@ export function mockDatabase(options?: DatabaseOptions): Database {
} }
interface ActionParams { interface ActionParams {
fields?: fields?: string[];
| string[]
| {
only?: string[];
except?: string[];
appends?: string[];
};
filter?: any; filter?: any;
filterByTk?: any;
sort?: string[]; sort?: string[];
page?: number; page?: number;
perPage?: number; perPage?: number;
values?: any; values?: any;
/**
* @deprecated
*/
resourceName?: string; resourceName?: string;
/**
* @deprecated
*/
resourceIndex?: string; resourceIndex?: string;
/**
* @deprecated
*/
associatedName?: string; associatedName?: string;
/**
* @deprecated
*/
associatedIndex?: string; associatedIndex?: string;
[key: string]: any; [key: string]: any;
} }
@ -135,29 +142,35 @@ export class MockServer extends Koa {
this.resourcer.registerActionHandlers(handlers); this.resourcer.registerActionHandlers(handlers);
} }
agent(): SuperAgentTest & { resource: (name: string) => Resource } { agent(): SuperAgentTest & { resource: (name: string, resourceOf?: any) => Resource } {
const agent = supertest.agent(this.callback()); const agent = supertest.agent(this.callback());
const prefix = this.resourcer.options.prefix; const prefix = this.resourcer.options.prefix;
const proxy = new Proxy(agent, { const proxy = new Proxy(agent, {
get(target, method: string, receiver) { get(target, method: string, receiver) {
if (method === 'resource') { if (method === 'resource') {
return (name: string) => { return (name: string, resourceOf?: any) => {
const keys = name.split('.'); const keys = name.split('.');
const proxy = new Proxy( const proxy = new Proxy(
{}, {},
{ {
get(target, method: string, receiver) { get(target, method: string, receiver) {
return (params: ActionParams = {}) => { return (params: ActionParams = {}) => {
const { associatedIndex, resourceIndex, values = {}, file, ...restParams } = params; let { filterByTk, values = {}, file, ...restParams } = params;
if (params.associatedIndex) {
resourceOf = params.associatedIndex;
}
if (params.resourceIndex) {
filterByTk = params.resourceIndex;
}
let url = prefix; let url = prefix;
if (keys.length > 1) { if (keys.length > 1) {
url += `/${keys[0]}/${associatedIndex}/${keys[1]}`; url += `/${keys[0]}/${resourceOf}/${keys[1]}`;
} else { } else {
url += `/${name}`; url += `/${name}`;
} }
url += `:${method as string}`; url += `:${method as string}`;
if (resourceIndex) { if (filterByTk) {
url += `/${resourceIndex}`; url += `/${filterByTk}`;
} }
switch (method) { switch (method) {

View File

@ -103,8 +103,8 @@ describe('list action', () => {
// tags with posts id eq 1 // tags with posts id eq 1
const response = await app const response = await app
.agent() .agent()
.resource('posts.tags') .resource('posts.tags', 1)
.list({ associatedIndex: 1, fields: ['id', 'posts_tags.createdAt'], sort: ['id'] }); .list({ fields: ['id', 'posts_tags.createdAt'], sort: ['id'] });
const body = response.body; const body = response.body;
expect(body.count).toEqual(2); expect(body.count).toEqual(2);

View File

@ -91,9 +91,8 @@ describe('remove action', () => {
const response = await app const response = await app
.agent() .agent()
.resource('posts.tags') .resource('posts.tags', p1.get('id'))
.remove({ .remove({
associatedIndex: p1.get('id'),
values: [t1.get('id')], values: [t1.get('id')],
}); });
@ -115,10 +114,8 @@ describe('remove action', () => {
const response = await app const response = await app
.agent() .agent()
.resource('posts.profile') .resource('posts.profile', p1.get('id'))
.remove({ .remove();
associatedIndex: p1.get('id'),
});
await postProfile.reload(); await postProfile.reload();
expect(await postProfile.getPost()).toBeNull(); expect(await postProfile.getPost()).toBeNull();

View File

@ -80,9 +80,8 @@ describe('set action', () => {
const response = await app const response = await app
.agent() .agent()
.resource('posts.tags') .resource('posts.tags', p1.get('id'))
.set({ .set({
associatedIndex: p1.get('id'),
values: [t1.get('id'), t2.get('id')], values: [t1.get('id'), t2.get('id')],
}); });
@ -91,9 +90,8 @@ describe('set action', () => {
// add with through values // add with through values
await app await app
.agent() .agent()
.resource('posts.tags') .resource('posts.tags', p1.get('id'))
.set({ .set({
associatedIndex: p1.get('id'),
values: [ values: [
[ [
t3.get('id'), t3.get('id'),

View File

@ -80,9 +80,8 @@ describe('toggle action', () => {
const response = await app const response = await app
.agent() .agent()
.resource('posts.tags') .resource('posts.tags', p1.get('id'))
.toggle({ .toggle({
associatedIndex: p1.get('id'),
values: [t1.get('id'), t2.get('id')], values: [t1.get('id'), t2.get('id')],
}); });
@ -90,9 +89,8 @@ describe('toggle action', () => {
await app await app
.agent() .agent()
.resource('posts.tags') .resource('posts.tags', p1.get('id'))
.toggle({ .toggle({
associatedIndex: p1.get('id'),
values: [t2.get('id')], values: [t2.get('id')],
}); });

View File

@ -1,8 +1,8 @@
import { mockServer } from './index'; import { MockServer, mockServer } from './index';
import { registerActions } from '@nocobase/actions'; import { registerActions } from '@nocobase/actions';
describe('update action', () => { describe('update action', () => {
let app; let app: MockServer;
let Post; let Post;
let Comment; let Comment;
let Tag; let Tag;
@ -71,7 +71,7 @@ describe('update action', () => {
.agent() .agent()
.resource('posts') .resource('posts')
.update({ .update({
resourceIndex: p1.get('id'), filterByTk: p1.get('id'),
values: { values: {
title: 'p0', title: 'p0',
}, },
@ -97,10 +97,9 @@ describe('update action', () => {
const response = await app const response = await app
.agent() .agent()
.resource('posts.comments') .resource('posts.comments', p1.get('id'))
.update({ .update({
resourceIndex: c1.get('id'), filterByTk: c1.get('id'),
associatedIndex: p1.get('id'),
values: { values: {
content: 'c0', content: 'c0',
}, },
@ -129,10 +128,9 @@ describe('update action', () => {
const response = await app const response = await app
.agent() .agent()
.resource('posts.tags') .resource('posts.tags', p1t1.get('id'))
.update({ .update({
resourceIndex: p1.get('id'), filterByTk: p1.get('id'),
associatedIndex: p1t1.get('id'),
values: { values: {
posts_tags: { posts_tags: {
tagged_at: 'test', tagged_at: 'test',
@ -158,9 +156,8 @@ describe('update action', () => {
const response = await app const response = await app
.agent() .agent()
.resource('posts.profile') .resource('posts.profile', p1.get('id'))
.update({ .update({
associatedIndex: p1.get('id'),
values: { values: {
post_profile: 'test0', post_profile: 'test0',
}, },

View File

@ -4,21 +4,28 @@ import Application, { ApplicationOptions } from '@nocobase/server';
import { getConfig } from './mockDatabase'; import { getConfig } from './mockDatabase';
interface ActionParams { interface ActionParams {
fields?: filterByTk?: any;
| string[] fields?: string[];
| {
only?: string[];
except?: string[];
appends?: string[];
};
filter?: any; filter?: any;
sort?: string[]; sort?: string[];
page?: number; page?: number;
perPage?: number; perPage?: number;
values?: any; values?: any;
/**
* @deprecated
*/
resourceName?: string; resourceName?: string;
/**
* @deprecated
*/
resourceIndex?: string; resourceIndex?: string;
/**
* @deprecated
*/
associatedName?: string; associatedName?: string;
/**
* @deprecated
*/
associatedIndex?: string; associatedIndex?: string;
[key: string]: any; [key: string]: any;
} }
@ -48,29 +55,49 @@ interface Resource {
} }
export class MockServer extends Application { export class MockServer extends Application {
agent(): SuperAgentTest & { resource: (name: string) => Resource } { async loadAndSync() {
await this.load();
await this.db.sync({
force: false,
alter: {
drop: false,
},
});
}
async cleanDb() {
await this.db.sequelize.getQueryInterface().dropAllTables();
}
agent(): SuperAgentTest & { resource: (name: string, resourceOf?: any) => Resource } {
const agent = supertest.agent(this.callback()); const agent = supertest.agent(this.callback());
const prefix = this.resourcer.options.prefix; const prefix = this.resourcer.options.prefix;
const proxy = new Proxy(agent, { const proxy = new Proxy(agent, {
get(target, method: string, receiver) { get(target, method: string, receiver) {
if (method === 'resource') { if (method === 'resource') {
return (name: string) => { return (name: string, resourceOf?: any) => {
const keys = name.split('.'); const keys = name.split('.');
const proxy = new Proxy( const proxy = new Proxy(
{}, {},
{ {
get(target, method: string, receiver) { get(target, method: string, receiver) {
return (params: ActionParams = {}) => { return (params: ActionParams = {}) => {
const { associatedIndex, resourceIndex, values = {}, file, ...restParams } = params; let { filterByTk, values = {}, file, ...restParams } = params;
if (params.associatedIndex) {
resourceOf = params.associatedIndex;
}
if (params.resourceIndex) {
filterByTk = params.resourceIndex;
}
let url = prefix; let url = prefix;
if (keys.length > 1) { if (keys.length > 1) {
url = `/${keys[0]}/${associatedIndex}/${keys[1]}`; url += `/${keys[0]}/${resourceOf}/${keys[1]}`;
} else { } else {
url = `/${name}`; url += `/${name}`;
} }
url += `:${method as string}`; url += `:${method as string}`;
if (resourceIndex) { if (filterByTk) {
url += `/${resourceIndex}`; url += `/${filterByTk}`;
} }
switch (method) { switch (method) {