http-snapshotter 0.2.4 → 0.3.0
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 +30 -32
- package/index.d.ts +11 -18
- package/index.js +1 -31
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -118,44 +118,42 @@ There are scenarios where one needs to test varied response for the same call (e
|
|
|
118
118
|
|
|
119
119
|
There are 2 ways to go about this:
|
|
120
120
|
|
|
121
|
-
Method 1: The easy way
|
|
122
|
-
change the response on runtime for the specific test:
|
|
121
|
+
Method 1: The easy way is to [intercept the function](https://gist.github.com/Munawwar/c1d024d20b78f19b3714ab09b62a0e1f) with your other test utilities:
|
|
123
122
|
|
|
124
123
|
```js
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
124
|
+
// setupIntercepts.js
|
|
125
|
+
// Using intercept.js (https://gist.github.com/Munawwar/c1d024d20b78f19b3714ab09b62a0e1f)
|
|
126
|
+
// Write all your intercepts in a single file for all tests.
|
|
127
|
+
// This is safe because the default behavior of an intercept is
|
|
128
|
+
// to call the original function.
|
|
129
|
+
import { intercept } from "./intercept.js";
|
|
130
|
+
import methods from './account.js';
|
|
131
|
+
// intercept the get() method
|
|
132
|
+
export const accountGet = intercept(methods, 'get');
|
|
133
|
+
|
|
134
|
+
// test.js
|
|
135
|
+
import { accountGet } from './setupIntercepts.js';
|
|
136
|
+
// Next import the root function that you want to test, which
|
|
137
|
+
// internally calls get() function from './account.js'
|
|
138
|
+
import { enablePaidFeature } from './routes.js';
|
|
130
139
|
|
|
131
140
|
test('Test behavior on a free account', async (t) => {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
JSON.stringify({
|
|
141
|
-
...(await response.clone().json()),
|
|
142
|
-
free_user: true,
|
|
143
|
-
}),
|
|
144
|
-
{
|
|
145
|
-
headers: response.headers
|
|
146
|
-
}
|
|
147
|
-
)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return response;
|
|
151
|
-
};
|
|
152
|
-
attachResponseTransformer(interceptResponse);
|
|
141
|
+
// Setup mock to simulate a free user
|
|
142
|
+
accountGet.mock(async (originalAccountGetFunction, ...args) => {
|
|
143
|
+
const result = await originalAccountGetFunction(...args); // this will use the existing http snapshot
|
|
144
|
+
return {
|
|
145
|
+
...result,
|
|
146
|
+
free_user: true,
|
|
147
|
+
};
|
|
148
|
+
});
|
|
153
149
|
|
|
154
|
-
//
|
|
155
|
-
// assert
|
|
150
|
+
// write the test here
|
|
151
|
+
// t.assert(await enablePaidFeature(), { error: 'Free accounts do not have access to this paid feature' })
|
|
156
152
|
|
|
157
|
-
// cleanup before moving to next test
|
|
158
|
-
|
|
153
|
+
// cleanup before moving to next test by calling undoMock()
|
|
154
|
+
// This won't destroy the intercept, but will revert the account get()
|
|
155
|
+
// function to call the original account get() function
|
|
156
|
+
accountGet.undoMock();
|
|
159
157
|
});
|
|
160
158
|
```
|
|
161
159
|
|
package/index.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
export type SnapshotText = {
|
|
2
|
-
responseType: 'text';
|
|
3
2
|
fileSuffixKey: string;
|
|
3
|
+
requestType: 'json' | 'text';
|
|
4
4
|
request: {
|
|
5
5
|
method: string;
|
|
6
6
|
url: string;
|
|
7
7
|
headers: string[][];
|
|
8
|
-
body: string | undefined;
|
|
8
|
+
body: string | object | undefined;
|
|
9
9
|
};
|
|
10
|
+
responseType: 'text';
|
|
10
11
|
response: {
|
|
11
12
|
status: number;
|
|
12
13
|
statusText: string;
|
|
@@ -15,14 +16,15 @@ export type SnapshotText = {
|
|
|
15
16
|
};
|
|
16
17
|
};
|
|
17
18
|
export type SnapshotJson = {
|
|
18
|
-
responseType: 'json';
|
|
19
19
|
fileSuffixKey: string;
|
|
20
|
+
requestType: 'json' | 'text';
|
|
20
21
|
request: {
|
|
21
22
|
method: string;
|
|
22
23
|
url: string;
|
|
23
24
|
headers: string[][];
|
|
24
|
-
body: string | undefined;
|
|
25
|
+
body: string | object | undefined;
|
|
25
26
|
};
|
|
27
|
+
responseType: 'json';
|
|
26
28
|
response: {
|
|
27
29
|
status: number;
|
|
28
30
|
statusText: string;
|
|
@@ -31,6 +33,11 @@ export type SnapshotJson = {
|
|
|
31
33
|
};
|
|
32
34
|
};
|
|
33
35
|
export type Snapshot = SnapshotText | SnapshotJson;
|
|
36
|
+
export type ReadSnapshotReturnType = Promise<{
|
|
37
|
+
snapshot: Snapshot;
|
|
38
|
+
absoluteFilePath: string;
|
|
39
|
+
fileName: string;
|
|
40
|
+
}>;
|
|
34
41
|
export type ClientRequestInterceptorType = import('@mswjs/interceptors/ClientRequest').ClientRequestInterceptor;
|
|
35
42
|
export type FetchInterceptorType = import('@mswjs/interceptors/fetch').FetchInterceptor;
|
|
36
43
|
/**
|
|
@@ -66,20 +73,6 @@ export function attachSnapshotFilenameGenerator(func: (req: Request) => Promise<
|
|
|
66
73
|
}>): void;
|
|
67
74
|
/** Reset snapshot filename generator to default */
|
|
68
75
|
export function resetSnapshotFilenameGenerator(): void;
|
|
69
|
-
/**
|
|
70
|
-
* Attach response transformer function.
|
|
71
|
-
*
|
|
72
|
-
* Here is an opportunity to modify the response (loaded from snapshot) on-the-fly right before
|
|
73
|
-
* the response is sent to consumers.
|
|
74
|
-
*
|
|
75
|
-
* WARNING: Attaching a function on a per-test basis may not be concurrent safe. i.e. If you tests
|
|
76
|
-
* run sequentially, then it is safe. But if your test runner runs test suites concurrently,
|
|
77
|
-
* then it is better to attach a function only once ever.
|
|
78
|
-
* @param {(response: Response, request: Request) => Promise<Response>} func
|
|
79
|
-
*/
|
|
80
|
-
export function attachResponseTransformer(func: (response: Response, request: Request) => Promise<Response>): void;
|
|
81
|
-
/** Reset response transformer */
|
|
82
|
-
export function resetResponseTransformer(): void;
|
|
83
76
|
/**
|
|
84
77
|
* Start the interceptor
|
|
85
78
|
* @param {object} opts
|
package/index.js
CHANGED
|
@@ -79,8 +79,6 @@ let snapshotDirectory = null;
|
|
|
79
79
|
* @typedef {SnapshotText | SnapshotJson} Snapshot
|
|
80
80
|
*/
|
|
81
81
|
|
|
82
|
-
/** @type {(res: any) => any} */
|
|
83
|
-
const identity = (response) => response;
|
|
84
82
|
|
|
85
83
|
const defaultKeyDerivationProps = ['method', 'url', 'body'];
|
|
86
84
|
/**
|
|
@@ -112,10 +110,6 @@ async function defaultSnapshotFileNameGenerator(request) {
|
|
|
112
110
|
}
|
|
113
111
|
|
|
114
112
|
// Dynamically changeable props
|
|
115
|
-
/**
|
|
116
|
-
* @type {(response: Response, request: Request) => Promise<Response>}
|
|
117
|
-
*/
|
|
118
|
-
let responseTransformer = identity;
|
|
119
113
|
/**
|
|
120
114
|
* @type {(req: Request) => Promise<{ filePrefix: string, fileSuffixKey: string }>}
|
|
121
115
|
*/
|
|
@@ -296,7 +290,7 @@ async function sendResponse(request, snapshot) {
|
|
|
296
290
|
},
|
|
297
291
|
} = snapshot;
|
|
298
292
|
|
|
299
|
-
|
|
293
|
+
const newResponse = new Response(
|
|
300
294
|
responseType === 'json'
|
|
301
295
|
? JSON.stringify(body)
|
|
302
296
|
: /** @type {string} */ (body),
|
|
@@ -307,8 +301,6 @@ async function sendResponse(request, snapshot) {
|
|
|
307
301
|
},
|
|
308
302
|
);
|
|
309
303
|
|
|
310
|
-
newResponse = await responseTransformer(newResponse, request);
|
|
311
|
-
|
|
312
304
|
// respondWith is a method added by @mswjs/interceptors
|
|
313
305
|
// @ts-ignore
|
|
314
306
|
request.respondWith(newResponse);
|
|
@@ -402,26 +394,6 @@ function resetSnapshotFilenameGenerator() {
|
|
|
402
394
|
snapshotFileNameGenerator = defaultSnapshotFileNameGenerator;
|
|
403
395
|
}
|
|
404
396
|
|
|
405
|
-
/**
|
|
406
|
-
* Attach response transformer function.
|
|
407
|
-
*
|
|
408
|
-
* Here is an opportunity to modify the response (loaded from snapshot) on-the-fly right before
|
|
409
|
-
* the response is sent to consumers.
|
|
410
|
-
*
|
|
411
|
-
* WARNING: Attaching a function on a per-test basis may not be concurrent safe. i.e. If you tests
|
|
412
|
-
* run sequentially, then it is safe. But if your test runner runs test suites concurrently,
|
|
413
|
-
* then it is better to attach a function only once ever.
|
|
414
|
-
* @param {(response: Response, request: Request) => Promise<Response>} func
|
|
415
|
-
*/
|
|
416
|
-
function attachResponseTransformer(func) {
|
|
417
|
-
responseTransformer = func;
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
/** Reset response transformer */
|
|
421
|
-
function resetResponseTransformer() {
|
|
422
|
-
responseTransformer = identity;
|
|
423
|
-
}
|
|
424
|
-
|
|
425
397
|
/**
|
|
426
398
|
* Start the interceptor
|
|
427
399
|
* @param {object} opts
|
|
@@ -506,8 +478,6 @@ module.exports = {
|
|
|
506
478
|
defaultSnapshotFileNameGenerator,
|
|
507
479
|
attachSnapshotFilenameGenerator,
|
|
508
480
|
resetSnapshotFilenameGenerator,
|
|
509
|
-
attachResponseTransformer,
|
|
510
|
-
resetResponseTransformer,
|
|
511
481
|
start,
|
|
512
482
|
stop,
|
|
513
483
|
};
|