@zimic/interceptor 0.16.0-canary.5 → 0.16.0-canary.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/cli.mjs.map +1 -1
- package/dist/http.d.ts +180 -141
- package/dist/http.js +88 -55
- package/dist/http.js.map +1 -1
- package/dist/http.mjs +88 -56
- package/dist/http.mjs.map +1 -1
- package/package.json +2 -2
- package/src/http/index.ts +5 -2
- package/src/http/interceptor/HttpInterceptorClient.ts +30 -15
- package/src/http/interceptor/LocalHttpInterceptor.ts +8 -8
- package/src/http/interceptor/RemoteHttpInterceptor.ts +8 -8
- package/src/http/interceptor/errors/RequestSavingSafeLimitExceededError.ts +22 -0
- package/src/http/interceptor/types/options.ts +3 -10
- package/src/http/interceptor/types/public.ts +44 -12
- package/src/http/requestHandler/HttpRequestHandlerClient.ts +15 -5
- package/src/http/requestHandler/errors/DisabledRequestSavingError.ts +1 -1
- package/src/http/requestHandler/errors/TimesCheckError.ts +5 -4
- package/src/http/requestHandler/types/public.ts +16 -8
package/package.json
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"api",
|
|
15
15
|
"static"
|
|
16
16
|
],
|
|
17
|
-
"version": "0.16.0-canary.
|
|
17
|
+
"version": "0.16.0-canary.7",
|
|
18
18
|
"repository": {
|
|
19
19
|
"type": "git",
|
|
20
20
|
"url": "https://github.com/zimicjs/zimic.git",
|
|
@@ -97,9 +97,9 @@
|
|
|
97
97
|
"tsup": "^8.4.0",
|
|
98
98
|
"typescript": "^5.8.2",
|
|
99
99
|
"vitest": "^3.0.8",
|
|
100
|
+
"@zimic/eslint-config-node": "0.0.0",
|
|
100
101
|
"@zimic/lint-staged-config": "0.0.0",
|
|
101
102
|
"@zimic/utils": "0.0.0",
|
|
102
|
-
"@zimic/eslint-config-node": "0.0.0",
|
|
103
103
|
"@zimic/tsconfig": "0.0.0"
|
|
104
104
|
},
|
|
105
105
|
"peerDependencies": {
|
package/src/http/index.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
export { default as InvalidJSONError } from './interceptorWorker/errors/InvalidJSONError';
|
|
2
|
-
export { default as InvalidFormDataError } from './interceptorWorker/errors/InvalidFormDataError';
|
|
3
1
|
export { default as RunningHttpInterceptorError } from './interceptor/errors/RunningHttpInterceptorError';
|
|
4
2
|
export { default as NotRunningHttpInterceptorError } from './interceptor/errors/NotRunningHttpInterceptorError';
|
|
5
3
|
export { default as UnknownHttpInterceptorPlatformError } from './interceptor/errors/UnknownHttpInterceptorPlatformError';
|
|
6
4
|
export { default as UnknownHttpInterceptorTypeError } from './interceptor/errors/UnknownHttpInterceptorTypeError';
|
|
5
|
+
export { default as RequestSavingSafeLimitExceededError } from './interceptor/errors/RequestSavingSafeLimitExceededError';
|
|
6
|
+
|
|
7
|
+
export { default as InvalidFormDataError } from './interceptorWorker/errors/InvalidFormDataError';
|
|
8
|
+
export { default as InvalidJSONError } from './interceptorWorker/errors/InvalidJSONError';
|
|
7
9
|
export { default as UnregisteredBrowserServiceWorkerError } from './interceptorWorker/errors/UnregisteredBrowserServiceWorkerError';
|
|
10
|
+
|
|
8
11
|
export { default as DisabledRequestSavingError } from './requestHandler/errors/DisabledRequestSavingError';
|
|
9
12
|
export { default as TimesCheckError } from './requestHandler/errors/TimesCheckError';
|
|
10
13
|
|
|
@@ -23,13 +23,17 @@ import RemoteHttpRequestHandler from '../requestHandler/RemoteHttpRequestHandler
|
|
|
23
23
|
import { HttpRequestHandler, InternalHttpRequestHandler } from '../requestHandler/types/public';
|
|
24
24
|
import { HttpInterceptorRequest } from '../requestHandler/types/requests';
|
|
25
25
|
import NotRunningHttpInterceptorError from './errors/NotRunningHttpInterceptorError';
|
|
26
|
+
import RequestSavingSafeLimitExceededError from './errors/RequestSavingSafeLimitExceededError';
|
|
26
27
|
import RunningHttpInterceptorError from './errors/RunningHttpInterceptorError';
|
|
27
28
|
import HttpInterceptorStore from './HttpInterceptorStore';
|
|
28
29
|
import { UnhandledRequestStrategy } from './types/options';
|
|
30
|
+
import { HttpInterceptorRequestSaving } from './types/public';
|
|
29
31
|
import { HttpInterceptorRequestContext } from './types/requests';
|
|
30
32
|
|
|
31
33
|
export const SUPPORTED_BASE_URL_PROTOCOLS = Object.freeze(['http', 'https']);
|
|
32
34
|
|
|
35
|
+
export const DEFAULT_REQUEST_SAVING_SAFE_LIMIT = 1000;
|
|
36
|
+
|
|
33
37
|
class HttpInterceptorClient<
|
|
34
38
|
Schema extends HttpSchema,
|
|
35
39
|
HandlerConstructor extends HttpRequestHandlerConstructor = HttpRequestHandlerConstructor,
|
|
@@ -38,7 +42,9 @@ class HttpInterceptorClient<
|
|
|
38
42
|
private store: HttpInterceptorStore;
|
|
39
43
|
|
|
40
44
|
private _baseURL!: URL;
|
|
41
|
-
|
|
45
|
+
|
|
46
|
+
requestSaving: HttpInterceptorRequestSaving;
|
|
47
|
+
private numberOfSavedRequests = 0;
|
|
42
48
|
|
|
43
49
|
onUnhandledRequest?: HandlerConstructor extends typeof LocalHttpRequestHandler
|
|
44
50
|
? UnhandledRequestStrategy.Local
|
|
@@ -64,7 +70,7 @@ class HttpInterceptorClient<
|
|
|
64
70
|
worker: HttpInterceptorWorker;
|
|
65
71
|
store: HttpInterceptorStore;
|
|
66
72
|
baseURL: URL;
|
|
67
|
-
|
|
73
|
+
requestSaving?: Partial<HttpInterceptorRequestSaving>;
|
|
68
74
|
onUnhandledRequest?: UnhandledRequestStrategy;
|
|
69
75
|
Handler: HandlerConstructor;
|
|
70
76
|
}) {
|
|
@@ -72,7 +78,12 @@ class HttpInterceptorClient<
|
|
|
72
78
|
this.store = options.store;
|
|
73
79
|
|
|
74
80
|
this.baseURL = options.baseURL;
|
|
75
|
-
|
|
81
|
+
|
|
82
|
+
this.requestSaving = {
|
|
83
|
+
enabled: options.requestSaving?.enabled ?? this.getDefaultRequestSavingEnabled(),
|
|
84
|
+
safeLimit: options.requestSaving?.safeLimit ?? DEFAULT_REQUEST_SAVING_SAFE_LIMIT,
|
|
85
|
+
};
|
|
86
|
+
|
|
76
87
|
this.onUnhandledRequest = options.onUnhandledRequest satisfies
|
|
77
88
|
| UnhandledRequestStrategy
|
|
78
89
|
| undefined as this['onUnhandledRequest'];
|
|
@@ -80,6 +91,10 @@ class HttpInterceptorClient<
|
|
|
80
91
|
this.Handler = options.Handler;
|
|
81
92
|
}
|
|
82
93
|
|
|
94
|
+
private getDefaultRequestSavingEnabled(): boolean {
|
|
95
|
+
return isServerSide() ? process.env.NODE_ENV === 'test' : false;
|
|
96
|
+
}
|
|
97
|
+
|
|
83
98
|
get baseURL() {
|
|
84
99
|
return this._baseURL;
|
|
85
100
|
}
|
|
@@ -103,17 +118,6 @@ class HttpInterceptorClient<
|
|
|
103
118
|
return this.baseURL.href;
|
|
104
119
|
}
|
|
105
120
|
|
|
106
|
-
get saveRequests() {
|
|
107
|
-
if (this._saveRequests === undefined) {
|
|
108
|
-
return isServerSide() ? process.env.NODE_ENV === 'test' : false;
|
|
109
|
-
}
|
|
110
|
-
return this._saveRequests;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
set saveRequests(saveRequests: boolean) {
|
|
114
|
-
this._saveRequests = saveRequests;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
121
|
get platform() {
|
|
118
122
|
return this.worker.platform;
|
|
119
123
|
}
|
|
@@ -251,7 +255,7 @@ class HttpInterceptorClient<
|
|
|
251
255
|
const responseDeclaration = await matchedHandler.applyResponseDeclaration(parsedRequest);
|
|
252
256
|
const response = HttpInterceptorWorker.createResponseFromDeclaration(request, responseDeclaration);
|
|
253
257
|
|
|
254
|
-
if (this.
|
|
258
|
+
if (this.requestSaving.enabled) {
|
|
255
259
|
const responseClone = response.clone();
|
|
256
260
|
|
|
257
261
|
const parsedResponse = await HttpInterceptorWorker.parseRawResponse<
|
|
@@ -265,6 +269,17 @@ class HttpInterceptorClient<
|
|
|
265
269
|
return response;
|
|
266
270
|
}
|
|
267
271
|
|
|
272
|
+
incrementNumberOfSavedRequests(increment: number) {
|
|
273
|
+
this.numberOfSavedRequests = Math.max(this.numberOfSavedRequests + increment, 0);
|
|
274
|
+
|
|
275
|
+
const exceedsSafeLimit = this.numberOfSavedRequests > this.requestSaving.safeLimit;
|
|
276
|
+
|
|
277
|
+
if (increment > 0 && exceedsSafeLimit) {
|
|
278
|
+
const error = new RequestSavingSafeLimitExceededError(this.numberOfSavedRequests, this.requestSaving.safeLimit);
|
|
279
|
+
console.warn(error);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
268
283
|
private async findMatchedHandler<
|
|
269
284
|
Method extends HttpSchemaMethod<Schema>,
|
|
270
285
|
Path extends HttpSchemaPath<Schema, Method>,
|
|
@@ -4,8 +4,8 @@ import LocalHttpRequestHandler from '../requestHandler/LocalHttpRequestHandler';
|
|
|
4
4
|
import HttpInterceptorClient from './HttpInterceptorClient';
|
|
5
5
|
import HttpInterceptorStore from './HttpInterceptorStore';
|
|
6
6
|
import { SyncHttpInterceptorMethodHandler } from './types/handlers';
|
|
7
|
-
import { LocalHttpInterceptorOptions } from './types/options';
|
|
8
|
-
import { LocalHttpInterceptor as PublicLocalHttpInterceptor } from './types/public';
|
|
7
|
+
import { LocalHttpInterceptorOptions, UnhandledRequestStrategy } from './types/options';
|
|
8
|
+
import { HttpInterceptorRequestSaving, LocalHttpInterceptor as PublicLocalHttpInterceptor } from './types/public';
|
|
9
9
|
|
|
10
10
|
class LocalHttpInterceptor<Schema extends HttpSchema> implements PublicLocalHttpInterceptor<Schema> {
|
|
11
11
|
private store = new HttpInterceptorStore();
|
|
@@ -23,7 +23,7 @@ class LocalHttpInterceptor<Schema extends HttpSchema> implements PublicLocalHttp
|
|
|
23
23
|
baseURL,
|
|
24
24
|
Handler: LocalHttpRequestHandler,
|
|
25
25
|
onUnhandledRequest: options.onUnhandledRequest,
|
|
26
|
-
|
|
26
|
+
requestSaving: options.requestSaving,
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -39,19 +39,19 @@ class LocalHttpInterceptor<Schema extends HttpSchema> implements PublicLocalHttp
|
|
|
39
39
|
this.client.baseURL = new URL(baseURL);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
get
|
|
43
|
-
return this.client.
|
|
42
|
+
get requestSaving() {
|
|
43
|
+
return this.client.requestSaving;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
set
|
|
47
|
-
this.client.
|
|
46
|
+
set requestSaving(requestSaving: HttpInterceptorRequestSaving) {
|
|
47
|
+
this.client.requestSaving = requestSaving;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
get onUnhandledRequest() {
|
|
51
51
|
return this.client.onUnhandledRequest;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
set onUnhandledRequest(onUnhandledRequest:
|
|
54
|
+
set onUnhandledRequest(onUnhandledRequest: UnhandledRequestStrategy.Local | undefined) {
|
|
55
55
|
this.client.onUnhandledRequest = onUnhandledRequest;
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -4,8 +4,8 @@ import RemoteHttpRequestHandler from '../requestHandler/RemoteHttpRequestHandler
|
|
|
4
4
|
import HttpInterceptorClient from './HttpInterceptorClient';
|
|
5
5
|
import HttpInterceptorStore from './HttpInterceptorStore';
|
|
6
6
|
import { AsyncHttpInterceptorMethodHandler } from './types/handlers';
|
|
7
|
-
import { RemoteHttpInterceptorOptions } from './types/options';
|
|
8
|
-
import { RemoteHttpInterceptor as PublicRemoteHttpInterceptor } from './types/public';
|
|
7
|
+
import { RemoteHttpInterceptorOptions, UnhandledRequestStrategy } from './types/options';
|
|
8
|
+
import { HttpInterceptorRequestSaving, RemoteHttpInterceptor as PublicRemoteHttpInterceptor } from './types/public';
|
|
9
9
|
|
|
10
10
|
class RemoteHttpInterceptor<Schema extends HttpSchema> implements PublicRemoteHttpInterceptor<Schema> {
|
|
11
11
|
private store = new HttpInterceptorStore();
|
|
@@ -24,7 +24,7 @@ class RemoteHttpInterceptor<Schema extends HttpSchema> implements PublicRemoteHt
|
|
|
24
24
|
baseURL,
|
|
25
25
|
Handler: RemoteHttpRequestHandler,
|
|
26
26
|
onUnhandledRequest: options.onUnhandledRequest,
|
|
27
|
-
|
|
27
|
+
requestSaving: options.requestSaving,
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -40,19 +40,19 @@ class RemoteHttpInterceptor<Schema extends HttpSchema> implements PublicRemoteHt
|
|
|
40
40
|
this.client.baseURL = new URL(baseURL);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
get
|
|
44
|
-
return this.client.
|
|
43
|
+
get requestSaving() {
|
|
44
|
+
return this.client.requestSaving;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
set
|
|
48
|
-
this.client.
|
|
47
|
+
set requestSaving(requestSaving: HttpInterceptorRequestSaving) {
|
|
48
|
+
this.client.requestSaving = requestSaving;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
get onUnhandledRequest() {
|
|
52
52
|
return this.client.onUnhandledRequest;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
set onUnhandledRequest(onUnhandledRequest:
|
|
55
|
+
set onUnhandledRequest(onUnhandledRequest: UnhandledRequestStrategy.Remote | undefined) {
|
|
56
56
|
this.client.onUnhandledRequest = onUnhandledRequest;
|
|
57
57
|
}
|
|
58
58
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error thrown when the safe limit of saved intercepted requests is exceeded.
|
|
3
|
+
*
|
|
4
|
+
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests Saving intercepted requests}
|
|
5
|
+
*/
|
|
6
|
+
class RequestSavingSafeLimitExceededError extends TypeError {
|
|
7
|
+
constructor(numberOfSavedRequests: number, safeLimit: number) {
|
|
8
|
+
super(
|
|
9
|
+
`The number of intercepted requests saved in memory (${numberOfSavedRequests}) exceeded the safe limit of ` +
|
|
10
|
+
`${safeLimit}. Did you forget to call \`interceptor.clear()\`?\n\n` +
|
|
11
|
+
'If you need to save requests, make sure to regularly call `interceptor.clear()`. Alternatively, you can ' +
|
|
12
|
+
'hide this warning by increasing `requestSaving.safeLimit` in your interceptor. Note that saving too many ' +
|
|
13
|
+
'requests in memory can lead to performance issues.\n\n' +
|
|
14
|
+
'If you do not need to save requests, consider setting `requestSaving.enabled: false` in your ' +
|
|
15
|
+
'interceptor.\n\n' +
|
|
16
|
+
'Learn more: https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests',
|
|
17
|
+
);
|
|
18
|
+
this.name = 'RequestSavingSafeLimitExceededError';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default RequestSavingSafeLimitExceededError;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { PossiblePromise } from '@zimic/utils/types';
|
|
2
2
|
|
|
3
|
+
import { HttpInterceptorRequestSaving } from './public';
|
|
3
4
|
import { UnhandledHttpInterceptorRequest } from './requests';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -119,20 +120,12 @@ export interface SharedHttpInterceptorOptions {
|
|
|
119
120
|
baseURL: string;
|
|
120
121
|
|
|
121
122
|
/**
|
|
122
|
-
*
|
|
123
|
-
* should save their intercepted requests in memory and make them accessible through
|
|
124
|
-
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerrequests `handler.requests`}.
|
|
123
|
+
* Configures if the intercepted requests are saved and how they are handled.
|
|
125
124
|
*
|
|
126
|
-
* **Important**: If `saveRequests` is true, make sure to regularly clear the interceptor to avoid that the requests
|
|
127
|
-
* accumulate in memory. A common practice is to call
|
|
128
|
-
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptorclear `interceptor.clear()`}
|
|
129
|
-
* after each test.
|
|
130
|
-
*
|
|
131
|
-
* @default false
|
|
132
125
|
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests Saving intercepted requests}
|
|
133
126
|
* @see {@link https://github.com/zimicjs/zimic/wiki/guides‐testing‐interceptor Testing}
|
|
134
127
|
*/
|
|
135
|
-
|
|
128
|
+
requestSaving?: Partial<HttpInterceptorRequestSaving>;
|
|
136
129
|
}
|
|
137
130
|
|
|
138
131
|
/**
|
|
@@ -3,6 +3,45 @@ import { HttpSchema } from '@zimic/http';
|
|
|
3
3
|
import { SyncHttpInterceptorMethodHandler, AsyncHttpInterceptorMethodHandler } from './handlers';
|
|
4
4
|
import { HttpInterceptorPlatform, UnhandledRequestStrategy } from './options';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Configures if the intercepted requests are saved and how they are handled.
|
|
8
|
+
*
|
|
9
|
+
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests Saving intercepted requests}
|
|
10
|
+
* @see {@link https://github.com/zimicjs/zimic/wiki/guides‐testing‐interceptor Testing}
|
|
11
|
+
*/
|
|
12
|
+
export interface HttpInterceptorRequestSaving {
|
|
13
|
+
/**
|
|
14
|
+
* Whether {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httprequesthandler request handlers}
|
|
15
|
+
* should save their intercepted requests in memory and make them accessible through
|
|
16
|
+
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerrequests `handler.requests`}.
|
|
17
|
+
*
|
|
18
|
+
* If you are using
|
|
19
|
+
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptorchecktimes `interceptor.checkTimes()`}
|
|
20
|
+
* or
|
|
21
|
+
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerchecktimes `handler.checkTimes()`}
|
|
22
|
+
* during tests, consider enabling this option to get more detailed information in `TimesCheckError` errors.
|
|
23
|
+
*
|
|
24
|
+
* **Important**: If `requestSaving.enabled` is `true`, make sure to regularly clear the interceptor to avoid requests
|
|
25
|
+
* accumulating in memory. A common practice is to call
|
|
26
|
+
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptorclear `interceptor.clear()`}
|
|
27
|
+
* after each test.
|
|
28
|
+
*
|
|
29
|
+
* @default process.env.NODE_ENV === 'test'
|
|
30
|
+
*/
|
|
31
|
+
enabled: boolean;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The safe number of requests to save in memory before logging warnings in the console. If `requestSaving.enabled` is
|
|
35
|
+
* `true` and the interceptor is not regularly cleared with
|
|
36
|
+
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptorclear `interceptor.clear()`},
|
|
37
|
+
* the requests may accumulate in memory and cause performance issues. This option does not limit the number of
|
|
38
|
+
* requests saved in memory, only when to log warnings.
|
|
39
|
+
*
|
|
40
|
+
* @default 1000
|
|
41
|
+
*/
|
|
42
|
+
safeLimit: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
6
45
|
/**
|
|
7
46
|
* An interceptor to handle HTTP requests and return mock responses. The methods, paths, status codes, parameters, and
|
|
8
47
|
* responses are statically-typed based on the provided service schema.
|
|
@@ -20,20 +59,12 @@ export interface HttpInterceptor<_Schema extends HttpSchema> {
|
|
|
20
59
|
baseURL: string;
|
|
21
60
|
|
|
22
61
|
/**
|
|
23
|
-
*
|
|
24
|
-
* should save their intercepted requests in memory and make them accessible through
|
|
25
|
-
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerrequests `handler.requests`}.
|
|
26
|
-
*
|
|
27
|
-
* **Important**: If `saveRequests` is true, make sure to regularly clear the interceptor to avoid that the requests
|
|
28
|
-
* accumulate in memory. A common practice is to call
|
|
29
|
-
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptorclear `interceptor.clear()`}
|
|
30
|
-
* after each test.
|
|
62
|
+
* Configures if the intercepted requests are saved and how they are handled.
|
|
31
63
|
*
|
|
32
|
-
* @default process.env.NODE_ENV === 'test'
|
|
33
64
|
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests Saving intercepted requests}
|
|
34
65
|
* @see {@link https://github.com/zimicjs/zimic/wiki/guides‐testing‐interceptor Testing}
|
|
35
66
|
*/
|
|
36
|
-
|
|
67
|
+
requestSaving: HttpInterceptorRequestSaving;
|
|
37
68
|
|
|
38
69
|
/**
|
|
39
70
|
* The platform the interceptor is running on.
|
|
@@ -86,8 +117,9 @@ export interface HttpInterceptor<_Schema extends HttpSchema> {
|
|
|
86
117
|
* of each test.
|
|
87
118
|
*
|
|
88
119
|
* When
|
|
89
|
-
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#
|
|
90
|
-
*
|
|
120
|
+
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests
|
|
121
|
+
* `requestSaving.enabled`} is
|
|
122
|
+
* `true` in your interceptor, the `TimesCheckError` errors will also list each unmatched request with diff of the
|
|
91
123
|
* expected and received data. This is useful for debugging requests that did not match a handler with
|
|
92
124
|
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerwithrestriction restrictions}.
|
|
93
125
|
*
|
|
@@ -91,7 +91,8 @@ class HttpRequestHandlerClient<
|
|
|
91
91
|
|
|
92
92
|
newThis.numberOfMatchedRequests = 0;
|
|
93
93
|
newThis.unmatchedRequestGroups.length = 0;
|
|
94
|
-
|
|
94
|
+
|
|
95
|
+
newThis.clearInterceptedRequests();
|
|
95
96
|
|
|
96
97
|
this.interceptor.registerRequestHandler(this.handler);
|
|
97
98
|
|
|
@@ -132,7 +133,7 @@ class HttpRequestHandlerClient<
|
|
|
132
133
|
declarationPointer: this.timesDeclarationPointer,
|
|
133
134
|
unmatchedRequestGroups: this.unmatchedRequestGroups,
|
|
134
135
|
hasRestrictions: this.restrictions.length > 0,
|
|
135
|
-
|
|
136
|
+
requestSaving: this.interceptor.requestSaving,
|
|
136
137
|
});
|
|
137
138
|
}
|
|
138
139
|
}
|
|
@@ -148,7 +149,8 @@ class HttpRequestHandlerClient<
|
|
|
148
149
|
|
|
149
150
|
this.numberOfMatchedRequests = 0;
|
|
150
151
|
this.unmatchedRequestGroups.length = 0;
|
|
151
|
-
|
|
152
|
+
|
|
153
|
+
this.clearInterceptedRequests();
|
|
152
154
|
|
|
153
155
|
this.createResponseDeclaration = undefined;
|
|
154
156
|
|
|
@@ -168,7 +170,9 @@ class HttpRequestHandlerClient<
|
|
|
168
170
|
this.numberOfMatchedRequests++;
|
|
169
171
|
} else {
|
|
170
172
|
const shouldSaveUnmatchedGroup =
|
|
171
|
-
this.interceptor.
|
|
173
|
+
this.interceptor.requestSaving.enabled &&
|
|
174
|
+
this.restrictions.length > 0 &&
|
|
175
|
+
this.timesDeclarationPointer !== undefined;
|
|
172
176
|
|
|
173
177
|
if (shouldSaveUnmatchedGroup) {
|
|
174
178
|
this.unmatchedRequestGroups.push({ request, diff: restrictionsMatch.diff });
|
|
@@ -378,6 +382,12 @@ class HttpRequestHandlerClient<
|
|
|
378
382
|
) {
|
|
379
383
|
const interceptedRequest = this.createInterceptedRequest(request, response);
|
|
380
384
|
this._requests.push(interceptedRequest);
|
|
385
|
+
this.interceptor.incrementNumberOfSavedRequests(1);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
private clearInterceptedRequests() {
|
|
389
|
+
this.interceptor.incrementNumberOfSavedRequests(-this._requests.length);
|
|
390
|
+
this._requests.length = 0;
|
|
381
391
|
}
|
|
382
392
|
|
|
383
393
|
private createInterceptedRequest(
|
|
@@ -401,7 +411,7 @@ class HttpRequestHandlerClient<
|
|
|
401
411
|
}
|
|
402
412
|
|
|
403
413
|
get requests(): readonly InterceptedHttpInterceptorRequest<Path, Default<Schema[Path][Method]>, StatusCode>[] {
|
|
404
|
-
if (!this.interceptor.
|
|
414
|
+
if (!this.interceptor.requestSaving.enabled) {
|
|
405
415
|
throw new DisabledRequestSavingError();
|
|
406
416
|
}
|
|
407
417
|
|
|
@@ -7,7 +7,7 @@ class DisabledRequestSavingError extends TypeError {
|
|
|
7
7
|
constructor() {
|
|
8
8
|
super(
|
|
9
9
|
'Intercepted requests are not being saved. ' +
|
|
10
|
-
'Did you forget to use `
|
|
10
|
+
'Did you forget to use `requestSaving.enabled: true` in your interceptor?\n\n' +
|
|
11
11
|
'Learn more: https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests',
|
|
12
12
|
);
|
|
13
13
|
this.name = 'DisabledRequestSavingError';
|
|
@@ -2,6 +2,7 @@ import isNonEmpty from '@zimic/utils/data/isNonEmpty';
|
|
|
2
2
|
import { Range } from '@zimic/utils/types';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
|
|
5
|
+
import { HttpInterceptorRequestSaving } from '@/http/interceptor/types/public';
|
|
5
6
|
import { stringifyValueToLog } from '@/utils/console';
|
|
6
7
|
|
|
7
8
|
import { UnmatchedHttpInterceptorRequestGroup } from '../types/restrictions';
|
|
@@ -13,7 +14,7 @@ interface TimesCheckErrorOptions {
|
|
|
13
14
|
declarationPointer: TimesDeclarationPointer | undefined;
|
|
14
15
|
unmatchedRequestGroups: UnmatchedHttpInterceptorRequestGroup[];
|
|
15
16
|
hasRestrictions: boolean;
|
|
16
|
-
|
|
17
|
+
requestSaving: HttpInterceptorRequestSaving;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
function createMessageHeader({
|
|
@@ -51,9 +52,9 @@ function createMessageHeader({
|
|
|
51
52
|
.join('');
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
function createMessageDiffs({
|
|
55
|
-
if (!
|
|
56
|
-
return 'Tip:
|
|
55
|
+
function createMessageDiffs({ requestSaving, unmatchedRequestGroups }: TimesCheckErrorOptions) {
|
|
56
|
+
if (!requestSaving.enabled) {
|
|
57
|
+
return 'Tip: use `requestSaving.enabled: true` in your interceptor for more details about the unmatched requests.';
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
return unmatchedRequestGroups
|
|
@@ -147,8 +147,9 @@ export interface LocalHttpRequestHandler<
|
|
|
147
147
|
* that was not satisfied.
|
|
148
148
|
*
|
|
149
149
|
* When
|
|
150
|
-
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#
|
|
151
|
-
*
|
|
150
|
+
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests
|
|
151
|
+
* `requestSaving.enabled`} is
|
|
152
|
+
* `true` in your interceptor, the `TimesCheckError` errors will also list each unmatched request with diff of the
|
|
152
153
|
* expected and received data. This is useful for debugging requests that did not match a handler with
|
|
153
154
|
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerwithrestriction restrictions}.
|
|
154
155
|
*
|
|
@@ -178,11 +179,14 @@ export interface LocalHttpRequestHandler<
|
|
|
178
179
|
* The intercepted requests that matched this handler, along with the responses returned to each of them. This is
|
|
179
180
|
* useful for testing that the correct requests were made by your application.
|
|
180
181
|
*
|
|
181
|
-
* **Important**: This method can only be used if
|
|
182
|
+
* **Important**: This method can only be used if
|
|
183
|
+
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests
|
|
184
|
+
* `requestSaving.enabled`} is
|
|
185
|
+
* `true` in the interceptor. See
|
|
182
186
|
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests Saving intercepted requests}
|
|
183
187
|
* for more information.
|
|
184
188
|
*
|
|
185
|
-
* @throws {DisabledRequestSavingError} If the interceptor
|
|
189
|
+
* @throws {DisabledRequestSavingError} If the interceptor has `requestSaving.enabled: false`.
|
|
186
190
|
* @readonly
|
|
187
191
|
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerrequests `handler.requests` API reference}
|
|
188
192
|
*/
|
|
@@ -284,8 +288,9 @@ export interface SyncedRemoteHttpRequestHandler<
|
|
|
284
288
|
* that was not satisfied.
|
|
285
289
|
*
|
|
286
290
|
* When
|
|
287
|
-
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#
|
|
288
|
-
*
|
|
291
|
+
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests
|
|
292
|
+
* `requestSaving.enabled`} is
|
|
293
|
+
* true in your interceptor, the `TimesCheckError` errors will also list each unmatched request with diff of the
|
|
289
294
|
* expected and received data. This is useful for debugging requests that did not match a handler with
|
|
290
295
|
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerwithrestriction restrictions}.
|
|
291
296
|
*
|
|
@@ -315,11 +320,14 @@ export interface SyncedRemoteHttpRequestHandler<
|
|
|
315
320
|
* The intercepted requests that matched this handler, along with the responses returned to each of them. This is
|
|
316
321
|
* useful for testing that the correct requests were made by your application.
|
|
317
322
|
*
|
|
318
|
-
* **Important**: This method can only be used if
|
|
323
|
+
* **Important**: This method can only be used if
|
|
324
|
+
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests
|
|
325
|
+
* `requestSaving.enabled`} is
|
|
326
|
+
* `true` in the interceptor. See
|
|
319
327
|
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests Saving intercepted requests}
|
|
320
328
|
* for more information.
|
|
321
329
|
*
|
|
322
|
-
* @throws {DisabledRequestSavingError} If the interceptor
|
|
330
|
+
* @throws {DisabledRequestSavingError} If the interceptor has `requestSaving.enabled: false`.
|
|
323
331
|
* @readonly
|
|
324
332
|
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerrequests `handler.requests` API reference}
|
|
325
333
|
*/
|