feat: add @nocobase/test

This commit is contained in:
chenos 2021-09-09 13:09:25 +08:00
parent 3fa9e59093
commit 409eb38d00
9 changed files with 223 additions and 19 deletions

4
packages/test/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
node_modules
yarn-error.log
.env
src2

7
packages/test/.npmignore Normal file
View File

@ -0,0 +1,7 @@
node_modules
*.log
docs
__tests__
tsconfig.json
src
.fatherrc.ts

View File

@ -0,0 +1,18 @@
{
"name": "@nocobase/test",
"version": "0.4.0-alpha.7",
"main": "lib/index.js",
"types": "./lib/index.d.ts",
"license": "MIT",
"scripts": {},
"dependencies": {
"@nocobase/server": "^0.4.0-alpha.7",
"@types/supertest": "^2.0.11",
"mockjs": "^1.1.0",
"mysql2": "^2.1.0",
"pg": "^8.3.3",
"pg-hstore": "^2.3.3",
"supertest": "^6.1.6"
},
"gitHead": "f0b335ac30f29f25c95d7d137655fa64d8d67f1e"
}

View File

@ -0,0 +1,16 @@
import { mockDatabase } from "../";
describe('mock databasea', () => {
it('mock databasea', async () => {
const db = mockDatabase();
db.table({
name: 'tests',
fields: [
{ type: 'string', name: 'name' },
],
});
expect(db.getModel('tests').getTableName()).toBe('_test_mockDatabase_tests');
await db.sync();
await db.close();
});
});

View File

@ -0,0 +1,34 @@
import { mockServer, MockServer } from "../";
describe('mock server', () => {
let api: MockServer;
beforeEach(() => {
api = mockServer({
dataWrapping: false,
});
api.resourcer.registerActionHandlers({
list: async (ctx, next) => {
ctx.body = [1, 2];
await next();
},
});
api.resourcer.define({
name: 'test',
});
});
afterEach(async () => {
return api.destroy();
});
it('agent', async () => {
const response = await api.agent().get('/test');
expect(response.body).toEqual([1, 2]);
});
it('resource', async () => {
const response = await api.resource('test').list();
expect(response.body).toEqual([1, 2]);
});
});

View File

@ -0,0 +1,2 @@
export * from './mockDatabase';
export * from './mockServer';

View File

@ -0,0 +1,40 @@
import merge from 'deepmerge';
import Database, { DatabaseOptions } from '@nocobase/database';
export function generatePrefixByPath() {
const { id } = require.main;
const key = id
.replace(`${process.env.PWD}/packages`, '')
.replace(/src\/__tests__/g, '')
.replace('.test.ts', '')
.replace(/[^\w]/g, '_')
.replace(/_+/g, '_');
return key
}
export function getConfig(config = {}, options?: any): DatabaseOptions {
return merge({
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
host: process.env.DB_HOST,
port: process.env.DB_PORT,
dialect: process.env.DB_DIALECT,
logging: process.env.DB_LOG_SQL === 'on',
sync: {
force: true,
alter: {
drop: true,
},
},
hooks: {
beforeDefine(model, options) {
options.tableName = `${generatePrefixByPath()}_${options.tableName || options.name.plural}`;
},
},
}, config || {}, options) as any;
};
export function mockDatabase(options?: DatabaseOptions): Database {
return new Database(getConfig(options));
}

View File

@ -0,0 +1,74 @@
import qs from 'qs';
import supertest from 'supertest';
import Application, { ApplicationOptions } from '@nocobase/server';
import { ActionParams } from '@nocobase/resourcer';
import { getConfig } from './mockDatabase';
interface Resource {
get: (params?: ActionParams) => Promise<supertest.Response>;
list: (params?: ActionParams) => Promise<supertest.Response>;
create: (params?: ActionParams) => Promise<supertest.Response>;
update: (params?: ActionParams) => Promise<supertest.Response>;
destroy: (params?: ActionParams) => Promise<supertest.Response>;
[name: string]: (params?: ActionParams) => Promise<supertest.Response>;
}
export class MockServer extends Application {
agent() {
return supertest.agent(this.callback());
}
resource(name: string) {
const agent = this.agent();
const keys = name.split('.');
const prefix = this.resourcer.options.prefix;
const proxy = new Proxy({}, {
get(target, method: string, receiver) {
return (params: ActionParams = {}) => {
const {
associatedKey,
resourceKey,
values = {},
file,
...restParams
} = params;
let url = prefix;
if (keys.length > 1) {
url = `/${keys[0]}/${associatedKey}/${keys[1]}}`
} else {
url = `/${name}`;
}
url += `:${method as string}`;
if (resourceKey) {
url += `/${resourceKey}`;
}
console.log('request url: ' + url);
switch (method) {
case 'upload':
return agent
.post(`${url}?${qs.stringify(restParams)}`)
.attach('file', file)
.field(values);
case 'list':
case 'get':
return agent.get(`${url}?${qs.stringify(restParams)}`);
default:
return agent
.post(`${url}?${qs.stringify(restParams)}`)
.send(values);
}
};
},
});
return proxy as Resource;
}
}
export function mockServer(options?: ApplicationOptions) {
return new MockServer({
...options,
database: getConfig(options?.database),
});
}
export default mockServer;

View File

@ -3604,6 +3604,11 @@
resolved "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.4.tgz#de48cf01c79c9f1560bcfd8ae43217ab028657f8"
integrity sha512-0mPF08jn9zYI0n0Q/Pnz7C4kThdSt+6LD4amsrYDDpgBfrVWa3TcCOxKX1zkGgYniGagRv8heN2cbh+CAn+uuQ==
"@types/cookiejar@*":
version "2.1.2"
resolved "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.2.tgz#66ad9331f63fe8a3d3d9d8c6e3906dd10f6446e8"
integrity sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==
"@types/cookies@*":
version "0.7.7"
resolved "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.7.tgz#7a92453d1d16389c05a5301eef566f34946cfd81"
@ -4026,6 +4031,21 @@
resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==
"@types/superagent@*":
version "4.1.12"
resolved "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.12.tgz#fad68c6712936892ad24cf94f2f7a07cc749fd0f"
integrity sha512-1GQvD6sySQPD6p9EopDFI3f5OogdICl1sU/2ij3Esobz/RtL9fWZZDPmsuv7eiy5ya+XNiPAxUcI3HIUTJa+3A==
dependencies:
"@types/cookiejar" "*"
"@types/node" "*"
"@types/supertest@^2.0.11":
version "2.0.11"
resolved "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.11.tgz#2e70f69f220bc77b4f660d72c2e1a4231f44a77d"
integrity sha512-uci4Esokrw9qGb9bvhhSVEjd6rkny/dk5PK/Qz4yxKiyppEI+dOPlNrZBahE3i+PoKFYyDxChVXZ/ysS/nrm1Q==
dependencies:
"@types/superagent" "*"
"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3":
version "2.0.6"
resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
@ -7348,11 +7368,6 @@ dayjs@1.x, dayjs@^1.9.1:
resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.10.6.tgz#288b2aa82f2d8418a6c9d4df5898c0737ad02a63"
integrity sha512-AztC/IOW4L1Q41A86phW5Thhcrco3xuAA+YX/BLpLWWjRcTj5TOt/QImBLmCKlrF7u7k47arTnOyL6GnbG8Hvw==
debounce@^1.2.0:
version "1.2.1"
resolved "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5"
integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==
debug-fabulous@1.X:
version "1.1.0"
resolved "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz#af8a08632465224ef4174a9f06308c3c2a1ebc8e"
@ -7895,11 +7910,6 @@ dva@^2.6.0-beta.20:
react-router-dom "^5.1.2"
redux "^4.0.1"
easy-bem@^1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/easy-bem/-/easy-bem-1.1.1.tgz#1bfcc10425498090bcfddc0f9c000aba91399e03"
integrity sha512-GJRqdiy2h+EXy6a8E6R+ubmqUM08BK0FWNq41k24fup6045biQ8NXxoXimiwegMQvFFV3t1emADdGNL1TlS61A==
ecc-jsbn@~0.1.1:
version "0.1.2"
resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
@ -16250,15 +16260,6 @@ react-image-lightbox@^5.1.4:
prop-types "^15.7.2"
react-modal "^3.11.1"
react-indiana-drag-scroll@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/react-indiana-drag-scroll/-/react-indiana-drag-scroll-2.0.1.tgz#8785488a9e9c789b0e1c092e60d03f05a789d428"
integrity sha512-xZQXfFf9pHLOL6/AvTFiGZCB4Vu8wO8DjEaO+xRVkSki2bEZSFfS8eeKG0OkTzcYVrXzc5aHAD1Mfl3EG+EFMA==
dependencies:
classnames "^2.2.6"
debounce "^1.2.0"
easy-bem "^1.1.1"
react-intl@3.12.1:
version "3.12.1"
resolved "https://registry.npmjs.org/react-intl/-/react-intl-3.12.1.tgz#e9a783ea20302e9da25e4eda59e5593a43d2ec80"
@ -18447,6 +18448,14 @@ supertest@^6.1.3:
methods "^1.1.2"
superagent "^6.1.0"
supertest@^6.1.6:
version "6.1.6"
resolved "https://registry.npmjs.org/supertest/-/supertest-6.1.6.tgz#6151c518f4c5ced2ac2aadb9f96f1bf8198174c8"
integrity sha512-0hACYGNJ8OHRg8CRITeZOdbjur7NLuNs0mBjVhdpxi7hP6t3QIbOzLON5RTUmZcy2I9riuII3+Pr2C7yztrIIg==
dependencies:
methods "^1.1.2"
superagent "^6.1.0"
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"