import qs from 'qs'; import supertest, { SuperAgentTest } from 'supertest'; import Application, { ApplicationOptions } from '@nocobase/server'; import { getConfig } from './mockDatabase'; interface ActionParams { 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; } interface SortActionParams { resourceName?: string; resourceIndex?: any; associatedName?: string; associatedIndex?: any; sourceId?: any; targetId?: any; sortField?: string; method?: string; target?: any; sticky?: boolean; [key: string]: any; } interface Resource { get: (params?: ActionParams) => Promise; list: (params?: ActionParams) => Promise; create: (params?: ActionParams) => Promise; update: (params?: ActionParams) => Promise; destroy: (params?: ActionParams) => Promise; sort: (params?: SortActionParams) => Promise; [name: string]: (params?: ActionParams) => Promise; } export class MockServer extends Application { 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, resourceOf?: any) => { const keys = name.split('.'); const proxy = new Proxy( {}, { get(target, method: string, receiver) { return (params: ActionParams = {}) => { 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]}/${resourceOf}/${keys[1]}`; } else { url += `/${name}`; } url += `:${method as string}`; if (filterByTk) { url += `/${filterByTk}`; } 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; }; } return (...args: any[]) => { return agent[method](...args); }; }, }); return proxy as any; } } export function mockServer(options?: ApplicationOptions) { return new MockServer({ ...options, database: getConfig(options?.database), }); } export function createMockServer() {} export default mockServer;