nock 0.56.0 → 0.59.1
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 +41 -1
- package/lib/intercept.js +9 -1
- package/lib/match_body.js +6 -6
- package/lib/recorder.js +87 -11
- package/lib/scope.js +22 -0
- package/package.json +2 -2
- package/tests/test_https_allowunmocked.js +24 -0
- package/tests/test_intercept.js +71 -0
- package/tests/test_recorder.js +80 -16
- package/tests/test_redirects.js +28 -0
package/README.md
CHANGED
|
@@ -106,7 +106,7 @@ var scope = nock('http://myapp.iriscouch.com')
|
|
|
106
106
|
});
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
The request body can be a string, a RegExp,
|
|
109
|
+
The request body can be a string, a RegExp, a JSON object or a function.
|
|
110
110
|
|
|
111
111
|
```js
|
|
112
112
|
var scope = nock('http://myapp.iriscouch.com')
|
|
@@ -118,6 +118,20 @@ var scope = nock('http://myapp.iriscouch.com')
|
|
|
118
118
|
});
|
|
119
119
|
```
|
|
120
120
|
|
|
121
|
+
If the request body is a function, return true if it should be considered a match:
|
|
122
|
+
```js
|
|
123
|
+
var scope = nock('http://myapp.iriscouch.com')
|
|
124
|
+
.post('/users', function(body) {
|
|
125
|
+
return body.id === '123ABC';
|
|
126
|
+
})
|
|
127
|
+
.reply(201, {
|
|
128
|
+
ok: true,
|
|
129
|
+
id: '123ABC',
|
|
130
|
+
rev: '946B7D1C'
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
|
|
121
135
|
## Specifying replies
|
|
122
136
|
|
|
123
137
|
You can specify the return status code for a path on the first argument of reply like this:
|
|
@@ -227,6 +241,32 @@ var scope = nock('http://www.headdy.com')
|
|
|
227
241
|
.reply(200, 'The default headers should come too');
|
|
228
242
|
```
|
|
229
243
|
|
|
244
|
+
### Including Content-Length Header Automatically
|
|
245
|
+
|
|
246
|
+
When using `scope.reply()` to set a response body manually, you can have the
|
|
247
|
+
`Content-Length` header calculated automatically.
|
|
248
|
+
|
|
249
|
+
```js
|
|
250
|
+
var scope = nock('http://www.headdy.com')
|
|
251
|
+
.replyContentLength()
|
|
252
|
+
.get('/')
|
|
253
|
+
.reply(200, { hello: 'world' });
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**NOTE:** this does not work with streams or other advanced means of specifying
|
|
257
|
+
the reply body.
|
|
258
|
+
|
|
259
|
+
### Including Date Header Automatically
|
|
260
|
+
|
|
261
|
+
You can automatically append a `Date` header to your mock reply:
|
|
262
|
+
|
|
263
|
+
```js
|
|
264
|
+
var scope = nock('http://www.headdy.com')
|
|
265
|
+
.replyDate(new Date(2015, 0, 1)) // defaults to now, must use a Date object
|
|
266
|
+
.get('/')
|
|
267
|
+
.reply(200, { hello: 'world' });
|
|
268
|
+
```
|
|
269
|
+
|
|
230
270
|
## HTTP Verbs
|
|
231
271
|
|
|
232
272
|
Nock supports any HTTP verb, and it has convenience methods for the GET, POST, PUT, HEAD, DELETE, PATCH and MERGE HTTP verbs.
|
package/lib/intercept.js
CHANGED
|
@@ -371,7 +371,15 @@ function activate() {
|
|
|
371
371
|
});
|
|
372
372
|
|
|
373
373
|
if (! matches && allowUnmocked) {
|
|
374
|
-
|
|
374
|
+
if (proto === 'https') {
|
|
375
|
+
var ClientRequest = http.ClientRequest;
|
|
376
|
+
http.ClientRequest = originalClientRequest;
|
|
377
|
+
req = overriddenRequest(options, callback);
|
|
378
|
+
http.ClientRequest = ClientRequest;
|
|
379
|
+
} else {
|
|
380
|
+
req = overriddenRequest(options, callback);
|
|
381
|
+
}
|
|
382
|
+
return req;
|
|
375
383
|
}
|
|
376
384
|
|
|
377
385
|
// NOTE: Since we already overrode the http.ClientRequest we are in fact constructing
|
package/lib/match_body.js
CHANGED
|
@@ -27,17 +27,13 @@ function matchBody(spec, body) {
|
|
|
27
27
|
|
|
28
28
|
// try to transform body to json
|
|
29
29
|
var json;
|
|
30
|
-
if (typeof spec === 'object') {
|
|
30
|
+
if (typeof spec === 'object' || typeof spec === 'function') {
|
|
31
31
|
try { json = JSON.parse(body);} catch(err) {}
|
|
32
32
|
if (json !== undefined) {
|
|
33
33
|
body = json;
|
|
34
34
|
}
|
|
35
35
|
else
|
|
36
|
-
if (
|
|
37
|
-
(typeof spec === 'object') &&
|
|
38
|
-
options.headers
|
|
39
|
-
)
|
|
40
|
-
{
|
|
36
|
+
if (options.headers) {
|
|
41
37
|
var contentType = options.headers['Content-Type'] ||
|
|
42
38
|
options.headers['content-type'];
|
|
43
39
|
|
|
@@ -47,6 +43,10 @@ function matchBody(spec, body) {
|
|
|
47
43
|
}
|
|
48
44
|
}
|
|
49
45
|
|
|
46
|
+
if (typeof spec === "function") {
|
|
47
|
+
return spec.call(this, body);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
50
|
try {
|
|
51
51
|
deepEqual(spec, body);
|
|
52
52
|
return true;
|
package/lib/recorder.js
CHANGED
|
@@ -6,6 +6,7 @@ var common = require('./common');
|
|
|
6
6
|
var intercept = require('./intercept');
|
|
7
7
|
var debug = require('debug')('nock.recorder');
|
|
8
8
|
var _ = require('lodash');
|
|
9
|
+
var Stream = require('stream');
|
|
9
10
|
|
|
10
11
|
var SEPARATOR = '\n<<<<<<-- cut here -->>>>>>\n';
|
|
11
12
|
var recordingInProgress = false;
|
|
@@ -83,6 +84,7 @@ var getBodyFromChunks = function(chunks, headers) {
|
|
|
83
84
|
};
|
|
84
85
|
|
|
85
86
|
function generateRequestAndResponseObject(req, bodyChunks, options, res, dataChunks) {
|
|
87
|
+
|
|
86
88
|
options.path = req.path;
|
|
87
89
|
return {
|
|
88
90
|
scope: getScope(options),
|
|
@@ -197,17 +199,7 @@ function record(rec_options) {
|
|
|
197
199
|
options = parse(options);
|
|
198
200
|
}
|
|
199
201
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
res.on('data', function(data) {
|
|
203
|
-
debug(thisRecordingId, 'new', proto, 'data chunk');
|
|
204
|
-
dataChunks.push(data);
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
if (proto === 'https') {
|
|
208
|
-
options._https_ = true;
|
|
209
|
-
}
|
|
210
|
-
|
|
202
|
+
// We put our 'end' listener to the front of the listener array.
|
|
211
203
|
res.once('end', function() {
|
|
212
204
|
debug(thisRecordingId, proto, 'intercepted request ended');
|
|
213
205
|
|
|
@@ -248,10 +240,94 @@ function record(rec_options) {
|
|
|
248
240
|
}
|
|
249
241
|
});
|
|
250
242
|
|
|
243
|
+
var dataChunks = [];
|
|
244
|
+
|
|
245
|
+
// Give the actual client a chance to setup its listeners.
|
|
246
|
+
// We will use the listener information to figure out
|
|
247
|
+
// how we need to feed the intercepted data back to the client.
|
|
251
248
|
if (callback) {
|
|
252
249
|
callback(res, options, callback);
|
|
253
250
|
}
|
|
254
251
|
|
|
252
|
+
// Handle clients that listen to 'readable' by intercepting them
|
|
253
|
+
// and feeding them the data manually.
|
|
254
|
+
var readableListeners = res.listeners('readable');
|
|
255
|
+
if (!_.isEmpty(readableListeners)) {
|
|
256
|
+
|
|
257
|
+
debug('handle readable listeners');
|
|
258
|
+
|
|
259
|
+
// We will replace the client's listeners with our own and manually
|
|
260
|
+
// invoke them.
|
|
261
|
+
_.each(readableListeners, function(listener) {
|
|
262
|
+
res.removeListener('readable', listener);
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
// Repleace the actual Stream.Readable prototype 'read' function
|
|
266
|
+
// so that we can control what the client listener will be reading.
|
|
267
|
+
var prototypeRead = Stream.Readable.prototype.read;
|
|
268
|
+
var currentReadIndex = 0;
|
|
269
|
+
res.read = function() {
|
|
270
|
+
|
|
271
|
+
debug(thisRecordingId, 'client reading data on', proto, dataChunks.length);
|
|
272
|
+
|
|
273
|
+
// Feed the data to the client through from our collected data chunks.
|
|
274
|
+
if (currentReadIndex < dataChunks.length) {
|
|
275
|
+
debug('chunk', chunk, 'read');
|
|
276
|
+
var chunk = dataChunks[currentReadIndex];
|
|
277
|
+
++currentReadIndex;
|
|
278
|
+
return chunk;
|
|
279
|
+
} else {
|
|
280
|
+
debug('no more chunks to read');
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
// Put our own listener instead of the removed client listener.
|
|
287
|
+
var onReadable = function(data) {
|
|
288
|
+
debug(thisRecordingId, 'new readable data on', proto);
|
|
289
|
+
var chunk;
|
|
290
|
+
// Use the prototypeRead function to actually read the data.
|
|
291
|
+
while (null !== (chunk = prototypeRead.call(res))) {
|
|
292
|
+
debug('read', chunk);
|
|
293
|
+
dataChunks.push(chunk);
|
|
294
|
+
}
|
|
295
|
+
// Manually invoke the user listeners emulating 'readable' event.
|
|
296
|
+
_.each(readableListeners, function(listener) {
|
|
297
|
+
listener();
|
|
298
|
+
});
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
res.on('readable', onReadable);
|
|
302
|
+
|
|
303
|
+
} else {
|
|
304
|
+
|
|
305
|
+
// In all other cases we (for now at least) fall back on intercepting
|
|
306
|
+
// 'data' events.
|
|
307
|
+
debug('fall back on our original implementation');
|
|
308
|
+
|
|
309
|
+
// Since we gave client the chance to setup its listeners
|
|
310
|
+
// before us, we need to remove them and setup our own.
|
|
311
|
+
_.each(res.listeners('data'), function(listener) {
|
|
312
|
+
res.removeListener('data', listener);
|
|
313
|
+
})
|
|
314
|
+
_.each(res.listeners('readable'), function(listener) {
|
|
315
|
+
res.removeListener('readable', listener);
|
|
316
|
+
})
|
|
317
|
+
|
|
318
|
+
var onData = function(data) {
|
|
319
|
+
debug(thisRecordingId, 'new data chunk on', proto);
|
|
320
|
+
dataChunks.push(data);
|
|
321
|
+
};
|
|
322
|
+
res.on('data', onData);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
debug('finished setting up intercepting');
|
|
326
|
+
|
|
327
|
+
if (proto === 'https') {
|
|
328
|
+
options._https_ = true;
|
|
329
|
+
}
|
|
330
|
+
|
|
255
331
|
});
|
|
256
332
|
|
|
257
333
|
var oldWrite = req.write;
|
package/lib/scope.js
CHANGED
|
@@ -30,6 +30,8 @@ function startScope(basePath, options) {
|
|
|
30
30
|
urlParts = url.parse(basePath),
|
|
31
31
|
port = urlParts.port || ((urlParts.protocol === 'http:') ? 80 : 443),
|
|
32
32
|
persist = false,
|
|
33
|
+
contentLen = false,
|
|
34
|
+
date = null,
|
|
33
35
|
basePathname = urlParts.pathname.replace(/\/$/, '');
|
|
34
36
|
|
|
35
37
|
basePath = urlParts.protocol + '//' + urlParts.hostname + ':' + port;
|
|
@@ -75,6 +77,11 @@ function startScope(basePath, options) {
|
|
|
75
77
|
headers = mixin(scope._defaultReplyHeaders, headers);
|
|
76
78
|
}
|
|
77
79
|
|
|
80
|
+
if (date) {
|
|
81
|
+
headers = headers || {};
|
|
82
|
+
headers['date'] = date.toUTCString();
|
|
83
|
+
}
|
|
84
|
+
|
|
78
85
|
if (headers !== undefined) {
|
|
79
86
|
this.headers = {};
|
|
80
87
|
|
|
@@ -101,6 +108,9 @@ function startScope(basePath, options) {
|
|
|
101
108
|
if (!this.headers['content-type']) {
|
|
102
109
|
this.headers['content-type'] = 'application/json';
|
|
103
110
|
}
|
|
111
|
+
if (contentLen) {
|
|
112
|
+
this.headers['content-length'] = body.length;
|
|
113
|
+
}
|
|
104
114
|
} catch(err) {
|
|
105
115
|
throw new Error('Error encoding response body into JSON');
|
|
106
116
|
}
|
|
@@ -493,6 +503,16 @@ function startScope(basePath, options) {
|
|
|
493
503
|
return persist;
|
|
494
504
|
}
|
|
495
505
|
|
|
506
|
+
function replyContentLength() {
|
|
507
|
+
contentLen = true;
|
|
508
|
+
return this;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
function replyDate(d) {
|
|
512
|
+
date = d || new Date();
|
|
513
|
+
return this;
|
|
514
|
+
}
|
|
515
|
+
|
|
496
516
|
|
|
497
517
|
scope = {
|
|
498
518
|
get: get
|
|
@@ -513,6 +533,8 @@ function startScope(basePath, options) {
|
|
|
513
533
|
, persist: _persist
|
|
514
534
|
, shouldPersist: shouldPersist
|
|
515
535
|
, pendingMocks: pendingMocks
|
|
536
|
+
, replyContentLength: replyContentLength
|
|
537
|
+
, replyDate: replyDate
|
|
516
538
|
};
|
|
517
539
|
|
|
518
540
|
return scope;
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"testing",
|
|
8
8
|
"isolation"
|
|
9
9
|
],
|
|
10
|
-
"version": "0.
|
|
10
|
+
"version": "0.59.1",
|
|
11
11
|
"author": "Pedro Teixeira <pedro.teixeira@gmail.com>",
|
|
12
12
|
"contributors": [
|
|
13
13
|
{
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
"jshint": "^2.5.6",
|
|
117
117
|
"needle": "^0.7.1",
|
|
118
118
|
"pre-commit": "0.0.9",
|
|
119
|
-
"request": "
|
|
119
|
+
"request": "2.51.0",
|
|
120
120
|
"restler": "3.2.2",
|
|
121
121
|
"restify": "^2.8.1",
|
|
122
122
|
"superagent": "~0.15.7",
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var test = require('tap').test;
|
|
4
|
+
var mikealRequest = require('request');
|
|
5
|
+
|
|
6
|
+
test('allowUnmock for https', function(t) {
|
|
7
|
+
var nock = require('../');
|
|
8
|
+
var scope = nock('https://www.google.com/', {allowUnmocked: true})
|
|
9
|
+
.get('/pathneverhit')
|
|
10
|
+
.reply(200, {foo: 'bar'});
|
|
11
|
+
|
|
12
|
+
var options = {
|
|
13
|
+
method: 'GET',
|
|
14
|
+
uri: 'https://www.google.com'
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
mikealRequest(options, function(err, resp, body) {
|
|
18
|
+
t.notOk(err, 'should be no error');
|
|
19
|
+
t.true(typeof body !== 'undefined', 'body should not be undefined');
|
|
20
|
+
t.true(body.length !== 0, 'body should not be empty');
|
|
21
|
+
t.end();
|
|
22
|
+
return console.log(resp.statusCode, 'body length: ', body.length);
|
|
23
|
+
});
|
|
24
|
+
});
|
package/tests/test_intercept.js
CHANGED
|
@@ -340,6 +340,34 @@ test("post with regexp as spec", function(t) {
|
|
|
340
340
|
req.end();
|
|
341
341
|
});
|
|
342
342
|
|
|
343
|
+
test("post with function as spec", function(t) {
|
|
344
|
+
var scope = nock('http://www.google.com')
|
|
345
|
+
.post('/echo', function(body) {
|
|
346
|
+
return body === 'key=val';
|
|
347
|
+
})
|
|
348
|
+
.reply(200, function(uri, body) {
|
|
349
|
+
return ['OK', uri, body].join(' ');
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
var req = http.request({
|
|
353
|
+
host: "www.google.com"
|
|
354
|
+
, method: 'POST'
|
|
355
|
+
, path: '/echo'
|
|
356
|
+
, port: 80
|
|
357
|
+
}, function(res) {
|
|
358
|
+
res.on('end', function() {
|
|
359
|
+
scope.done();
|
|
360
|
+
t.end();
|
|
361
|
+
});
|
|
362
|
+
res.on('data', function(data) {
|
|
363
|
+
t.equal(data.toString(), 'OK /echo key=val' , 'response should match');
|
|
364
|
+
});
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
req.write('key=val');
|
|
368
|
+
req.end();
|
|
369
|
+
});
|
|
370
|
+
|
|
343
371
|
test("post with chaining on call", function(t) {
|
|
344
372
|
var input = 'key=val';
|
|
345
373
|
|
|
@@ -1035,6 +1063,8 @@ test("reply with JSON", function(t) {
|
|
|
1035
1063
|
|
|
1036
1064
|
res.setEncoding('utf8');
|
|
1037
1065
|
t.equal(res.statusCode, 200);
|
|
1066
|
+
t.notOk(res.headers['date']);
|
|
1067
|
+
t.notOk(res.headers['content-length']);
|
|
1038
1068
|
t.equal(res.headers['content-type'], 'application/json');
|
|
1039
1069
|
res.on('end', function() {
|
|
1040
1070
|
t.ok(dataCalled);
|
|
@@ -1052,6 +1082,47 @@ test("reply with JSON", function(t) {
|
|
|
1052
1082
|
|
|
1053
1083
|
});
|
|
1054
1084
|
|
|
1085
|
+
test("reply with content-length header", function(t){
|
|
1086
|
+
var scope = nock('http://www.jsonreplier.com')
|
|
1087
|
+
.replyContentLength()
|
|
1088
|
+
.get('/')
|
|
1089
|
+
.reply(200, {hello: "world"});
|
|
1090
|
+
|
|
1091
|
+
var req = http.get({
|
|
1092
|
+
host: "www.jsonreplier.com"
|
|
1093
|
+
, path: '/'
|
|
1094
|
+
, port: 80
|
|
1095
|
+
}, function(res) {
|
|
1096
|
+
t.equal(res.headers['content-length'], 17);
|
|
1097
|
+
res.on('end', function() {
|
|
1098
|
+
scope.done();
|
|
1099
|
+
t.end();
|
|
1100
|
+
});
|
|
1101
|
+
});
|
|
1102
|
+
});
|
|
1103
|
+
|
|
1104
|
+
test("reply with date header", function(t){
|
|
1105
|
+
var date = new Date();
|
|
1106
|
+
|
|
1107
|
+
var scope = nock('http://www.jsonreplier.com')
|
|
1108
|
+
.replyDate(date)
|
|
1109
|
+
.get('/')
|
|
1110
|
+
.reply(200, {hello: "world"});
|
|
1111
|
+
|
|
1112
|
+
var req = http.get({
|
|
1113
|
+
host: "www.jsonreplier.com"
|
|
1114
|
+
, path: '/'
|
|
1115
|
+
, port: 80
|
|
1116
|
+
}, function(res) {
|
|
1117
|
+
console.error(res.headers);
|
|
1118
|
+
t.equal(res.headers['date'], date.toUTCString());
|
|
1119
|
+
res.on('end', function() {
|
|
1120
|
+
scope.done();
|
|
1121
|
+
t.end();
|
|
1122
|
+
});
|
|
1123
|
+
});
|
|
1124
|
+
});
|
|
1125
|
+
|
|
1055
1126
|
test("filter path with function", function(t) {
|
|
1056
1127
|
var scope = nock('http://www.filterurls.com')
|
|
1057
1128
|
.filteringPath(function(path) {
|
package/tests/test_recorder.js
CHANGED
|
@@ -543,24 +543,88 @@ tap.test('records request headers except user-agent if enable_reqheaders_recordi
|
|
|
543
543
|
});
|
|
544
544
|
|
|
545
545
|
tap.test('includes query parameters from superagent', function(t) {
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
546
|
+
nock.restore();
|
|
547
|
+
nock.recorder.clear();
|
|
548
|
+
t.equal(nock.recorder.play().length, 0);
|
|
549
549
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
550
|
+
nock.recorder.rec({
|
|
551
|
+
dont_print: true,
|
|
552
|
+
output_objects: true
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
superagent.get('http://google.com')
|
|
556
|
+
.query({q: 'test search' })
|
|
557
|
+
.end(function(res) {
|
|
558
|
+
nock.restore();
|
|
559
|
+
var ret = nock.recorder.play();
|
|
560
|
+
t.true(ret.length >= 1);
|
|
561
|
+
t.equal(ret[0].path, '/?q=test%20search');
|
|
562
|
+
t.end();
|
|
553
563
|
});
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
tap.test('works with clients listening for readable', function(t) {
|
|
567
|
+
nock.restore();
|
|
568
|
+
nock.recorder.clear();
|
|
569
|
+
t.equal(nock.recorder.play().length, 0);
|
|
570
|
+
|
|
571
|
+
var REQUEST_BODY = 'ABCDEF';
|
|
572
|
+
var RESPONSE_BODY = '012345';
|
|
573
|
+
|
|
574
|
+
// Create test http server and perform the tests while it's up.
|
|
575
|
+
var testServer = http.createServer(function (req, res) {
|
|
576
|
+
res.write(RESPONSE_BODY);
|
|
577
|
+
res.end();
|
|
578
|
+
}).listen(8081, function(err) {
|
|
579
|
+
|
|
580
|
+
// t.equal(err, undefined);
|
|
581
|
+
|
|
582
|
+
var options = { host:'localhost'
|
|
583
|
+
, port:testServer.address().port
|
|
584
|
+
, path:'/' }
|
|
585
|
+
;
|
|
586
|
+
|
|
587
|
+
var rec_options = {
|
|
588
|
+
dont_print: true,
|
|
589
|
+
output_objects: true
|
|
590
|
+
};
|
|
591
|
+
|
|
592
|
+
nock.recorder.rec(rec_options);
|
|
593
|
+
|
|
594
|
+
var req = http.request(options, function(res) {
|
|
595
|
+
var readableCount = 0;
|
|
596
|
+
var chunkCount = 0;
|
|
597
|
+
res.on('readable', function() {
|
|
598
|
+
++readableCount;
|
|
599
|
+
var chunk;
|
|
600
|
+
while (null !== (chunk = res.read())) {
|
|
601
|
+
t.equal(chunk.toString(), RESPONSE_BODY);
|
|
602
|
+
++chunkCount;
|
|
603
|
+
}
|
|
604
|
+
});
|
|
605
|
+
res.once('end', function() {
|
|
606
|
+
nock.restore();
|
|
607
|
+
var ret = nock.recorder.play();
|
|
608
|
+
t.equal(ret.length, 1);
|
|
609
|
+
ret = ret[0];
|
|
610
|
+
t.type(ret, 'object');
|
|
611
|
+
t.equal(readableCount, 1);
|
|
612
|
+
t.equal(chunkCount, 1);
|
|
613
|
+
t.equal(ret.scope, "http://localhost:" + options.port);
|
|
614
|
+
t.equal(ret.method, "GET");
|
|
615
|
+
t.equal(ret.body, REQUEST_BODY);
|
|
616
|
+
t.equal(ret.status, 200);
|
|
617
|
+
t.equal(ret.response, RESPONSE_BODY);
|
|
618
|
+
t.end();
|
|
619
|
+
|
|
620
|
+
// Close the test server, we are done with it.
|
|
621
|
+
testServer.close();
|
|
622
|
+
});
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
req.end(REQUEST_BODY);
|
|
626
|
+
});
|
|
554
627
|
|
|
555
|
-
superagent.get('http://google.com')
|
|
556
|
-
.query({q: 'test search' })
|
|
557
|
-
.end(function(res) {
|
|
558
|
-
nock.restore();
|
|
559
|
-
var ret = nock.recorder.play();
|
|
560
|
-
t.true(ret.length >= 1);
|
|
561
|
-
t.equal(ret[0].path, '/?q=test%20search');
|
|
562
|
-
t.end();
|
|
563
|
-
});
|
|
564
628
|
});
|
|
565
629
|
|
|
566
630
|
tap.test("teardown", function(t) {
|
|
@@ -572,4 +636,4 @@ tap.test("teardown", function(t) {
|
|
|
572
636
|
}
|
|
573
637
|
t.deepEqual(leaks, [], 'No leaks');
|
|
574
638
|
t.end();
|
|
575
|
-
});
|
|
639
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var assert = require('assert');
|
|
4
|
+
var test = require('tap').test;
|
|
5
|
+
var mikealRequest = require('request');
|
|
6
|
+
var nock = require('../');
|
|
7
|
+
|
|
8
|
+
test("follows refirects", function(t) {
|
|
9
|
+
nock('http://redirecter.com')
|
|
10
|
+
.get('/YourAccount')
|
|
11
|
+
.reply(302, undefined, {
|
|
12
|
+
'Location': 'http://redirecter.com/Login'
|
|
13
|
+
})
|
|
14
|
+
.get('/Login')
|
|
15
|
+
.reply(200, 'Here is the login page');
|
|
16
|
+
|
|
17
|
+
mikealRequest('http://redirecter.com/YourAccount', function(err, res, body) {
|
|
18
|
+
if (err) {
|
|
19
|
+
throw err;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
assert.equal(res.statusCode, 200);
|
|
23
|
+
|
|
24
|
+
assert.equal(body, 'Here is the login page');
|
|
25
|
+
t.end();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
});
|