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';
describe('add action', () => {
let app;
let app: MockServer;
let Post;
let Comment;
let Tag;
@ -80,9 +80,8 @@ describe('add action', () => {
const response = await app
.agent()
.resource('posts.tags')
.resource('posts.tags', p1.get('id'))
.add({
associatedIndex: p1.get('id'),
values: [t1.get('id'), t2.get('id')],
});
@ -91,9 +90,8 @@ describe('add action', () => {
// add with through values
await app
.agent()
.resource('posts.tags')
.resource('posts.tags', p1.get('id'))
.add({
associatedIndex: p1.get('id'),
values: [
[
t3.get('id'),

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -80,9 +80,8 @@ describe('toggle action', () => {
const response = await app
.agent()
.resource('posts.tags')
.resource('posts.tags', p1.get('id'))
.toggle({
associatedIndex: p1.get('id'),
values: [t1.get('id'), t2.get('id')],
});
@ -90,9 +89,8 @@ describe('toggle action', () => {
await app
.agent()
.resource('posts.tags')
.resource('posts.tags', p1.get('id'))
.toggle({
associatedIndex: p1.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';
describe('update action', () => {
let app;
let app: MockServer;
let Post;
let Comment;
let Tag;
@ -71,7 +71,7 @@ describe('update action', () => {
.agent()
.resource('posts')
.update({
resourceIndex: p1.get('id'),
filterByTk: p1.get('id'),
values: {
title: 'p0',
},
@ -97,10 +97,9 @@ describe('update action', () => {
const response = await app
.agent()
.resource('posts.comments')
.resource('posts.comments', p1.get('id'))
.update({
resourceIndex: c1.get('id'),
associatedIndex: p1.get('id'),
filterByTk: c1.get('id'),
values: {
content: 'c0',
},
@ -129,10 +128,9 @@ describe('update action', () => {
const response = await app
.agent()
.resource('posts.tags')
.resource('posts.tags', p1t1.get('id'))
.update({
resourceIndex: p1.get('id'),
associatedIndex: p1t1.get('id'),
filterByTk: p1.get('id'),
values: {
posts_tags: {
tagged_at: 'test',
@ -158,9 +156,8 @@ describe('update action', () => {
const response = await app
.agent()
.resource('posts.profile')
.resource('posts.profile', p1.get('id'))
.update({
associatedIndex: p1.get('id'),
values: {
post_profile: 'test0',
},

View File

@ -4,21 +4,28 @@ import Application, { ApplicationOptions } from '@nocobase/server';
import { getConfig } from './mockDatabase';
interface ActionParams {
fields?:
| string[]
| {
only?: string[];
except?: string[];
appends?: string[];
};
filterByTk?: any;
fields?: string[];
filter?: any;
sort?: string[];
page?: number;
perPage?: number;
values?: any;
/**
* @deprecated
*/
resourceName?: string;
/**
* @deprecated
*/
resourceIndex?: string;
/**
* @deprecated
*/
associatedName?: string;
/**
* @deprecated
*/
associatedIndex?: string;
[key: string]: any;
}
@ -48,29 +55,49 @@ interface Resource {
}
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 prefix = this.resourcer.options.prefix;
const proxy = new Proxy(agent, {
get(target, method: string, receiver) {
if (method === 'resource') {
return (name: string) => {
return (name: string, resourceOf?: any) => {
const keys = name.split('.');
const proxy = new Proxy(
{},
{
get(target, method: string, receiver) {
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;
if (keys.length > 1) {
url = `/${keys[0]}/${associatedIndex}/${keys[1]}`;
url += `/${keys[0]}/${resourceOf}/${keys[1]}`;
} else {
url = `/${name}`;
url += `/${name}`;
}
url += `:${method as string}`;
if (resourceIndex) {
url += `/${resourceIndex}`;
if (filterByTk) {
url += `/${filterByTk}`;
}
switch (method) {