nock 9.2.2 → 9.2.6

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 CHANGED
@@ -187,64 +187,51 @@ var scope = nock('http://www.example.com')
187
187
 
188
188
  ## Specifying request body
189
189
 
190
- You can specify the request body to be matched as the second argument to the `get`, `post`, `put` or `delete` specifications like this:
190
+ You can specify the request body to be matched as the second argument to the `get`, `post`, `put` or `delete` specifications. There are four types of second argument allowed:
191
+
192
+ **String**: nock will exact match the stringified request body with the provided string
191
193
 
192
194
  ```js
193
- var scope = nock('http://myapp.iriscouch.com')
194
- .post('/users', {
195
- username: 'pgte',
196
- email: 'pedro.teixeira@gmail.com'
197
- })
198
- .reply(201, {
199
- ok: true,
200
- id: '123ABC',
201
- rev: '946B7D1C'
202
- });
195
+ nock('http://www.example.com')
196
+ .post('/login', 'username=pgte&password=123456')
197
+ .reply(200, { id: '123ABC' });
203
198
  ```
204
199
 
205
- The request body can be a string, a RegExp, a JSON object or a function.
200
+ **RegExp**: nock will test the stringified request body against the provided RegExp
206
201
 
207
202
  ```js
208
- var scope = nock('http://myapp.iriscouch.com')
209
- .post('/users', /email=.?@gmail.com/gi)
210
- .reply(201, {
211
- ok: true,
212
- id: '123ABC',
213
- rev: '946B7D1C'
214
- });
203
+ nock('http://www.example.com')
204
+ .post('/login', /username=\w+/gi)
205
+ .reply(200, { id: '123ABC' });
215
206
  ```
216
207
 
217
- If the request body is a JSON object, a RegExp can be used to match an attribute value.
208
+ **JSON object**: nock will exact match the request body with the provided object. In order to increase flexibility, nock also supports RegExp as an attribute value for the keys:
218
209
 
219
210
  ```js
220
- var scope = nock('http://myapp.iriscouch.com')
221
- .post('/users', {
222
- username: 'pgte',
223
- password: /a.+/,
224
- email: 'pedro.teixeira@gmail.com'
225
- })
226
- .reply(201, {
227
- ok: true,
228
- id: '123ABC',
229
- rev: '946B7D1C'
230
- });
211
+ nock('http://www.example.com')
212
+ .post('/login', { username: 'pgte', password: /.+/i })
213
+ .reply(200, { id: '123ABC' });
231
214
  ```
232
215
 
233
- If the request body is a function, return true if it should be considered a match:
216
+ **Function**: nock will evaluate the function providing the request body object as first argument. Return true if it should be considered a match:
234
217
 
235
218
  ```js
236
- var scope = nock('http://myapp.iriscouch.com')
237
- .post('/users', function(body) {
238
- return body.id === '123ABC';
239
- })
240
- .reply(201, {
241
- ok: true,
242
- id: '123ABC',
243
- rev: '946B7D1C'
244
- });
219
+ nock('http://www.example.com')
220
+ .post('/login', function(body) {
221
+ return body.username && body.password;
222
+ })
223
+ .reply(200, { id: '123ABC' });
224
+ ```
225
+
226
+ In case you need to perform a partial matching on a complex, nested request body you should have a look at libraries like [lodash.matches](https://lodash.com/docs/#matches). Indeed, partial matching can be achieved as:
245
227
 
228
+ ```js
229
+ nock('http://www.example.com')
230
+ .post('/user', _.matches({ address: { country: 'US' } }))
231
+ .reply(200, { id: '123ABC' });
246
232
  ```
247
233
 
234
+
248
235
  ## Specifying request query string
249
236
 
250
237
  Nock understands query strings. Instead of placing the entire URL, you can specify the query part as an object:
package/lib/common.js CHANGED
@@ -266,7 +266,7 @@ var headersArrayToObject = function (rawHeaders) {
266
266
  var headers = {};
267
267
 
268
268
  for (var i=0, len=rawHeaders.length; i<len; i=i+2) {
269
- var key = rawHeaders[i];
269
+ var key = rawHeaders[i].toLowerCase();
270
270
  var value = rawHeaders[i+1];
271
271
 
272
272
  if (headers[key]) {
package/lib/match_body.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  var deepEqual = require('deep-equal');
4
4
  var qs = require('qs');
5
+ var _ = require('lodash')
5
6
 
6
7
  module.exports =
7
8
  function matchBody(spec, body) {
@@ -14,10 +15,14 @@ function matchBody(spec, body) {
14
15
  body = body.toString();
15
16
  }
16
17
 
17
- var contentType = options.headers && (options.headers['Content-Type'] ||
18
- options.headers['content-type']);
18
+ var contentType = (
19
+ options.headers &&
20
+ (options.headers['Content-Type'] || options.headers['content-type']) ||
21
+ ''
22
+ ).toString();
19
23
 
20
- var isMultipart = contentType && contentType.toString().match(/multipart/);
24
+ var isMultipart = contentType.indexOf('multipart') >= 0;
25
+ var isUrlencoded = contentType.indexOf('application/x-www-form-urlencoded') >= 0;
21
26
 
22
27
  // try to transform body to json
23
28
  var json;
@@ -25,10 +30,8 @@ function matchBody(spec, body) {
25
30
  try { json = JSON.parse(body);} catch(err) {}
26
31
  if (json !== undefined) {
27
32
  body = json;
28
- } else {
29
- if (contentType && contentType.toString().match(/application\/x-www-form-urlencoded/)) {
30
- body = qs.parse(body, { allowDots: true });
31
- }
33
+ } else if (isUrlencoded) {
34
+ body = qs.parse(body, { allowDots: true });
32
35
  }
33
36
  }
34
37
 
@@ -54,9 +57,37 @@ function matchBody(spec, body) {
54
57
  spec = spec.replace(/\r?\n|\r/g, '');
55
58
  }
56
59
 
60
+ if (isUrlencoded) {
61
+ spec = mapValuesDeep(spec, function(val) {
62
+ if (_.isRegExp(val)) {
63
+ return val
64
+ }
65
+ return val + ''
66
+ })
67
+ }
68
+
57
69
  return deepEqualExtended(spec, body);
58
70
  };
59
71
 
72
+
73
+ /**
74
+ * Based on lodash issue discussion
75
+ * https://github.com/lodash/lodash/issues/1244
76
+ */
77
+ function mapValuesDeep(obj, cb) {
78
+ if (_.isArray(obj)) {
79
+ return obj.map(function(v) {
80
+ return mapValuesDeep(v, cb)
81
+ })
82
+ }
83
+ if (_.isPlainObject(obj)) {
84
+ return _.mapValues(obj, function(v) {
85
+ return mapValuesDeep(v, cb)
86
+ })
87
+ }
88
+ return cb(obj)
89
+ }
90
+
60
91
  function deepEqualExtended(spec, body) {
61
92
  if (spec && spec.constructor === RegExp) {
62
93
  return spec.test(body);
package/lib/recorder.js CHANGED
@@ -74,11 +74,11 @@ var getBodyFromChunks = function(chunks, headers) {
74
74
  // 2. A string buffer which represents a JSON object.
75
75
  // 3. A string buffer which doesn't represent a JSON object.
76
76
 
77
- var isBinary = common.isBinaryBuffer(mergedBuffer)
77
+ var isBinary = common.isBinaryBuffer(mergedBuffer);
78
78
  if(isBinary) {
79
79
  return {
80
80
  body: mergedBuffer.toString('hex'),
81
- isBinary
81
+ isBinary: true
82
82
  }
83
83
  } else {
84
84
  var maybeStringifiedJson = mergedBuffer.toString('utf8');
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "testing",
8
8
  "isolation"
9
9
  ],
10
- "version": "9.2.2",
10
+ "version": "9.2.6",
11
11
  "author": "Pedro Teixeira <pedro.teixeira@gmail.com>",
12
12
  "contributors": [
13
13
  {