-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.ts
108 lines (97 loc) · 3.23 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import type { LifeCycleEventsMap } from 'msw';
import type { SetupWorker } from 'msw/browser';
import type { SetupServer } from 'msw/node';
import { defaultRequestLogger } from './defaultRequestLogger';
import { makeErrorMessage } from './makeErrorMessage';
import { matchStringUrl } from './matchStringUrl';
import { matchRegexUrl } from './matchRegexUrl';
type MockedRequest = LifeCycleEventsMap['request:match'][0]['request'];
/**
* Create a new MSW inspector instance bound to the provided msw server setup
*/
function createMSWInspector<FunctionMock extends Function>({
mockSetup,
mockFactory,
requestLogger = defaultRequestLogger,
}: {
mockSetup: SetupServer | SetupWorker;
mockFactory: () => FunctionMock;
requestLogger?: (req: MockedRequest) => Promise<Record<string, unknown>>;
}) {
// Store intercepted network requests by url
const interceptedRequests = new Map<string, Request[]>();
async function storeRequest(
...args: LifeCycleEventsMap['request:match']
): Promise<void> {
interceptedRequests;
const { request } = args[0];
const { href } = new URL(request.url);
const currentHrefRequest = interceptedRequests.get(href) || [];
currentHrefRequest.push(request);
interceptedRequests.set(href, currentHrefRequest);
}
return {
/**
* Return a Jest mock function holding a RequestLogRecord for each call performed against provided path.
* Network requested are spied through msw listeners
*
* @param {string | RegExp} url Url of a network request (`http://origin.com/path`)
* @return {*} {Promise<FunctionMock>}
*/
async getRequests(
url: string | RegExp,
{ debug = true } = {},
): Promise<FunctionMock> {
const matches =
url instanceof RegExp
? matchRegexUrl({ url, interceptedRequests })
: matchStringUrl({ url, interceptedRequests });
const functionMock = mockFactory();
if (matches.length === 0) {
if (debug) {
throw new Error(
makeErrorMessage({
message: `Cannot find a matching requests for url: "${url}"`,
interceptedRequests,
}),
);
}
return functionMock;
}
// Create logs for each matching request
const requestLogs = await Promise.all(
matches.map((request) => requestLogger(request)),
);
// Call function mock with each created log
requestLogs.forEach((log) => {
functionMock(log);
});
return functionMock;
},
/**
* Setup a msw spy. Call it before tests are executed
*/
setup() {
// https://mswjs.io/docs/extensions/life-cycle-events#methods
mockSetup.events.on('request:match', storeRequest);
return this;
},
/**
* Clear msw spy call log. Call it before every single test execution
*/
clear() {
interceptedRequests.clear();
return this;
},
/**
* Tear down msw spy. Call it after all tests are executed
*/
teardown() {
mockSetup.events.removeListener('request:match', storeRequest);
return this;
},
};
}
export type MswInspector = ReturnType<typeof createMSWInspector>;
export { createMSWInspector, defaultRequestLogger };
export type { MockedRequest };