test: add ut for render-core/utils/data-helper.ts

This commit is contained in:
JackLian 2022-05-30 16:47:33 +08:00 committed by 絮黎
parent bf280c6fa1
commit 171b1013b2
4 changed files with 731 additions and 172 deletions

View File

@ -1,3 +1,4 @@
/* eslint-disable max-len */
/* eslint-disable react/prop-types */
import classnames from 'classnames';
import { create as createDataSourceEngine } from '@alilc/lowcode-datasource-engine/interpret';
@ -154,8 +155,7 @@ export default function baseRendererFactory(): IBaseRenderComponent {
this.__showPlaceholder = false;
return resolve({});
}
this.__dataHelper
.getInitData()
this.__dataHelper.getInitData()
.then((res: any) => {
this.__showPlaceholder = false;
if (isEmpty(res)) {
@ -286,8 +286,7 @@ export default function baseRendererFactory(): IBaseRenderComponent {
// this.__showPlaceholder = false;
return resolve({});
}
this.__dataHelper
.getInitData()
this.__dataHelper.getInitData()
.then((res: any) => {
// this.__showPlaceholder = false;
if (isEmpty(res)) {

View File

@ -118,7 +118,7 @@ export function isJSSlot(obj: any): obj is JSSlot {
}
// Compatible with the old protocol JSBlock
return ([EXPRESSION_TYPE.JSSLOT, EXPRESSION_TYPE.JSBLOCK].includes(obj.type));
return [EXPRESSION_TYPE.JSSLOT, EXPRESSION_TYPE.JSBLOCK].includes(obj.type);
}
/**

View File

@ -1,9 +1,11 @@
/* eslint-disable no-console */
/* eslint-disable max-len */
/* eslint-disable object-curly-newline */
import { isJSFunction } from '@alilc/lowcode-types';
import { transformArrayToMap, transformStringToFunction, clone } from './common';
import { transformArrayToMap, transformStringToFunction } from './common';
import { jsonp, request, get, post } from './request';
import { DataSource, DataSourceItem } from '../types';
import logger from './logger';
import { DataSource, DataSourceItem, IRendererAppHelper } from '../types';
const DS_STATUS = {
INIT: 'init',
@ -12,22 +14,77 @@ const DS_STATUS = {
ERROR: 'error',
};
type DataSourceType = 'fetch' | 'jsonp';
/**
* do request for standard DataSourceType
* @param {DataSourceType} type type of DataSourceItem
* @param {any} options
*/
export function doRequest(type: DataSourceType, options: any) {
// eslint-disable-next-line prefer-const
let { uri, url, method = 'GET', headers, params, ...otherProps } = options;
otherProps = otherProps || {};
if (type === 'jsonp') {
return jsonp(uri, params, otherProps);
}
if (type === 'fetch') {
switch (method.toUpperCase()) {
case 'GET':
return get(uri, params, headers, otherProps);
case 'POST':
return post(uri, params, headers, otherProps);
default:
return request(uri, method, params, headers, otherProps);
}
}
logger.log(`Engine default dataSource does not support type:[${type}] dataSource request!`, options);
}
// TODO: according to protocol, we should implement errorHandler/shouldFetch/willFetch/requestHandler and isSync controll.
export class DataHelper {
/**
* host object that will be "this" object when excuting dataHandler
*
* @type {*}
* @memberof DataHelper
*/
host: any;
/**
* data source config
*
* @type {DataSource}
* @memberof DataHelper
*/
config: DataSource;
/**
* a parser function which will be called to process config data
* which eventually will call common/utils.processData() to process data
* (originalConfig) => parsedConfig
* @type {*}
* @memberof DataHelper
*/
parser: any;
/**
* config.list
*
* @type {any[]}
* @memberof DataHelper
*/
ajaxList: any[];
ajaxMap: any;
dataSourceMap: any;
appHelper: any;
appHelper: IRendererAppHelper;
constructor(comp: any, config: DataSource, appHelper: any, parser: any) {
constructor(comp: any, config: DataSource, appHelper: IRendererAppHelper, parser: any) {
this.host = comp;
this.config = config || {};
this.parser = parser;
@ -37,15 +94,6 @@ export class DataHelper {
this.appHelper = appHelper;
}
// 重置configdataSourceMap状态会被重置
resetConfig(config = {}) {
this.config = config as DataSource;
this.ajaxList = (config as DataSource)?.list || [];
this.ajaxMap = transformArrayToMap(this.ajaxList, 'id');
this.dataSourceMap = this.generateDataSourceMap();
return this.dataSourceMap;
}
// 更新config只会更新配置状态保存
updateConfig(config = {}) {
this.config = config as DataSource;
@ -79,6 +127,7 @@ export class DataHelper {
res[item.id] = {
status: DS_STATUS.INIT,
load: (...args: any) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return this.getDataSource(item.id, ...args);
},
@ -93,41 +142,54 @@ export class DataHelper {
this.dataSourceMap[id].status = error ? DS_STATUS.ERROR : DS_STATUS.LOADED;
}
getInitData() {
const initSyncData = this.parser(this.ajaxList).filter((item: DataSourceItem) => {
if (item.isInit) {
/**
* get all dataSourceItems which marked as isInit === true
* @private
* @returns
* @memberof DataHelper
*/
getInitDataSourseConfigs() {
const initConfigs = this.parser(this.ajaxList).filter((item: DataSourceItem) => {
// according to [spec](https://lowcode-engine.cn/lowcode), isInit should be boolean true to be working
if (item.isInit === true) {
this.dataSourceMap[item.id].status = DS_STATUS.LOADING;
return true;
}
return false;
});
return initConfigs;
}
/**
* process all dataSourceItems which marked as isInit === true, and get dataSource request results.
* @public
* @returns
* @memberof DataHelper
*/
getInitData() {
const initSyncData = this.getInitDataSourseConfigs();
// 所有 datasource 的 datahandler
return this.asyncDataHandler(initSyncData).then((res) => {
let { dataHandler } = this.config;
if (isJSFunction(dataHandler)) {
dataHandler = transformStringToFunction(dataHandler.value);
}
if (!dataHandler || typeof dataHandler !== 'function') return res;
try {
return (dataHandler as any).call(this.host, res);
} catch (e) {
console.error('请求数据处理函数运行出错', e);
}
const { dataHandler } = this.config;
return this.handleData(null, dataHandler, res, null);
});
}
getDataSource(id: string, params: any, otherOptions: any, callback: any) {
const req = this.parser(this.ajaxMap[id]);
const options = req.options || {};
let callbackFn = callback;
let otherOptionsObj = otherOptions;
if (typeof otherOptions === 'function') {
callback = otherOptions;
otherOptions = {};
callbackFn = otherOptions;
otherOptionsObj = {};
}
const { headers, ...otherProps } = otherOptions || {};
const { headers, ...otherProps } = otherOptionsObj || {};
if (!req) {
console.warn(`getDataSource API named ${id} not exist`);
return;
}
return this.asyncDataHandler([
{
...req,
@ -149,170 +211,99 @@ export class DataHelper {
},
},
])
.then((res: any) => {
try {
callback && callback(res && res[id]);
} catch (e) {
console.error('load请求回调函数报错', e);
}
return res && res[id];
})
.catch((err) => {
try {
callback && callback(null, err);
} catch (e) {
console.error('load请求回调函数报错', e);
}
return err;
});
.then((res: any) => {
try {
callbackFn && callbackFn(res && res[id]);
} catch (e) {
console.error('load请求回调函数报错', e);
}
return res && res[id];
})
.catch((err) => {
try {
callbackFn && callbackFn(null, err);
} catch (e) {
console.error('load请求回调函数报错', e);
}
return err;
});
}
asyncDataHandler(asyncDataList: any[]) {
return new Promise((resolve, reject) => {
const allReq = [];
const doserReq: Array<{name: string; package: string; params: any }> = [];
const doserList: string[] = [];
const beforeRequest = this.appHelper && this.appHelper.utils && this.appHelper.utils.beforeRequest;
const afterRequest = this.appHelper && this.appHelper.utils && this.appHelper.utils.afterRequest;
const csrfInput = document.getElementById('_csrf_token');
const _tb_token_ = (csrfInput as any)?.value;
const allReq: any[] = [];
asyncDataList.forEach((req) => {
const { id, type, options } = req;
if (!id || !type || type === 'legao') return;
if (type === 'doServer') {
const { uri, params } = options || {};
if (!uri) return;
doserList.push(id);
doserReq.push({ name: uri, package: 'cms', params });
} else {
allReq.push(req);
const { id, type } = req;
// TODO: need refactoring to remove 'legao' related logic
if (!id || !type || type === 'legao') {
return;
}
allReq.push(req);
});
if (doserReq.length > 0) {
allReq.push({
type: 'doServer',
options: {
uri: '/nrsService.do',
cors: true,
method: 'POST',
params: {
data: JSON.stringify(doserReq),
_tb_token_,
},
},
});
if (allReq.length === 0) {
resolve({});
}
if (allReq.length === 0) resolve({});
const res: any = {};
// todo:
Promise.all(
allReq.map((item: any) => {
return new Promise((resolve) => {
return new Promise((innerResolve) => {
const { type, id, dataHandler, options } = item;
const doFetch = (type: string, options: any) => {
this.fetchOne(type as any, options)
?.then((data: any) => {
if (afterRequest) {
this.appHelper.utils.afterRequest(item, data, undefined, (data: any, error: any) => {
fetchHandler(data, error);
});
} else {
fetchHandler(data, undefined);
}
})
.catch((err: Error) => {
if (afterRequest) {
// 必须要这么调用否则beforeRequest中的this会丢失
this.appHelper.utils.afterRequest(item, undefined, err, (data: any, error: any) => {
fetchHandler(data, error);
});
} else {
fetchHandler(undefined, err);
}
});
};
const fetchHandler = (data: any, error: any) => {
if (type === 'doServer') {
if (!Array.isArray(data)) {
data = [data];
}
doserList.forEach((id, idx) => {
const req: any = this.ajaxMap[id];
if (req) {
res[id] = this.dataHandler(id, req.dataHandler, data && data[idx], error);
this.updateDataSourceMap(id, res[id], error);
}
});
} else {
res[id] = this.dataHandler(id, dataHandler, data, error);
this.updateDataSourceMap(id, res[id], error);
}
resolve({});
res[id] = this.handleData(id, dataHandler, data, error);
this.updateDataSourceMap(id, res[id], error);
innerResolve({});
};
if (type === 'doServer') {
doserList.forEach((item) => {
this.dataSourceMap[item].status = DS_STATUS.LOADING;
});
} else {
this.dataSourceMap[id].status = DS_STATUS.LOADING;
}
// 请求切片
if (beforeRequest) {
// 必须要这么调用否则beforeRequest中的this会丢失
this.appHelper.utils.beforeRequest(item, clone(options), (options: any) => doFetch(type, options));
} else {
doFetch(type, options);
}
const doFetch = (innerType: string, innerOptions: any) => {
doRequest(innerType as any, innerOptions)
?.then((data: any) => {
fetchHandler(data, undefined);
})
.catch((err: Error) => {
fetchHandler(undefined, err);
});
};
this.dataSourceMap[id].status = DS_STATUS.LOADING;
doFetch(type, options);
});
}),
)
.then(() => {
resolve(res);
})
.catch((e) => {
reject(e);
});
).then(() => {
resolve(res);
}).catch((e) => {
reject(e);
});
});
}
// dataHandler todo:
dataHandler(id: string, dataHandler: any, data: any, error: any) {
/**
* process data using dataHandler
*
* @param {(string | null)} id request id, will be used in error message, can be null
* @param {*} dataHandler
* @param {*} data
* @param {*} error
* @returns
* @memberof DataHelper
*/
handleData(id: string | null, dataHandler: any, data: any, error: any) {
let dataHandlerFun = dataHandler;
if (isJSFunction(dataHandler)) {
dataHandler = transformStringToFunction(dataHandler.value);
dataHandlerFun = transformStringToFunction(dataHandler.value);
}
if (!dataHandlerFun || typeof dataHandlerFun !== 'function') {
return data;
}
if (!dataHandler || typeof dataHandler !== 'function') return data;
try {
return dataHandler.call(this.host, data, error);
return dataHandlerFun.call(this.host, data, error);
} catch (e) {
console.error(`[${ id }]单个请求数据处理函数运行出错`, e);
}
}
fetchOne(type: DataSourceType, options: any) {
// eslint-disable-next-line prefer-const
let { uri, url, method = 'GET', headers, params, ...otherProps } = options;
otherProps = otherProps || {};
if (type === 'jsonp') {
return jsonp(uri, params, otherProps);
}
if (type === 'fetch') {
switch (method.toUpperCase()) {
case 'GET':
return get(uri, params, headers, otherProps);
case 'POST':
return post(uri, params, headers, otherProps);
default:
return request(uri, method, params, headers, otherProps);
if (id) {
console.error(`[${id}]单个请求数据处理函数运行出错`, e);
} else {
console.error('请求数据处理函数运行出错', e);
}
}
logger.log(`Engine default dataSource not support type:[${type}] dataSource request!`, options);
}
}
type DataSourceType = 'fetch' | 'jsonp';

View File

@ -0,0 +1,569 @@
// @ts-nocheck
const mockJsonp = jest.fn();
const mockRequest = jest.fn();
const mockGet = jest.fn();
const mockPost = jest.fn();
jest.mock('../../src/utils/request', () => {
return {
jsonp: (uri, params, headers, otherProps) => {
return new Promise((resolve, reject) => {
resolve(mockJsonp(uri, params, headers, otherProps));
});
},
request: (uri, params, headers, otherProps) => {
return new Promise((resolve, reject) => {
resolve(mockRequest(uri, params, headers, otherProps));
});
},
get: (uri, params, headers, otherProps) => {
return new Promise((resolve, reject) => {
resolve(mockGet(uri, params, headers, otherProps));
});
},
post: (uri, params, headers, otherProps) => {
return new Promise((resolve, reject) => {
resolve(mockPost(uri, params, headers, otherProps));
});
},
};
});
import { DataHelper, doRequest } from '../../src/utils/data-helper';
import { parseData } from '../../src/utils/common';
describe('test DataHelper ', () => {
beforeEach(() => {
jest.resetModules();
})
it('can be inited', () => {
const mockHost = {};
let mockDataSourceConfig = {};
const mockAppHelper = {};
const mockParser = (config: any) => parseData(config);
let dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser);
expect(dataHelper).toBeTruthy();
expect(dataHelper.host).toBe(mockHost);
expect(dataHelper.config).toBe(mockDataSourceConfig);
expect(dataHelper.appHelper).toBe(mockAppHelper);
expect(dataHelper.parser).toBe(mockParser);
dataHelper = new DataHelper(mockHost, undefined, mockAppHelper, mockParser);
expect(dataHelper.config).toStrictEqual({});
expect(dataHelper.ajaxList).toStrictEqual([]);
mockDataSourceConfig = {
list: [
{
id: 'ds1',
}, {
id: 'ds2',
},
]
};
dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser);
expect(dataHelper.config).toBe(mockDataSourceConfig);
expect(dataHelper.ajaxList.length).toBe(2);
expect(dataHelper.ajaxMap.ds1).toStrictEqual({
id: 'ds1',
});
});
it('should handle generateDataSourceMap properly in constructor', () => {
const mockHost = {};
let mockDataSourceConfig = {};
const mockAppHelper = {};
const mockParser = (config: any) => parseData(config);
let dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser);
// test generateDataSourceMap logic
mockDataSourceConfig = {
list: [
{
id: 'getInfo',
isInit: true,
type: 'fetch', // fetch/mtop/jsonp/custom
options: {
uri: 'mock/info.json',
method: 'GET',
params: { a: 1 },
timeout: 5000,
},
}, {
id: 'postInfo',
isInit: true,
type: 'fetch',
options: {
uri: 'mock/info.json',
method: 'POST',
params: { a: 1 },
timeout: 5000,
},
},
]
};
dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser);
expect(Object.keys(dataHelper.dataSourceMap).length).toBe(2);
expect(dataHelper.dataSourceMap.getInfo.status).toBe('init');
expect(typeof dataHelper.dataSourceMap.getInfo.load).toBe('function');
});
it('getInitDataSourseConfigs should work', () => {
const mockHost = {};
let mockDataSourceConfig = {};
const mockAppHelper = {};
const mockParser = (config: any) => parseData(config);
// test generateDataSourceMap logic
mockDataSourceConfig = {
list: [
{
id: 'getInfo',
isInit: true,
type: 'fetch', // fetch/mtop/jsonp/custom
options: {
uri: 'mock/info.json',
method: 'GET',
params: { a: 1 },
timeout: 5000,
},
},
{
id: 'postInfo',
isInit: false,
type: 'fetch',
options: {
uri: 'mock/info.json',
method: 'POST',
params: { a: 1 },
timeout: 5000,
},
},
{
id: 'getInfoLater',
isInit: false,
type: 'fetch',
options: {
uri: 'mock/info.json',
method: 'POST',
params: { a: 1 },
timeout: 5000,
},
},
{
id: 'getInfoLater2',
isInit: 'not a valid boolean',
type: 'fetch',
options: {
uri: 'mock/info.json',
method: 'POST',
params: { a: 1 },
timeout: 5000,
},
},
],
};
const dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser);
expect(dataHelper.getInitDataSourseConfigs().length).toBe(1);
expect(dataHelper.getInitDataSourseConfigs()[0].id).toBe('getInfo');
});
it('util function doRequest should work', () => {
doRequest('jsonp', {
uri: 'https://www.baidu.com',
params: { a: 1 },
otherStuff1: 'aaa',
});
expect(mockJsonp).toBeCalled();
// test GET
doRequest('fetch', {
uri: 'https://www.baidu.com',
method: 'get',
params: { a: 1 },
otherStuff1: 'aaa',
});
expect(mockGet).toBeCalled();
mockGet.mockClear();
doRequest('fetch', {
uri: 'https://www.baidu.com',
method: 'Get',
params: { a: 1 },
otherStuff1: 'aaa',
});
expect(mockGet).toBeCalled();
mockGet.mockClear();
doRequest('fetch', {
uri: 'https://www.baidu.com',
method: 'GET',
params: { a: 1 },
otherStuff1: 'aaa',
});
expect(mockGet).toBeCalled();
mockGet.mockClear();
// test POST
doRequest('fetch', {
uri: 'https://www.baidu.com',
method: 'post',
params: { a: 1 },
otherStuff1: 'aaa',
});
expect(mockPost).toBeCalled();
mockPost.mockClear();
doRequest('fetch', {
uri: 'https://www.baidu.com',
method: 'POST',
params: { a: 1 },
otherStuff1: 'aaa',
});
expect(mockPost).toBeCalled();
mockPost.mockClear();
doRequest('fetch', {
uri: 'https://www.baidu.com',
method: 'Post',
params: { a: 1 },
otherStuff1: 'aaa',
});
expect(mockPost).toBeCalled();
mockPost.mockClear();
// test default
doRequest('fetch', {
uri: 'https://www.baidu.com',
method: 'whatever',
params: { a: 1 },
otherStuff1: 'aaa',
});
expect(mockRequest).toBeCalled();
mockRequest.mockClear();
mockGet.mockClear();
// method will be GET when not provided
doRequest('fetch', {
uri: 'https://www.baidu.com',
params: { a: 1 },
otherStuff1: 'aaa',
});
expect(mockRequest).toBeCalledTimes(0);
expect(mockGet).toBeCalledTimes(1);
mockRequest.mockClear();
mockGet.mockClear();
mockPost.mockClear();
mockJsonp.mockClear();
doRequest('someOtherType', {
uri: 'https://www.baidu.com',
params: { a: 1 },
otherStuff1: 'aaa',
});
expect(mockRequest).toBeCalledTimes(0);
expect(mockGet).toBeCalledTimes(0);
expect(mockPost).toBeCalledTimes(0);
expect(mockJsonp).toBeCalledTimes(0);
});
it('updateDataSourceMap should work', () => {
const mockHost = {};
const mockDataSourceConfig = {
list: [
{
id: 'ds1',
}, {
id: 'ds2',
},
]
};
const mockAppHelper = {};
const mockParser = (config: any) => parseData(config);
const dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser);
dataHelper.updateDataSourceMap('ds1', { a: 1 }, null);
expect(dataHelper.dataSourceMap['ds1']).toBeTruthy();
expect(dataHelper.dataSourceMap['ds1'].data).toStrictEqual({ a: 1 });
expect(dataHelper.dataSourceMap['ds1'].error).toBeUndefined();
expect(dataHelper.dataSourceMap['ds1'].status).toBe('loaded');
dataHelper.updateDataSourceMap('ds2', { b: 2 }, new Error());
expect(dataHelper.dataSourceMap['ds2']).toBeTruthy();
expect(dataHelper.dataSourceMap['ds2'].data).toStrictEqual({ b: 2 });
expect(dataHelper.dataSourceMap['ds2'].status).toBe('error');
expect(dataHelper.dataSourceMap['ds2'].error).toBeTruthy();
});
it('handleData should work', () => {
const mockHost = { stateA: 'aValue'};
const mockDataSourceConfig = {
list: [
{
id: 'fullConfigGet',
isInit: true,
options: {
params: {},
method: 'GET',
isCors: true,
timeout: 5000,
headers: {},
uri: 'mock/info.json',
},
shouldFetch: {
type: 'JSFunction',
value: 'function() { return true; }',
},
dataHandler: {
type: 'JSFunction',
value: 'function(res) { return res.data; }',
},
errorHandler: {
type: 'JSFunction',
value: 'function(error) {}',
},
willFetch: {
type: 'JSFunction',
value: 'function(options) { return options; }',
},
},
]
};
const mockAppHelper = {};
const mockParser = (config: any) => parseData(config);
const dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser);
// test valid case
let mockDataHandler = {
type: 'JSFunction',
value: 'function(res) { return res.data + \'+\' + this.stateA; }',
};
let result = dataHelper.handleData('fullConfigGet', mockDataHandler, { data: 'mockDataValue' }, null);
expect(result).toBe('mockDataValue+aValue');
// test invalid datahandler
mockDataHandler = {
type: 'not a JSFunction',
value: 'function(res) { return res.data + \'+\' + this.stateA; }',
};
result = dataHelper.handleData('fullConfigGet', mockDataHandler, { data: 'mockDataValue' }, null);
expect(result).toStrictEqual({ data: 'mockDataValue' });
// test exception
const mockError = jest.fn();
const orginalConsole = global.console;
global.console = { error: mockError };
// exception with id
mockDataHandler = {
type: 'JSFunction',
value: 'function(res) { return res.data + \'+\' + JSON.parse({a:1}); }',
};
result = dataHelper.handleData('fullConfigGet', mockDataHandler, { data: 'mockDataValue' }, null);
expect(result).toBeUndefined();
expect(mockError).toBeCalledWith('[fullConfigGet]单个请求数据处理函数运行出错', expect.anything());
// exception without id
mockDataHandler = {
type: 'JSFunction',
value: 'function(res) { return res.data + \'+\' + JSON.parse({a:1}); }',
};
result = dataHelper.handleData(null, mockDataHandler, { data: 'mockDataValue' }, null);
expect(result).toBeUndefined();
expect(mockError).toBeCalledWith('请求数据处理函数运行出错', expect.anything());
global.console = orginalConsole;
});
it('updateConfig should work', () => {
const mockHost = { stateA: 'aValue'};
const mockDataSourceConfig = {
list: [
{
id: 'ds1',
}, {
id: 'ds2',
},
{
id: 'fullConfigGet',
isInit: true,
options: {
params: {},
method: 'GET',
isCors: true,
timeout: 5000,
headers: {},
uri: 'mock/info.json',
},
shouldFetch: {
type: 'JSFunction',
value: 'function() { return true; }',
},
dataHandler: {
type: 'JSFunction',
value: 'function(res) { return res.data; }',
},
errorHandler: {
type: 'JSFunction',
value: 'function(error) {}',
},
willFetch: {
type: 'JSFunction',
value: 'function(options) { return options; }',
},
},
]
};
const mockAppHelper = {};
const mockParser = (config: any) => parseData(config);
const dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser);
expect(dataHelper.ajaxList.length).toBe(3);
let updatedConfig = {
list: [
{
id: 'ds2',
},
{
id: 'fullConfigGet',
},
]
};
dataHelper.updateConfig(updatedConfig);
expect(dataHelper.ajaxList.length).toBe(2);
expect(dataHelper.dataSourceMap.ds1).toBeUndefined();
updatedConfig = {
list: [
{
id: 'ds2',
},
{
id: 'fullConfigGet',
},
{
id: 'ds3',
},
]
};
dataHelper.updateConfig(updatedConfig);
expect(dataHelper.ajaxList.length).toBe(3);
expect(dataHelper.dataSourceMap.ds3).toBeTruthy();
});
it('getInitData should work', () => {
const mockHost = { stateA: 'aValue'};
const mockDataSourceConfig = {
list: [
{
id: 'ds1',
}, {
id: 'ds2',
},
{
id: 'fullConfigGet',
isInit: true,
type: 'fetch',
options: {
params: {},
method: 'GET',
isCors: true,
timeout: 5000,
headers: {
headerA: 1,
},
uri: 'mock/info.json',
},
shouldFetch: {
type: 'JSFunction',
value: 'function() { return true; }',
},
dataHandler: {
type: 'JSFunction',
value: 'function(res) { return 123; }',
},
errorHandler: {
type: 'JSFunction',
value: 'function(error) {}',
},
willFetch: {
type: 'JSFunction',
value: 'function(options) { return options; }',
},
},
]
};
const mockAppHelper = {};
const mockParser = (config: any) => parseData(config);
const dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser);
expect(dataHelper.ajaxList.length).toBe(3);
expect(mockGet).toBeCalledTimes(0);
dataHelper.getInitData().then(res => {
expect(mockGet).toBeCalledTimes(1);
expect(mockGet).toBeCalledWith('mock/info.json', {}, {
headerA: 1,
}, expect.anything());
mockGet.mockClear();
});
});
it('getDataSource should work', () => {
const mockHost = { stateA: 'aValue'};
const mockDataSourceConfig = {
list: [
{
id: 'ds1',
}, {
id: 'ds2',
},
{
id: 'fullConfigGet',
isInit: true,
type: 'fetch',
options: {
params: {},
method: 'GET',
isCors: true,
timeout: 5000,
headers: {
headerA: 1,
},
uri: 'mock/info.json',
},
shouldFetch: {
type: 'JSFunction',
value: 'function() { return true; }',
},
dataHandler: {
type: 'JSFunction',
value: 'function(res) { return 123; }',
},
errorHandler: {
type: 'JSFunction',
value: 'function(error) {}',
},
willFetch: {
type: 'JSFunction',
value: 'function(options) { return options; }',
},
},
]
};
const mockAppHelper = {};
const mockParser = (config: any) => parseData(config);
const dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser);
expect(dataHelper.ajaxList.length).toBe(3);
expect(mockGet).toBeCalledTimes(0);
const callbackFn = jest.fn();
dataHelper.getDataSource('fullConfigGet', { param1: 'value1' }, {}, callbackFn).then(res => {
expect(mockGet).toBeCalledTimes(1);
expect(mockGet).toBeCalledWith('mock/info.json', { param1: 'value1' }, {
headerA: 1,
}, expect.anything());
mockGet.mockClear();
expect(callbackFn).toBeCalledTimes(1);
});
});
});