feat: add @nocobase/test
This commit is contained in:
parent
3fa9e59093
commit
409eb38d00
4
packages/test/.gitignore
vendored
Normal file
4
packages/test/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
node_modules
|
||||||
|
yarn-error.log
|
||||||
|
.env
|
||||||
|
src2
|
7
packages/test/.npmignore
Normal file
7
packages/test/.npmignore
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
node_modules
|
||||||
|
*.log
|
||||||
|
docs
|
||||||
|
__tests__
|
||||||
|
tsconfig.json
|
||||||
|
src
|
||||||
|
.fatherrc.ts
|
18
packages/test/package.json
Normal file
18
packages/test/package.json
Normal 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"
|
||||||
|
}
|
16
packages/test/src/__tests__/mockDatabase.test.ts
Normal file
16
packages/test/src/__tests__/mockDatabase.test.ts
Normal 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();
|
||||||
|
});
|
||||||
|
});
|
34
packages/test/src/__tests__/mockServer.test.ts
Normal file
34
packages/test/src/__tests__/mockServer.test.ts
Normal 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]);
|
||||||
|
});
|
||||||
|
});
|
2
packages/test/src/index.ts
Normal file
2
packages/test/src/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './mockDatabase';
|
||||||
|
export * from './mockServer';
|
40
packages/test/src/mockDatabase.ts
Normal file
40
packages/test/src/mockDatabase.ts
Normal 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));
|
||||||
|
}
|
74
packages/test/src/mockServer.ts
Normal file
74
packages/test/src/mockServer.ts
Normal 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;
|
47
yarn.lock
47
yarn.lock
@ -3604,6 +3604,11 @@
|
|||||||
resolved "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.4.tgz#de48cf01c79c9f1560bcfd8ae43217ab028657f8"
|
resolved "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.4.tgz#de48cf01c79c9f1560bcfd8ae43217ab028657f8"
|
||||||
integrity sha512-0mPF08jn9zYI0n0Q/Pnz7C4kThdSt+6LD4amsrYDDpgBfrVWa3TcCOxKX1zkGgYniGagRv8heN2cbh+CAn+uuQ==
|
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@*":
|
"@types/cookies@*":
|
||||||
version "0.7.7"
|
version "0.7.7"
|
||||||
resolved "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.7.tgz#7a92453d1d16389c05a5301eef566f34946cfd81"
|
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"
|
resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
|
||||||
integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==
|
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":
|
"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3":
|
||||||
version "2.0.6"
|
version "2.0.6"
|
||||||
resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
|
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"
|
resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.10.6.tgz#288b2aa82f2d8418a6c9d4df5898c0737ad02a63"
|
||||||
integrity sha512-AztC/IOW4L1Q41A86phW5Thhcrco3xuAA+YX/BLpLWWjRcTj5TOt/QImBLmCKlrF7u7k47arTnOyL6GnbG8Hvw==
|
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:
|
debug-fabulous@1.X:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz#af8a08632465224ef4174a9f06308c3c2a1ebc8e"
|
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"
|
react-router-dom "^5.1.2"
|
||||||
redux "^4.0.1"
|
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:
|
ecc-jsbn@~0.1.1:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
|
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"
|
prop-types "^15.7.2"
|
||||||
react-modal "^3.11.1"
|
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:
|
react-intl@3.12.1:
|
||||||
version "3.12.1"
|
version "3.12.1"
|
||||||
resolved "https://registry.npmjs.org/react-intl/-/react-intl-3.12.1.tgz#e9a783ea20302e9da25e4eda59e5593a43d2ec80"
|
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"
|
methods "^1.1.2"
|
||||||
superagent "^6.1.0"
|
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:
|
supports-color@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
resolved "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||||
|
Loading…
Reference in New Issue
Block a user