node-tdd 3.1.2 → 3.3.2
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 +7 -0
- package/lib/modules/request-recorder/util.js +6 -1
- package/lib/modules/request-recorder.js +19 -4
- package/lib/util/desc.js +12 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -132,6 +132,13 @@ Default: `false`
|
|
|
132
132
|
|
|
133
133
|
When set to true, all headers are stripped when requests are recorded.
|
|
134
134
|
|
|
135
|
+
### nockReqHeaderOverwrite
|
|
136
|
+
|
|
137
|
+
Type: `object`<br>
|
|
138
|
+
Default: `{}`
|
|
139
|
+
|
|
140
|
+
Can be used to overwrite `reqheaders` in recordings. Cassette files are only updated when changed.
|
|
141
|
+
|
|
135
142
|
#### fixtureFolder
|
|
136
143
|
|
|
137
144
|
Type: `string`<br>
|
|
@@ -31,5 +31,10 @@ module.exports.rewriteHeaders = (headers, fn = (k, v) => v) => {
|
|
|
31
31
|
return {};
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
const headersLower = Object.fromEntries(Object.entries(headers).sort(([a], [b]) => a > b ? 1 : -1).map(([k, v]) => [k.toLowerCase(), v]));
|
|
35
|
+
const result = {};
|
|
36
|
+
Object.entries(headersLower).forEach(([k, v]) => {
|
|
37
|
+
result[k] = fn(k, v, headersLower);
|
|
38
|
+
});
|
|
39
|
+
return result;
|
|
35
40
|
};
|
|
@@ -45,6 +45,7 @@ module.exports = opts => {
|
|
|
45
45
|
Joi.assert(opts, Joi.object().keys({
|
|
46
46
|
cassetteFolder: Joi.string(),
|
|
47
47
|
stripHeaders: Joi.boolean(),
|
|
48
|
+
reqHeaderOverwrite: Joi.object().pattern(Joi.string().case('lower'), Joi.alternatives(Joi.string(), Joi.function())),
|
|
48
49
|
strict: Joi.boolean(),
|
|
49
50
|
heal: Joi.alternatives(Joi.boolean(), Joi.string()),
|
|
50
51
|
modifiers: Joi.object().pattern(Joi.string(), Joi.alternatives(Joi.function(), Joi.link('#modifiers')))
|
|
@@ -68,6 +69,18 @@ module.exports = opts => {
|
|
|
68
69
|
return flags.some(flag => needleFlags.includes(flag));
|
|
69
70
|
};
|
|
70
71
|
|
|
72
|
+
const overwriteHeaders = (key, value, headers) => {
|
|
73
|
+
if (key in opts.reqHeaderOverwrite) {
|
|
74
|
+
return typeof opts.reqHeaderOverwrite[key] === 'function' ? opts.reqHeaderOverwrite[key]({
|
|
75
|
+
key,
|
|
76
|
+
value,
|
|
77
|
+
headers
|
|
78
|
+
}) : opts.reqHeaderOverwrite[key];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return value;
|
|
82
|
+
};
|
|
83
|
+
|
|
71
84
|
return {
|
|
72
85
|
inject: async cassetteFile => {
|
|
73
86
|
assert(nockDone === null);
|
|
@@ -126,7 +139,8 @@ module.exports = opts => {
|
|
|
126
139
|
nockRecorder.clear();
|
|
127
140
|
return recorded.map(record => Object.assign(record, {
|
|
128
141
|
headers: opts.stripHeaders === true ? undefined : convertHeaders(record.rawHeaders),
|
|
129
|
-
rawHeaders: undefined
|
|
142
|
+
rawHeaders: undefined,
|
|
143
|
+
reqheaders: rewriteHeaders(record.reqheaders, overwriteHeaders)
|
|
130
144
|
}));
|
|
131
145
|
});
|
|
132
146
|
} else if (anyFlagPresent(['stub'])) {
|
|
@@ -136,7 +150,7 @@ module.exports = opts => {
|
|
|
136
150
|
path: options.path,
|
|
137
151
|
body: tryParseJson(body),
|
|
138
152
|
status: 200,
|
|
139
|
-
reqheaders: rewriteHeaders(options.headers),
|
|
153
|
+
reqheaders: rewriteHeaders(options.headers, overwriteHeaders),
|
|
140
154
|
response: {},
|
|
141
155
|
responseIsBinary: false
|
|
142
156
|
});
|
|
@@ -194,9 +208,10 @@ module.exports = opts => {
|
|
|
194
208
|
|
|
195
209
|
if (anyFlagPresent(['magic', 'headers'])) {
|
|
196
210
|
// add new headers
|
|
197
|
-
|
|
211
|
+
const reqheaders = { ...rewriteHeaders(req.headers),
|
|
198
212
|
...rewriteHeaders(pendingMocks[idx].record.reqheaders)
|
|
199
213
|
};
|
|
214
|
+
pendingMocks[idx].record.reqheaders = rewriteHeaders(reqheaders, overwriteHeaders);
|
|
200
215
|
}
|
|
201
216
|
|
|
202
217
|
if (anyFlagPresent(['magic', 'response'])) {
|
|
@@ -218,7 +233,7 @@ module.exports = opts => {
|
|
|
218
233
|
afterRecord: recordings => JSON.stringify(recordings.map(r => ({ ...r,
|
|
219
234
|
body: tryParseJson(r.body),
|
|
220
235
|
rawHeaders: opts.stripHeaders === true ? undefined : r.rawHeaders,
|
|
221
|
-
reqheaders: rewriteHeaders(r.reqheaders)
|
|
236
|
+
reqheaders: rewriteHeaders(r.reqheaders, overwriteHeaders)
|
|
222
237
|
})), null, 2)
|
|
223
238
|
}, resolve));
|
|
224
239
|
requestInjector.inject();
|
package/lib/util/desc.js
CHANGED
|
@@ -10,6 +10,10 @@ const callsites = require('callsites');
|
|
|
10
10
|
|
|
11
11
|
const get = require('lodash.get');
|
|
12
12
|
|
|
13
|
+
const {
|
|
14
|
+
fileURLToPath
|
|
15
|
+
} = require('url');
|
|
16
|
+
|
|
13
17
|
const minimist = require('minimist');
|
|
14
18
|
|
|
15
19
|
const tmp = require('tmp');
|
|
@@ -45,7 +49,11 @@ const mocha = {
|
|
|
45
49
|
const desc = (suiteName, optsOrTests, testsOrNull = null) => {
|
|
46
50
|
const opts = testsOrNull === null ? {} : optsOrTests;
|
|
47
51
|
const tests = testsOrNull === null ? optsOrTests : testsOrNull;
|
|
48
|
-
const
|
|
52
|
+
const filenameOrUrl = callsites()[1].getFileName(); // eslint-disable-next-line @blackflux/rules/istanbul-prevent-ignore
|
|
53
|
+
|
|
54
|
+
/* istanbul ignore next */
|
|
55
|
+
|
|
56
|
+
const testFile = path.resolve(filenameOrUrl.startsWith('file://') ? fileURLToPath(filenameOrUrl) : filenameOrUrl);
|
|
49
57
|
|
|
50
58
|
const resolve = name => path.join(path.dirname(testFile), name.replace(/\$FILENAME/g, path.basename(testFile)));
|
|
51
59
|
|
|
@@ -55,6 +63,7 @@ const desc = (suiteName, optsOrTests, testsOrNull = null) => {
|
|
|
55
63
|
nockFolder: Joi.string().optional(),
|
|
56
64
|
nockModifiers: Joi.object().optional().pattern(Joi.string(), Joi.function()),
|
|
57
65
|
nockStripHeaders: Joi.boolean().optional(),
|
|
66
|
+
nockReqHeaderOverwrite: Joi.object().optional().pattern(Joi.string(), Joi.alternatives(Joi.function(), Joi.string())),
|
|
58
67
|
fixtureFolder: Joi.string().optional(),
|
|
59
68
|
envVarsFile: Joi.string().optional(),
|
|
60
69
|
envVars: Joi.object().optional().unknown(true).pattern(Joi.string(), Joi.string()),
|
|
@@ -73,6 +82,7 @@ const desc = (suiteName, optsOrTests, testsOrNull = null) => {
|
|
|
73
82
|
const nockFolder = resolve(get(opts, 'nockFolder', '$FILENAME__cassettes'));
|
|
74
83
|
const nockModifiers = get(opts, 'nockModifiers', {});
|
|
75
84
|
const nockStripHeaders = get(opts, 'nockStripHeaders', false);
|
|
85
|
+
const nockReqHeaderOverwrite = get(opts, 'nockReqHeaderOverwrite', {});
|
|
76
86
|
const fixtureFolder = resolve(get(opts, 'fixtureFolder', '$FILENAME__fixtures'));
|
|
77
87
|
const envVarsFile = resolve(get(opts, 'envVarsFile', '$FILENAME.env.yml'));
|
|
78
88
|
const envVars = get(opts, 'envVars', null);
|
|
@@ -178,6 +188,7 @@ const desc = (suiteName, optsOrTests, testsOrNull = null) => {
|
|
|
178
188
|
requestRecorder = RequestRecorder({
|
|
179
189
|
cassetteFolder: `${nockFolder}/`,
|
|
180
190
|
stripHeaders: nockStripHeaders,
|
|
191
|
+
reqHeaderOverwrite: nockReqHeaderOverwrite,
|
|
181
192
|
strict: true,
|
|
182
193
|
heal: nockHeal,
|
|
183
194
|
modifiers: nockModifiers
|