Skip to content

Commit 5111587

Browse files
committed
Support proxy other server
* Using pathToRgexp instead pure regexp
1 parent 8bac458 commit 5111587

File tree

4 files changed

+62
-5
lines changed

4 files changed

+62
-5
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"mocha": "^4.0.1"
4444
},
4545
"dependencies": {
46-
"mockjs": "^1.0.1-beta3"
46+
"mockjs": "^1.0.1-beta3",
47+
"path-to-regexp": "^2.1.0"
4748
}
4849
}

src/index.js

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import pathToRegexp from 'path-to-regexp';
12
import { parseRequest, matchUrl, isNull } from './util';
23
import Response from './response';
34

45
class FetchMock {
56
constructor(required, options = {
67
fetch: () => {},
78
exclude: [],
9+
proxy: [],
810
}) {
911
if ('object' !== typeof required) {
1012
throw new Error('There is no required defined.');
@@ -13,10 +15,13 @@ class FetchMock {
1315
this.urls = [];
1416
this.raw = options.fetch;
1517
this.exclude = options.exclude;
18+
this.proxy = options.proxy;
1619

1720
this.loadMocks = this.loadMocks.bind(this);
1821
this.loadMock = this.loadMock.bind(this);
1922
this.matchReqUrl = this.matchReqUrl.bind(this);
23+
this.isExclude = this.isExclude.bind(this);
24+
this.isProxied = this.isProxied.bind(this);
2025
this.fetch = this.fetch.bind(this);
2126

2227
this.loadMocks(required);
@@ -60,7 +65,7 @@ class FetchMock {
6065
}
6166
return false;
6267
});
63-
if (!filters || filters.length == 0) throw new Error(`No url ${url} is defined.`);
68+
if (!filters || filters.length == 0) throw new Error(`No url ${request.url} is defined.`);
6469
request.urlparams = insideParams;
6570
return {
6671
request,
@@ -71,14 +76,42 @@ class FetchMock {
7176
isExclude(url) {
7277
for (let i = 0; i < this.exclude.length; i++) {
7378
const excludeUrl = this.exclude[i];
74-
if (excludeUrl === url || (excludeUrl instanceof RegExp && excludeUrl.exec(url) !== null)) {
79+
if (excludeUrl === url || pathToRegexp(`${excludeUrl}`).exec(url) !== null) {
7580
return true;
7681
}
7782
}
7883
return false;
7984
}
8085

86+
isProxied(url) {
87+
if (this.proxy.length === 0) return false;
88+
const proxied = this.proxy.filter(item => pathToRegexp(`${item.path}`).exec(url) !== null);
89+
if (proxied.length > 1) throw new Error(`${url} proxied has two proxies, you should specific only one`);
90+
91+
return proxied[0];
92+
}
93+
94+
proxied(url) {
95+
// get proxied info
96+
let matches, proxied;
97+
this.proxy.forEach(item => {
98+
const tmp = pathToRegexp(item.path).exec(url);
99+
if (tmp.length > 1) {
100+
matches = tmp;
101+
proxied = item;
102+
return false;
103+
}
104+
});
105+
106+
return proxied.process ? proxied.process(proxied, matches) : `${proxied.target}/${matches[1]}`;
107+
}
108+
81109
fetch(url, options) {
110+
// using proxy
111+
if (this.isProxied(url)) {
112+
url = this.proxied(url);
113+
}
114+
82115
// using raw fetch while match exclude
83116
if (this.isExclude(url)) {
84117
// using raw fetch

test/index.test.js

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,17 @@ import FetchMock, { Mock } from '../';
55
const fetch = new FetchMock(require('../__mocks__'), {
66
fetch: require('isomorphic-fetch'),
77
exclude: [
8-
/^foo(bar)?$/i,
9-
/http:\/\/www.baidu.com/,
8+
'/foo/boo/:foo*',
9+
'http://:foo*',
10+
'https://:foo*',
1011
],
12+
proxy: [{
13+
path: '/taobao/search(.*)',
14+
target: 'https://suggest.taobao.com/sug',
15+
process: ({ target }, matches) => {
16+
return `${target}${matches[1]}`
17+
}
18+
}],
1119
}).fetch;
1220
describe('test fetch mock', () => {
1321
it('fetch /api/users data', async () => {
@@ -146,4 +154,15 @@ describe('test fetch mock', () => {
146154
expect(data).to.be.an('object');
147155
expect(data.userId).to.be.eql(123);
148156
});
157+
158+
it('proxy other api server', async () => {
159+
const response = await fetch('/taobao/search?code=utf-8&q=dongxi');
160+
const { status } = response;
161+
const data = await response.json();
162+
expect(status).to.be.eql(200);
163+
expect(data).not.to.be(undefined);
164+
expect(data).not.to.be.empty();
165+
expect(data).to.be.an('object');
166+
expect(data.result).to.be.an('array');
167+
});
149168
});

yarn.lock

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2003,6 +2003,10 @@ path-is-inside@^1.0.1, path-is-inside@^1.0.2:
20032003
version "1.0.2"
20042004
resolved "http://registry.npm.taobao.org/path-is-inside/download/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
20052005

2006+
path-to-regexp@^2.1.0:
2007+
version "2.1.0"
2008+
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-2.1.0.tgz#7e30f9f5b134bd6a28ffc2e3ef1e47075ac5259b"
2009+
20062010
performance-now@^0.2.0:
20072011
version "0.2.0"
20082012
resolved "http://registry.npm.taobao.org/performance-now/download/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"

0 commit comments

Comments
 (0)