UNPKG

twreporter-react

Version:

React-Redux site for The Reporter Foundation in Taiwan

2,180 lines (1,810 loc) 98.2 kB
'use strict'; var fs = require('fs'); var nock = require('../.'); var http = require('http'); var https = require('https'); var util = require('util'); var events = require('events'); var stream = require('stream'); var test = require('tap').test; var mikealRequest = require('request'); var superagent = require('superagent'); var needle = require("needle"); var restify = require('restify'); var domain = require('domain'); var hyperquest = require('hyperquest'); var globalCount; nock.enableNetConnect(); test("setup", function(t) { globalCount = Object.keys(global).length; t.end(); }); test("double activation throws exception", function(t) { nock.restore(); t.false(nock.isActive()); try { nock.activate(); t.true(nock.isActive()); nock.activate(); // This line should never be reached. t.false(true); } catch(e) { t.equal(e.toString(), 'Error: Nock already active'); } t.true(nock.isActive()); t.end(); }); test("allow override works (2)", function(t) { var scope = nock("https://httpbin.org",{allowUnmocked: true}). post("/post"). reply(200,"99problems"); var options = { method: "POST", uri: "https://httpbin.org/post", json: { some: "data" } }; mikealRequest(options, function(err, resp, body) { scope.done(); t.end(); return console.log(resp.statusCode, body); }); }); test("reply can take a callback", function(t) { var dataCalled = false; var scope = nock('http://www.google.com') .get('/') .reply(200, function(path, requestBody, callback) { callback(null, "Hello World!"); }); var req = http.request({ host: "www.google.com", path: '/', port: 80 }, function(res) { t.equal(res.statusCode, 200, "Status code is 200"); res.on('end', function() { t.ok(dataCalled, "data handler was called"); scope.done(); t.end(); }); res.on('data', function(data) { dataCalled = true; t.ok(data instanceof Buffer, "data should be buffer"); t.equal(data.toString(), "Hello World!", "response should match"); }); }); req.end(); }); test("reply should throw on error on the callback", function(t) { var dataCalled = false; var scope = nock('http://www.google.com') .get('/') .reply(500, function(path, requestBody, callback) { callback(new Error("Database failed")); }); var req = http.request({ host: "www.google.com", path: '/', port: 80 }, function(res) { t.equal(res.statusCode, 500, "Status code is 500"); res.on('data', function(data) { dataCalled = true; t.ok(data instanceof Buffer, "data should be buffer"); t.ok(data.toString().indexOf("Error: Database failed") === 0, "response should match"); }); res.on('end', function() { t.ok(dataCalled, "data handler was called"); scope.done(); t.end(); }); }); req.end(); }); test("get gets mocked", function(t) { var dataCalled = false; var scope = nock('http://www.google.com') .get('/') .reply(200, "Hello World!"); var req = http.request({ host: "www.google.com", path: '/', port: 80 }, function(res) { t.equal(res.statusCode, 200, "Status code is 200"); res.on('end', function() { t.ok(dataCalled, "data handler was called"); scope.done(); t.end(); }); res.on('data', function(data) { dataCalled = true; t.ok(data instanceof Buffer, "data should be buffer"); t.equal(data.toString(), "Hello World!", "response should match"); }); }); req.end(); }); test("get gets mocked with relative base path", function(t) { var dataCalled = false; var scope = nock('http://www.google.com/abc') .get('/def') .reply(200, "Hello World!"); var req = http.request({ host: "www.google.com", path: '/abc/def', port: 80 }, function(res) { t.equal(res.statusCode, 200); res.on('end', function() { t.ok(dataCalled); scope.done(); t.end(); }); res.on('data', function(data) { dataCalled = true; t.ok(data instanceof Buffer, "data should be buffer"); t.equal(data.toString(), "Hello World!", "response should match"); }); }); req.end(); }); test("post", function(t) { var dataCalled = false; var scope = nock('http://www.google.com') .post('/form') .reply(201, "OK!"); var req = http.request({ host: "www.google.com", method: 'POST', path: '/form', port: 80 }, function(res) { t.equal(res.statusCode, 201); res.on('end', function() { t.ok(dataCalled); scope.done(); t.end(); }); res.on('data', function(data) { dataCalled = true; t.ok(data instanceof Buffer, "data should be buffer"); t.equal(data.toString(), "OK!", "response should match"); }); }); req.end(); }); test("post with empty response body", function(t) { var scope = nock('http://www.google.com') .post('/form') .reply(200); var req = http.request({ host: "www.google.com", method: 'POST', path: '/form', port: 80 }, function(res) { t.equal(res.statusCode, 200); res.on('end', function() { scope.done(); t.end(); }); res.on('data', function() { t.fail("No body should be returned"); }); }); req.end(); }); test("post, lowercase", function(t) { var dataCalled = false; var scope = nock('http://www.google.com') .post('/form') .reply(200, "OK!"); var req = http.request({ host: "www.google.com", method: 'post', path: '/form', port: 80 }, function(res) { t.equal(res.statusCode, 200); res.on('end', function() { t.ok(dataCalled); scope.done(); t.end(); }); res.on('data', function(data) { dataCalled = true; t.ok(data instanceof Buffer, "data should be buffer"); t.equal(data.toString(), "OK!", "response should match"); }); }); req.end(); }); test("get with reply callback", function(t) { var scope = nock('http://www.google.com') .get('/') .reply(200, function() { return 'OK!'; }); var req = http.request({ host: "www.google.com", path: '/', port: 80 }, function(res) { res.on('end', function() { scope.done(); t.end(); }); res.on('data', function(data) { t.equal(data.toString(), 'OK!', 'response should match'); }); }); req.end(); }); test("get to different subdomain with reply callback and filtering scope", function(t) { // We scope for www.google.com but through scope filtering we // will accept any <subdomain>.google.com var scope = nock('http://www.google.com', { filteringScope: function(scope) { return /^http:\/\/.*\.google\.com/.test(scope); } }) .get('/') .reply(200, function() { return 'OK!'; }); var req = http.request({ host: "any-subdomain-will-do.google.com", path: '/', port: 80 }, function(res) { res.on('end', function() { scope.done(); t.end(); }); res.on('data', function(data) { t.equal(data.toString(), 'OK!', 'response should match'); }); }); req.end(); }); test("get with reply callback returning object", function(t) { var scope = nock('http://www.googlezzzz.com') .get('/') .reply(200, function() { return { message: 'OK!' }; }); var req = http.request({ host: "www.googlezzzz.com", path: '/', port: 80 }, function(res) { res.on('end', function() { scope.done(); t.end(); }); res.on('data', function(data) { t.equal(data.toString(), JSON.stringify({ message: 'OK!' }), 'response should match'); }); }); req.end(); }); test("post with reply callback, uri, and request body", function(t) { var input = 'key=val'; var scope = nock('http://www.google.com') .post('/echo', input) .reply(200, function(uri, body) { return ['OK', uri, body].join(' '); }); var req = http.request({ host: "www.google.com" , method: 'POST' , path: '/echo' , port: 80 }, function(res) { res.on('end', function() { scope.done(); t.end(); }); res.on('data', function(data) { t.equal(data.toString(), 'OK /echo key=val' , 'response should match'); }); }); req.write(input); req.end(); }); test("post with regexp as spec", function(t) { var scope = nock('http://www.google.com') .post('/echo', /key=v.?l/g) .reply(200, function(uri, body) { return ['OK', uri, body].join(' '); }); var req = http.request({ host: "www.google.com" , method: 'POST' , path: '/echo' , port: 80 }, function(res) { res.on('end', function() { scope.done(); t.end(); }); res.on('data', function(data) { t.equal(data.toString(), 'OK /echo key=val' , 'response should match'); }); }); req.write('key=val'); req.end(); }); test("post with function as spec", function(t) { var scope = nock('http://www.google.com') .post('/echo', function(body) { return body === 'key=val'; }) .reply(200, function(uri, body) { return ['OK', uri, body].join(' '); }); var req = http.request({ host: "www.google.com" , method: 'POST' , path: '/echo' , port: 80 }, function(res) { res.on('end', function() { scope.done(); t.end(); }); res.on('data', function(data) { t.equal(data.toString(), 'OK /echo key=val' , 'response should match'); }); }); req.write('key=val'); req.end(); }); test("post with chaining on call", function(t) { var input = 'key=val'; var scope = nock('http://www.google.com') .post('/echo', input) .reply(200, function(uri, body) { return ['OK', uri, body].join(' '); }); var req = http.request({ host: "www.google.com" , method: 'POST' , path: '/echo' , port: 80 }, function(res) { res.on('end', function() { scope.done(); t.end(); }); res.on('data', function(data) { t.equal(data.toString(), 'OK /echo key=val' , 'response should match'); }); }).on('error', function(error){ t.equal(error, null); t.end(); }); req.end(input); }); test("reply with callback and filtered path and body", function(t) { var noPrematureExecution = false; var scope = nock('http://www.realcallback.com') .filteringPath(/.*/, '*') .filteringRequestBody(/.*/, '*') .post('*', '*') .reply(200, function(uri, body) { t.assert(noPrematureExecution); return ['OK', uri, body].join(' '); }); var req = http.request({ host: "www.realcallback.com" , method: 'POST' , path: '/original/path' , port: 80 }, function(res) { t.equal(res.statusCode, 200); res.on('end', function() { scope.done(); t.end(); }); res.on('data', function(data) { t.equal(data.toString(), 'OK /original/path original=body' , 'response should match'); }); }); noPrematureExecution = true; req.end('original=body'); }); test("isDone", function(t) { var scope = nock('http://www.google.com') .get('/') .reply(200, "Hello World!"); t.notOk(scope.isDone(), "not done when a request is outstanding"); var req = http.request({ host: "www.google.com" , path: '/' , port: 80 }, function(res) { t.equal(res.statusCode, 200); res.on('end', function() { t.ok(scope.isDone(), "done after request is made"); scope.done(); t.end(); }); // Streams start in 'paused' mode and must be started. // See https://nodejs.org/api/stream.html#stream_class_stream_readable res.resume(); }); req.end(); }); test("requireDone", function(t) { var scope = nock('http://www.google.com') .get('/', false, { requireDone: false }) .reply(200, "Hello World!"); t.ok(scope.isDone(), "done when a requireDone is set to false"); scope.get('/', false, { requireDone: true}) .reply(200, "Hello World!"); t.notOk(scope.isDone(), "not done when a requireDone is explicitly set to true"); nock.cleanAll() t.end(); }); test("request headers exposed", function(t) { var scope = nock('http://www.headdy.com') .get('/') .reply(200, "Hello World!", {'X-My-Headers': 'My Header value'}); var req = http.get({ host: "www.headdy.com" , method: 'GET' , path: '/' , port: 80 , headers: {'X-My-Headers': 'My custom Header value'} }, function(res) { res.on('end', function() { scope.done(); t.end(); }); // Streams start in 'paused' mode and must be started. // See https://nodejs.org/api/stream.html#stream_class_stream_readable res.resume(); }); t.equivalent(req._headers, {'x-my-headers': 'My custom Header value', 'host': 'www.headdy.com'}); }); test("headers work", function(t) { var scope = nock('http://www.headdy.com') .get('/') .reply(200, "Hello World!", {'X-My-Headers': 'My Header value'}); var req = http.request({ host: "www.headdy.com" , method: 'GET' , path: '/' , port: 80 }, function(res) { t.equal(res.statusCode, 200); res.on('end', function() { t.equivalent(res.headers, {'x-my-headers': 'My Header value'}); scope.done(); t.end(); }); // Streams start in 'paused' mode and must be started. // See https://nodejs.org/api/stream.html#stream_class_stream_readable res.resume(); }); req.end(); }); test("reply headers work with function", function(t) { var scope = nock('http://replyheadersworkwithfunction.xxx') .get('/') .reply(200, function() { return 'ABC'; }, {'X-My-Headers': 'My custom header value'}); var req = http.get({ host: "replyheadersworkwithfunction.xxx", path: '/', port: 80 }, function(res) { t.equivalent(res.headers, {'x-my-headers': 'My custom header value'}); scope.done(); t.end(); }); }); test("reply headers as function work", function(t) { var scope = nock('http://example.com') .get('/') .reply(200, 'boo!', { 'X-My-Headers': function (req, res, body) { return body.toString(); } }); var req = http.get({ host: 'example.com', path: '/' }, function (res) { t.equivalent(res.headers, { 'x-my-headers': 'boo!' }); t.equivalent(res.rawHeaders, ['x-my-headers', 'boo!']); // 67 t.end(); }); }); test("match headers", function(t) { var scope = nock('http://www.headdy.com') .get('/') .matchHeader('x-my-headers', 'My custom Header value') .reply(200, "Hello World!"); http.get({ host: "www.headdy.com" , method: 'GET' , path: '/' , port: 80 , headers: {'X-My-Headers': 'My custom Header value'} }, function(res) { res.setEncoding('utf8'); t.equal(res.statusCode, 200); res.on('data', function(data) { t.equal(data, 'Hello World!'); }); res.on('end', function() { scope.done(); t.end(); }); }); }); test("multiple match headers", function(t) { var scope = nock('http://www.headdy.com') .get('/') .matchHeader('x-my-headers', 'My custom Header value') .reply(200, "Hello World!") .get('/') .matchHeader('x-my-headers', 'other value') .reply(200, "Hello World other value!"); http.get({ host: "www.headdy.com" , method: 'GET' , path: '/' , port: 80 , headers: {'X-My-Headers': 'other value'} }, function(res) { res.setEncoding('utf8'); t.equal(res.statusCode, 200); res.on('data', function(data) { t.equal(data, 'Hello World other value!'); }); res.on('end', function() { http.get({ host: "www.headdy.com" , method: 'GET' , path: '/' , port: 80 , headers: {'X-My-Headers': 'My custom Header value'} }, function(res) { res.setEncoding('utf8'); t.equal(res.statusCode, 200); res.on('data', function(data) { t.equal(data, 'Hello World!'); }); res.on('end', function() { scope.done(); t.end(); }); }); }); }); }); test("match headers with regexp", function(t) { var scope = nock('http://www.headier.com') .get('/') .matchHeader('x-my-headers', /My He.d.r [0-9.]+/) .reply(200, "Hello World!"); http.get({ host: "www.headier.com" , method: 'GET' , path: '/' , port: 80 , headers: {'X-My-Headers': 'My Header 1.0'} }, function(res) { res.setEncoding('utf8'); t.equal(res.statusCode, 200); res.on('data', function(data) { t.equal(data, 'Hello World!'); }); res.on('end', function() { scope.done(); t.end(); }); }); }); test("match headers on number with regexp", function(t) { var scope = nock('http://www.headier.com') .get('/') .matchHeader('x-my-headers', /\d+/) .reply(200, "Hello World!"); http.get({ host: "www.headier.com" , method: 'GET' , path: '/' , port: 80 , headers: {'X-My-Headers': 123} }, function(res) { res.setEncoding('utf8'); t.equal(res.statusCode, 200); res.on('data', function(data) { t.equal(data, 'Hello World!'); }); res.on('end', function() { scope.done(); t.end(); }); }); }); test("match headers with function", function(t) { var scope = nock('http://www.headier.com') .get('/') .matchHeader('x-my-headers', function (val) { return val > 123; }) .reply(200, "Hello World!"); http.get({ host: "www.headier.com" , method: 'GET' , path: '/' , port: 80 , headers: {'X-My-Headers': 456} }, function(res) { res.setEncoding('utf8'); t.equal(res.statusCode, 200); res.on('data', function(data) { t.equal(data, 'Hello World!'); }); res.on('end', function() { scope.done(); t.end(); }); }); }); test("match all headers", function(t) { var scope = nock('http://api.headdy.com') .matchHeader('accept', 'application/json') .get('/one') .reply(200, { hello: "world" }) .get('/two') .reply(200, { a: 1, b: 2, c: 3 }); var ended = 0; function callback() { ended += 1; if (ended === 2) { scope.done(); t.end(); } } http.get({ host: "api.headdy.com" , path: '/one' , port: 80 , headers: {'Accept': 'application/json'} }, function(res) { res.setEncoding('utf8'); t.equal(res.statusCode, 200); res.on('data', function(data) { t.equal(data, '{"hello":"world"}'); }); res.on('end', callback); }); http.get({ host: "api.headdy.com" , path: '/two' , port: 80 , headers: {'accept': 'application/json'} }, function(res) { res.setEncoding('utf8'); t.equal(res.statusCode, 200); res.on('data', function(data) { t.equal(data, '{"a":1,"b":2,"c":3}'); }); res.on('end', callback); }); }); test("header manipulation", function(t) { var scope = nock('http://example.com') .get('/accounts') .reply(200, { accounts: [{ id: 1, name: 'Joe Blow' }] }) , req; req = http.get({ host: 'example.com', path: '/accounts' }, function (res) { res.on('end', function () { scope.done(); t.end(); }); // Streams start in 'paused' mode and must be started. // See https://nodejs.org/api/stream.html#stream_class_stream_readable res.resume(); }); req.setHeader('X-Custom-Header', 'My Value'); t.equal(req.getHeader('X-Custom-Header'), 'My Value', 'Custom header was not set'); req.removeHeader('X-Custom-Header'); t.notOk(req.getHeader('X-Custom-Header'), 'Custom header was not removed'); req.end(); }); test("head", function(t) { var dataCalled = false; var scope = nock('http://www.google.com') .head('/form') .reply(201, "OK!"); var req = http.request({ host: "www.google.com" , method: 'HEAD' , path: '/form' , port: 80 }, function(res) { t.equal(res.statusCode, 201); res.on('end', function() { scope.done(); t.end(); }); // Streams start in 'paused' mode and must be started. // See https://nodejs.org/api/stream.html#stream_class_stream_readable res.resume(); }); req.end(); }); test("body data is differentiating", function(t) { var doneCount = 0 , scope = nock('http://www.boddydiff.com') .post('/', 'abc') .reply(200, "Hey 1") .post('/', 'def') .reply(200, "Hey 2"); function done(t) { doneCount += 1; t.end(); }; t.test("A", function(t) { var req = http.request({ host: "www.boddydiff.com" , method: 'POST' , path: '/' , port: 80 }, function(res) { var dataCalled = false; t.equal(res.statusCode, 200); res.on('end', function() { t.ok(dataCalled); done(t); }); res.on('data', function(data) { dataCalled = true; t.ok(data instanceof Buffer, "data should be buffer"); t.equal(data.toString(), "Hey 1", "response should match"); }); }); req.end('abc'); }); t.test("B", function(t) { var req = http.request({ host: "www.boddydiff.com" , method: 'POST' , path: '/' , port: 80 }, function(res) { var dataCalled = false; t.equal(res.statusCode, 200); res.on('end', function() { t.ok(dataCalled); done(t); }); res.on('data', function(data) { dataCalled = true; t.ok(data instanceof Buffer, "data should be buffer"); t.equal(data.toString(), "Hey 2", "response should match"); }); }); req.end('def'); }); }); test("chaining", function(t) { var repliedCount = 0; var scope = nock('http://www.spiffy.com') .get('/') .reply(200, "Hello World!") .post('/form') .reply(201, "OK!"); function endOne(t) { repliedCount += 1; if (t === 2) { scope.done(); } t.end(); } t.test("post", function(t) { var dataCalled; var req = http.request({ host: "www.spiffy.com" , method: 'POST' , path: '/form' , port: 80 }, function(res) { t.equal(res.statusCode, 201); res.on('end', function() { t.ok(dataCalled); endOne(t); }); res.on('data', function(data) { dataCalled = true; t.ok(data instanceof Buffer, "data should be buffer"); t.equal(data.toString(), "OK!", "response should match"); }); }); req.end(); }); t.test("get", function(t) { var dataCalled; var req = http.request({ host: "www.spiffy.com" , method: 'GET' , path: '/' , port: 80 }, function(res) { t.equal(res.statusCode, 200); res.on('end', function() { t.ok(dataCalled); scope.done(); t.end(); }); res.on('data', function(data) { dataCalled = true; t.ok(data instanceof Buffer, "data should be buffer"); t.equal(data.toString(), "Hello World!", "response should match"); }); }); req.end(); }); }); test("encoding", function(t) { var dataCalled = false var scope = nock('http://www.encoderz.com') .get('/') .reply(200, "Hello World!"); var req = http.request({ host: "www.encoderz.com" , path: '/' , port: 80 }, function(res) { res.setEncoding('base64'); t.equal(res.statusCode, 200); res.on('end', function() { t.ok(dataCalled); scope.done(); t.end(); }); res.on('data', function(data) { dataCalled = true; t.type(data, 'string', "data should be string"); t.equal(data, "SGVsbG8gV29ybGQh", "response should match base64 encoding"); }); }); req.end(); }); test("reply with file", function(t) { var dataCalled = false var scope = nock('http://www.filereplier.com') .get('/') .replyWithFile(200, __dirname + '/../assets/reply_file_1.txt') .get('/test') .reply(200, 'Yay!'); var req = http.request({ host: "www.filereplier.com" , path: '/' , port: 80 }, function(res) { t.equal(res.statusCode, 200); res.on('end', function() { t.ok(dataCalled); t.end(); }); res.on('data', function(data) { dataCalled = true; t.equal(data.toString(), "Hello from the file!", "response should match"); }); }); req.end(); }); test("reply with file and pipe response", function(t) { var scope = nock('http://www.files.com') .get('/') .replyWithFile(200, __dirname + '/../assets/reply_file_1.txt') var req = http.get({ host: "www.files.com" , path: '/' , port: 80 }, function(res) { var str = ''; var fakeStream = new(require('stream').Stream); fakeStream.writable = true; fakeStream.write = function(d) { str += d; }; fakeStream.end = function() { t.equal(str, "Hello from the file!", "response should match"); t.end(); }; res.pipe(fakeStream); res.setEncoding('utf8'); t.equal(res.statusCode, 200); }); }); test("reply with file with headers", function(t) { var dataCalled = false var scope = nock('http://www.filereplier2.com') .get('/') .replyWithFile(200, __dirname + '/../assets/reply_file_2.txt.gz', { 'content-encoding': 'gzip' }); var req = http.request({ host: "www.filereplier2.com" , path: '/' , port: 80 }, function(res) { t.equal(res.statusCode, 200); res.on('end', function() { t.ok(dataCalled); t.end(); }); res.on('data', function(data) { dataCalled = true; t.equal(data.length, 57); }); }); req.end(); }); test("reply with file with mikeal/request", function(t) { var scope = nock('http://www.files.com') .get('/') .replyWithFile(200, __dirname + '/../assets/reply_file_1.txt') var options = { uri: 'http://www.files.com/', onResponse: true }; mikealRequest('http://www.files.com/', function(err, res, body) { if (err) { throw err; } res.setEncoding('utf8'); t.equal(res.statusCode, 200); t.equal(body, "Hello from the file!", "response should match"); t.end(); }); }); test("reply with JSON", function(t) { var dataCalled = false var scope = nock('http://www.jsonreplier.com') .get('/') .reply(200, {hello: "world"}); var req = http.request({ host: "www.jsonreplier.com" , path: '/' , port: 80 }, function(res) { res.setEncoding('utf8'); t.equal(res.statusCode, 200); t.notOk(res.headers['date']); t.notOk(res.headers['content-length']); t.equal(res.headers['content-type'], 'application/json'); res.on('end', function() { t.ok(dataCalled); scope.done(); t.end(); }); res.on('data', function(data) { dataCalled = true; t.equal(data.toString(), '{"hello":"world"}', "response should match"); }); }); req.end(); }); test("reply with content-length header", function(t){ var scope = nock('http://www.jsonreplier.com') .replyContentLength() .get('/') .reply(200, {hello: "world"}); var req = http.get({ host: "www.jsonreplier.com" , path: '/' , port: 80 }, function(res) { t.equal(res.headers['content-length'], 17); res.on('end', function() { scope.done(); t.end(); }); // Streams start in 'paused' mode and must be started. // See https://nodejs.org/api/stream.html#stream_class_stream_readable res.resume(); }); }); test("reply with date header", function(t){ var date = new Date(); var scope = nock('http://www.jsonreplier.com') .replyDate(date) .get('/') .reply(200, {hello: "world"}); var req = http.get({ host: "www.jsonreplier.com" , path: '/' , port: 80 }, function(res) { console.error(res.headers); t.equal(res.headers['date'], date.toUTCString()); res.on('end', function() { scope.done(); t.end(); }); // Streams start in 'paused' mode and must be started. // See https://nodejs.org/api/stream.html#stream_class_stream_readable res.resume(); }); }); test("filter path with function", function(t) { var scope = nock('http://www.filterurls.com') .filteringPath(function(path) { return '/?a=2&b=1'; }) .get('/?a=2&b=1') .reply(200, "Hello World!"); var req = http.request({ host: "www.filterurls.com" , method: 'GET' , path: '/?a=1&b=2' , port: 80 }, function(res) { t.equal(res.statusCode, 200); res.on('end', function() { scope.done(); t.end(); }); // Streams start in 'paused' mode and must be started. // See https://nodejs.org/api/stream.html#stream_class_stream_readable res.resume(); }); req.end(); }); test("filter path with regexp", function(t) { var scope = nock('http://www.filterurlswithregexp.com') .filteringPath(/\d/g, '3') .get('/?a=3&b=3') .reply(200, "Hello World!"); var req = http.request({ host: "www.filterurlswithregexp.com" , method: 'GET' , path: '/?a=1&b=2' , port: 80 }, function(res) { t.equal(res.statusCode, 200); res.on('end', function() { scope.done(); t.end(); }); // Streams start in 'paused' mode and must be started. // See https://nodejs.org/api/stream.html#stream_class_stream_readable res.resume(); }); req.end(); }); test("filter body with function", function(t) { var filteringRequestBodyCounter = 0; var scope = nock('http://www.filterboddiez.com') .filteringRequestBody(function(body) { ++filteringRequestBodyCounter; t.equal(body, 'mamma mia'); return 'mamma tua'; }) .post('/', 'mamma tua') .reply(200, "Hello World!"); var req = http.request({ host: "www.filterboddiez.com" , method: 'POST' , path: '/' , port: 80 }, function(res) { t.equal(res.statusCode, 200); res.on('end', function() { scope.done(); t.equal(filteringRequestBodyCounter, 1); t.end(); }); // Streams start in 'paused' mode and must be started. // See https://nodejs.org/api/stream.html#stream_class_stream_readable res.resume(); }); req.end('mamma mia'); }); test("filter body with regexp", function(t) { var scope = nock('http://www.filterboddiezregexp.com') .filteringRequestBody(/mia/, 'nostra') .post('/', 'mamma nostra') .reply(200, "Hello World!"); var req = http.request({ host: "www.filterboddiezregexp.com" , method: 'POST' , path: '/' , port: 80 }, function(res) { t.equal(res.statusCode, 200); res.on('end', function() { scope.done(); t.end(); }); // Streams start in 'paused' mode and must be started. // See https://nodejs.org/api/stream.html#stream_class_stream_readable res.resume(); }); req.end('mamma mia'); }); test("abort request", function(t) { var scope = nock('http://www.google.com') .get('/hey') .reply(200, 'nobody'); var req = http.request({ host: 'www.google.com' , path: '/hey' }); req.on('response', function(res) { res.on('close', function(err) { t.equal(err.code, 'aborted'); scope.done(); t.end(); }); res.on('end', function() { t.true(false, 'this should never execute'); }); req.abort(); }); req.end(); }); test("pause response before data", function(t) { var scope = nock('http://www.mouse.com') .get('/pauser') .reply(200, 'nobody'); var req = http.request({ host: 'www.mouse.com' , path: '/pauser' }); req.on('response', function(res) { res.pause(); var waited = false; setTimeout(function() { waited = true; res.resume(); }, 500); res.on('data', function(data) { t.true(waited); }); res.on('end', function() { scope.done(); t.end(); }); }); req.end(); }); test("pause response after data", function(t) { var response = new stream.PassThrough(); var scope = nock('http://pauseme.com') .get('/') // Node does not pause the 'end' event so we need to use a stream to simulate // multiple 'data' events. .reply(200, response); var req = http.get({ host: 'pauseme.com' , path: '/' }, function(res) { var waited = false; setTimeout(function() { waited = true; res.resume(); }, 500); res.on('data', function(data) { res.pause(); }); res.on('end', function() { t.true(waited); scope.done(); t.end(); }); }); // Manually simulate multiple 'data' events. response.emit("data", "one"); setTimeout(function () { response.emit("data", "two"); response.end(); }, 0); }); test("response pipe", function(t) { var dest = (function() { function Constructor() { events.EventEmitter.call(this); this.buffer = new Buffer(0); this.writable = true; } util.inherits(Constructor, events.EventEmitter); Constructor.prototype.end = function() { this.emit('end'); }; Constructor.prototype.write = function(chunk) { var buf = new Buffer(this.buffer.length + chunk.length); this.buffer.copy(buf); chunk.copy(buf, this.buffer.length); this.buffer = buf; return true; }; return new Constructor(); })(); var scope = nock('http://pauseme.com') .get('/') .reply(200, 'nobody'); var req = http.get({ host: 'pauseme.com' , path: '/' }, function(res) { dest.on('pipe', function() { t.pass('should emit "pipe" event') }); dest.on('end', function() { scope.done(); t.equal(dest.buffer.toString(), 'nobody'); t.end(); }); res.pipe(dest); }); }); test("response pipe without implicit end", function(t) { var dest = (function() { function Constructor() { events.EventEmitter.call(this); this.buffer = new Buffer(0); this.writable = true; } util.inherits(Constructor, events.EventEmitter); Constructor.prototype.end = function() { this.emit('end'); }; Constructor.prototype.write = function(chunk) { var buf = new Buffer(this.buffer.length + chunk.length); this.buffer.copy(buf); chunk.copy(buf, this.buffer.length); this.buffer = buf; return true; }; return new Constructor(); })(); var scope = nock('http://pauseme.com') .get('/') .reply(200, 'nobody'); var req = http.get({ host: 'pauseme.com' , path: '/' }, function(res) { dest.on('end', function() { t.fail('should not call end implicitly'); }); res.on('end', function() { scope.done(); t.pass('should emit end event'); t.end(); }); res.pipe(dest, {end: false}); }); }); test("chaining API", function(t) { var scope = nock('http://chainchomp.com') .get('/one') .reply(200, 'first one') .get('/two') .reply(200, 'second one'); http.get({ host: 'chainchomp.com' , path: '/one' }, function(res) { res.setEncoding('utf8'); t.equal(res.statusCode, 200, 'status should be ok'); res.on('data', function(data) { t.equal(data, 'first one', 'should be equal to first reply'); }); res.on('end', function() { http.get({ host: 'chainchomp.com' , path: '/two' }, function(res) { res.setEncoding('utf8'); t.equal(res.statusCode, 200, 'status should be ok'); res.on('data', function(data) { t.equal(data, 'second one', 'should be qual to second reply'); }); res.on('end', function() { scope.done(); t.end(); }); }); }); }); }); test("same URI", function(t) { var scope = nock('http://sameurii.com') .get('/abc') .reply(200, 'first one') .get('/abc') .reply(200, 'second one'); http.get({ host: 'sameurii.com' , path: '/abc' }, function(res) { res.on('data', function(data) { res.setEncoding('utf8'); t.equal(data.toString(), 'first one', 'should be qual to first reply'); res.on('end', function() { http.get({ host: 'sameurii.com' , path: '/abc' }, function(res) { res.setEncoding('utf8'); res.on('data', function(data) { t.equal(data.toString(), 'second one', 'should be qual to second reply'); res.on('end', function() { scope.done(); t.end(); }); }); }); }); }); }); }); test("can use hostname instead of host", function(t) { var scope = nock('http://www.google.com') .get('/') .reply(200, "Hello World!"); var req = http.request({ hostname: "www.google.com" , path: '/' }, function(res) { t.equal(res.statusCode, 200); res.on('end', function() { scope.done(); t.end(); }); // Streams start in 'paused' mode and must be started. // See https://nodejs.org/api/stream.html#stream_class_stream_readable res.resume(); }); req.end(); }); test('hostname is case insensitive', function(t) { var scope = nock('http://caseinsensitive.com') .get('/path') .reply(200, "hey"); var options = { hostname: 'cASEinsensitivE.com', path: '/path', method: 'GET' }; var req = http.request(options, function(res) { scope.done(); t.end(); }); req.end(); }); test("can take a port", function(t) { var scope = nock('http://www.myserver.com:3333') .get('/') .reply(200, "Hello World!"); var req = http.request({ hostname: "www.myserver.com" , path: '/' , port: 3333 }, function(res) { t.equal(res.statusCode, 200); res.on('end', function() { scope.done(); t.end(); }); // Streams start in 'paused' mode and must be started. // See https://nodejs.org/api/stream.html#stream_class_stream_readable res.resume(); }); req.end(); }); test("can use https", function(t) { var dataCalled = false var scope = nock('https://google.com') .get('/') .reply(200, "Hello World!"); var req = https.request({ host: "google.com" , path: '/' }, function(res) { t.equal(res.statusCode, 200); res.on('end', function() { t.ok(dataCalled, 'data event called'); scope.done(); t.end(); }); res.on('data', function(data) { dataCalled = true; t.ok(data instanceof Buffer, "data should be buffer"); t.equal(data.toString(), "Hello World!", "response should match"); }); }); req.end(); }); test("emits error if https route is missing", function(t) { var dataCalled = false var scope = nock('https://google.com') .get('/') .reply(200, "Hello World!"); var req = https.request({ host: "google.com" , path: '/abcdef892932' }, function(res) { throw new Error('should not come here!'); }); req.end(); // This listener is intentionally after the end call so make sure that // listeners added after the end will catch the error req.on('error', function (err) { t.equal(err.message.trim(), 'Nock: No match for request GET https://google.com/abcdef892932'); t.end(); }); }); test("emits error if https route is missing", function(t) { var dataCalled = false var scope = nock('https://google.com:123') .get('/') .reply(200, "Hello World!"); var req = https.request({ host: "google.com", port: 123, path: '/dsadsads' }, function(res) { throw new Error('should not come here!'); }); req.end(); // This listener is intentionally after the end call so make sure that // listeners added after the end will catch the error req.on('error', function (err) { t.equal(err.message.trim(), 'Nock: No match for request GET https://google.com:123/dsadsads'); t.end(); }); }); test("can use ClientRequest using GET", function(t) { var dataCalled = false var scope = nock('http://www2.clientrequester.com') .get('/dsad') .reply(202, "HEHE!"); var req = new http.ClientRequest({ host: "www2.clientrequester.com" , path: '/dsad' }); req.end(); req.on('response', function(res) { t.equal(res.statusCode, 202); res.on('end', function() { t.ok(dataCalled, "data event was called"); scope.done(); t.end(); }); res.on('data', function(data) { dataCalled = true; t.ok(data instanceof Buffer, "data should be buffer"); t.equal(data.toString(), "HEHE!", "response should match"); }); }); req.end(); }); test("can use ClientRequest using POST", function(t) { var dataCalled = false var scope = nock('http://www2.clientrequester.com') .post('/posthere/please', 'heyhey this is the body') .reply(201, "DOOONE!"); var req = new http.ClientRequest({ host: "www2.clientrequester.com" , path: '/posthere/please' , method: 'POST' }); req.write('heyhey this is the body'); req.end(); req.on('response', function(res) { t.equal(res.statusCode, 201); res.on('end', function() { t.ok(dataCalled, "data event was called"); scope.done(); t.end(); }); res.on('data', function(data) { dataCalled = true; t.ok(data instanceof Buffer, "data should be buffer"); t.equal(data.toString(), "DOOONE!", "response should match"); }); }); req.end(); }); test("same url matches twice", function(t) { var scope = nock('http://www.twicematcher.com') .get('/hey') .reply(200, "First match") .get('/hey') .reply(201, "Second match"); var replied = 0; function callback() { replied += 1; if (replied == 2) { scope.done(); t.end(); } } http.get({ host: "www.twicematcher.com" , path: '/hey' }, function(res) { t.equal(res.statusCode, 200); res.on('data', function(data) { t.equal(data.toString(), 'First match', 'should match first request response body'); }); res.on('end', callback); }); http.get({ host: "www.twicematcher.com" , path: '/hey' }, function(res) { t.equal(res.statusCode, 201); res.on('data', function(data) { t.equal(data.toString(), 'Second match', 'should match second request response body'); }); res.on('end', callback); }); }); test("scopes are independent", function(t) { var scope1 = nock('http://www34.google.com') .get('/') .reply(200, "Hello World!"); var scope2 = nock('http://www34.google.com') .get('/') .reply(200, "Hello World!"); var req = http.request({ host: "www34.google.com" , path: '/' , port: 80 }, function(res) { res.on('end', function() { t.ok(scope1.isDone()); t.ok(! scope2.isDone()); // fails t.end(); }); // Streams start in 'paused' mode and must be started. // See https://nodejs.org/api/stream.html#stream_class_stream_readable res.resume(); }); req.end(); }); test("two scopes with the same request are consumed", function(t) { var scope1 = nock('http://www36.google.com') .get('/') .reply(200, "Hello World!"); var scope2 = nock('http://www36.google.com') .get('/') .reply(200, "Hello World!"); var doneCount = 0; function done() { doneCount += 1; if (doneCount == 2) { t.end(); } } for (var i = 0; i < 2; i += 1) { var req = http.request({ host: "www36.google.com" , path: '/' , port: 80 }, function(res) { res.on('end', done); // Streams start in 'paused' mode and must be started. // See https://nodejs.org/api/stream.html#stream_class_stream_readable res.resume(); }); req.end(); } }); test("allow unmocked option works", function(t) { var scope = nock('http://www.google.com', {allowUnmocked: true}) .get('/abc') .reply(200, 'Hey!') .get('/wont/get/here') .reply(200, 'Hi!'); function secondIsDone() { t.ok(! scope.isDone()); http.request({ host: "www.google.com" , path: "/" , port: 80 }, function(res) { res.destroy(); t.assert(res.statusCode < 400 && res.statusCode >= 200, 'GET Google Home page'); t.end(); } ).end(); } function firstIsDone() { t.ok(! scope.isDone()); http.request({ host: "www.google.com" , path: "/does/not/exist/dskjsakdj" , port: 80 }, function(res) { t.assert(res.statusCode === 404, 'Google say it does not exist'); res.on('data', function() {}); res.on('end', secondIsDone); } ).end(); } http.request({ host: "www.google.com" , path: "/abc" , port: 80 }, function(res) { res.on('end', firstIsDone); // Streams start in 'paused' mode and must be started. // See https://nodejs.org/api/stream.html#stream_class_stream_readable res.resume(); } ).end(); }); test("default reply headers work", function(t) { var scope = nock('http://default.reply.headers.com') .defaultReplyHeaders({'X-Powered-By': 'Meeee', 'X-Another-Header': 'Hey man!'}) .get('/') .reply(200, '', {A: 'b'}); function done(res) { t.deepEqual(res.headers, {'x-powered-by': 'Meeee', 'x-another-header': 'Hey man!', a: 'b'}); t.end(); } http.request({ host: 'default.reply.headers.com' , path: '/' }, done).end(); }); test("default reply headers as functions work", function(t) { var date = (new Date()).toUTCString(); var message = 'A message.'; var scope = nock('http://default.reply.headers.com') .defaultReplyHeaders({ 'Content-Length' : function (req, res, body) { return body.length; }, 'Date': function () { return date; }, 'Foo': function () { return 'foo'; } }) .get('/') .reply(200, message, {foo: 'bar'}); http.request({ host: 'default.reply.headers.com', path: '/' }, function (res) { t.deepEqual( res.headers, { 'content-length': message.length, 'date': date, 'foo': 'bar' } ); t.end(); } ).end(); }); test("JSON encoded replies set the content-type header", function(t) { var scope = nock('http://localhost') .get('/') .reply(200, { A: 'b' }); function done(res) { scope.done(); t.equal(res.statusCode, 200); t.equal(res.headers['content-type'], 'application/json'); t.end(); } http.request({ host: 'localhost' , path: '/' }, done).end(); }); test("JSON encoded replies does not overwrite existing content-type header", function(t) { var scope = nock('http://localhost') .get('/') .reply(200, { A: 'b' }, { 'Content-Type': 'unicorns' }); function done(res) { scope.done(); t.equal(res.statusCode, 200); t.equal(res.headers['content-type'], 'unicorns'); t.end(); } http.request({ host: 'localhost' , path: '/' }, done).end(); }); test("blank response doesn't have content-type application/json attached to it", function(t) { var scope = nock('http://localhost') .get('/') .reply(200); function done(res) { t.equal(res.statusCode, 200); t.notEqual(res.headers['content-type'], "application/json"); t.end(); } http.request({ host: 'localhost' , path: '/' }, done).end(); }); test('clean all works', function(t) { var scope = nock('http://amazon.com') .get('/nonexistent') .reply(200); var req = http.get({host: 'amazon.com', path: '/nonexistent'}, function(res) { t.assert(res.statusCode === 200, "should mock before cleanup"); nock.cleanAll(); var req = http.get({host: 'amazon.com', path: '/nonexistent'}, function(res) { res.destroy(); t.assert(res.statusCode !== 200, "should clean up properly"); t.end(); }).on('error', function(err) { t.end(); }); }); }); test('is done works', function(t) { var scope = nock('http://amazon.com') .get('/nonexistent') .reply(200); t.ok(!nock.isDone()); var req = http.get({host: 'amazon.com', path: '/nonexistent'}, function(res) { t.assert(res.statusCode === 200, "should mock before cleanup"); t.ok(nock.isDone()); t.end(); }); }); test('pending mocks works', function(t) { var scope = nock('http://amazon.com') .get('/nonexistent') .reply(200); t.deepEqual(nock.pendingMocks(), ['GET http://amazon.com:80/nonexistent']); var req = http.get({host: 'amazon.com', path: '/nonexistent'}, function(res) { t.assert(res.statusCode === 200, "should mock before cleanup"); t.deepEqual(nock.pendingMocks(), []); t.end(); }); }); test('username and password works', function(t) { var scope = nock('http://passwordyy.com') .get('/') .reply(200, "Welcome, username"); http.request({ hostname: 'passwordyy.com', auth: "username:password", path: '/' }, function(res) { scope.done(); t.end(); }).end(); }); test('works with mikeal/request and username and password', function(t) { var scope = nock('http://passwordyyyyy.com') .get('/abc') .reply(200, "Welcome, username"); mikealRequest({uri: 'http://username:password@passwordyyyyy.com/abc', log:true}, function(err, res, body) { t.ok(! err, 'error'); t.ok(scope.isDone());