Skip to content

Commit 2413f7b

Browse files
authored
Merge pull request #956 from wheresrhys/rhys/host-matcher
Rhys/host matcher
2 parents 661b98f + 32fdb1b commit 2413f7b

File tree

6 files changed

+61
-38
lines changed

6 files changed

+61
-38
lines changed

.github/ISSUE_TEMPLATE/new-issue.md

Lines changed: 0 additions & 36 deletions
This file was deleted.

docs/docs/API/route/matcher.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ Match a url ending with a string, e.g. `"end:.jpg"`
5656

5757
Match a url including a string, e.g. `"include:site.com/api"`
5858

59+
### host:...
60+
61+
`{String}`
62+
63+
Match a url which has a given host, e.g. `"host:a.b.com"`
64+
5965
### path:...
6066

6167
`{String}`

docs/docs/Usage/quickstart.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ You can use the names you gave your routes to check if they have been called.
4949

5050
```js
5151
assert(fetchMock.callHistory.called('good get'));
52-
assert(fetchMock.callHistory.lastCall('good get').queryParams.get('search'), 'needle');
52+
assert(
53+
fetchMock.callHistory.lastCall('good get').queryParams.get('search'),
54+
'needle',
55+
);
5356
```
5457

5558
## Tearing down your mock

packages/fetch-mock/src/Matchers.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@ import glob from 'glob-to-regexp';
44
import * as regexparam from 'regexparam';
55
import { isSubsetOf } from './IsSubsetOf.js';
66
import { dequal as isEqual } from 'dequal';
7-
import { normalizeHeaders, getPath, normalizeUrl } from './RequestUtils.js';
7+
import {
8+
normalizeHeaders,
9+
getPath,
10+
getHost,
11+
normalizeUrl,
12+
} from './RequestUtils.js';
813

914
export type URLMatcherObject = {
1015
begin?: string;
1116
end?: string;
1217
include?: string;
1318
glob?: string;
1419
express?: string;
20+
host?: string;
1521
path?: string;
1622
regexp?: RegExp;
1723
};
@@ -80,6 +86,9 @@ const stringMatchers: { [key: string]: UrlMatcherGenerator } = {
8086
return path === targetString || path === dotlessTargetString;
8187
};
8288
},
89+
host: (targetString) => {
90+
return ({ url }) => targetString === getHost(url);
91+
},
8392
};
8493
const getHeaderMatcher: MatcherGenerator = ({ headers: expectedHeaders }) => {
8594
if (!expectedHeaders) {

packages/fetch-mock/src/RequestUtils.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,15 @@ export function getPath(url: string): string {
125125
return u.pathname;
126126
}
127127

128+
export function getHost(url: string): string | null {
129+
if (absoluteUrlRX.test(url)) {
130+
return new URL(url).host;
131+
} else if ('location' in globalThis) {
132+
return globalThis.location.host;
133+
}
134+
return null;
135+
}
136+
128137
export function getQuery(url: string): string {
129138
const u = absoluteUrlRX.test(url)
130139
? new URL(url)

packages/fetch-mock/src/__tests__/Matchers/url.test.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,18 @@ describe('url matching', () => {
3939
expect(route.matcher({ url: 'http://a.com/paths' })).toBe(true);
4040
});
4141

42+
it('match host: keyword', () => {
43+
const route = new Route({
44+
url: 'host:a.b.com',
45+
response: 200,
46+
});
47+
48+
expect(route.matcher({ url: 'http://b.com/path' })).toBe(false);
49+
expect(route.matcher({ url: 'http://a.com/path' })).toBe(false);
50+
expect(route.matcher({ url: 'http://a.b.com/path' })).toBe(true);
51+
expect(route.matcher({ url: 'https://a.b.com/path' })).toBe(true);
52+
});
53+
4254
it('match end: keyword', () => {
4355
const route = new Route({ url: 'end:com/path', response: 200 });
4456
expect(route.matcher({ url: 'http://a.com/paths' })).toBe(false);
@@ -332,12 +344,22 @@ describe('url matching', () => {
332344
});
333345
expect(route.matcher({ url: 'image.jpg' })).toBe(true);
334346
});
347+
348+
it('not match host: keyword', () => {
349+
const route = new Route({
350+
url: 'host:a.com',
351+
response: 200,
352+
});
353+
354+
expect(route.matcher({ url: '/path' })).toBe(false);
355+
});
335356
});
336357
}
337358

338359
describe('when in browser environment', () => {
339360
let location;
340361
let origin;
362+
let host;
341363
beforeAll(() => {
342364
if (!isBrowser) {
343365
const dom = new JSDOM(``, {
@@ -347,6 +369,7 @@ describe('url matching', () => {
347369
}
348370
location = globalThis.location.href;
349371
origin = globalThis.location.origin;
372+
host = globalThis.location.host;
350373
});
351374
afterAll(() => {
352375
if (!isBrowser) {
@@ -388,6 +411,15 @@ describe('url matching', () => {
388411
const route = new Route({ url: '/image.jpg', response: 200 });
389412
expect(route.matcher({ url: `${origin}/image.jpg` })).toBe(true);
390413
});
414+
415+
it('match host: keyword', () => {
416+
const route = new Route({
417+
url: `host:${host}`,
418+
response: 200,
419+
});
420+
421+
expect(route.matcher({ url: '/path' })).toBe(true);
422+
});
391423
});
392424
});
393425
});

0 commit comments

Comments
 (0)