Repository: node-nock/nock
Pull request #1122 (2018-05-07 19:12:32)

adding a failing test for issue#1121
fixes https://github.com/node-nock/nock/issues/1121
main idea: `set-cookie` and `Set-Cookie` should merge into the same array
maybe apply `toLowerCase` to all "rawHeaders" entry?
which makes the expected return to have all lower-case keys

gr2m: yeah that could work. Wanna give it a try and see if it breaks other tests?
cjzcpsyx: @gr2m There are actually 5 other tests are breaking when I had the clean fork from latest development version. And I will pull up some changes for the issue I opened, and we can talk about it
gr2m: sounds good, thanks!

Patch:
diff --git a/lib/common.js b/lib/common.js
index 932259e..fb03dac 100644
--- a/lib/common.js
+++ b/lib/common.js
@@ -266,7 +266,7 @@ var headersArrayToObject = function (rawHeaders) {
   var headers = {};
 
   for (var i=0, len=rawHeaders.length; i<len; i=i+2) {
-    var key = rawHeaders[i];
+    var key = rawHeaders[i].toLowerCase();
     var value = rawHeaders[i+1];
 
     if (headers[key]) {


Test patch:
diff --git a/tests/test_common.js b/tests/test_common.js
index 98931ba..3361727 100644
--- a/tests/test_common.js
+++ b/tests/test_common.js
@@ -228,25 +228,28 @@ tap.test('headersArrayToObject', function (t) {
   ];
 
   t.deepEqual(common.headersArrayToObject(headers), {
-    "Content-Type": "application/json; charset=utf-8",
-    "Last-Modified": "foobar",
-    "Expires": "fizbuzz"
+    "content-type": "application/json; charset=utf-8",
+    "last-modified": "foobar",
+    "expires": "fizbuzz"
   });
 
   var headersMultipleSetCookies = headers.concat([
     "Set-Cookie",
     "foo=bar; Domain=.github.com; Path=/",
     "Set-Cookie",
-    "fiz=baz; Domain=.github.com; Path=/"
+    "fiz=baz; Domain=.github.com; Path=/",
+    "set-cookie",
+    "foo=baz; Domain=.github.com; Path=/"
   ]);
 
   t.deepEqual(common.headersArrayToObject(headersMultipleSetCookies), {
-    "Content-Type": "application/json; charset=utf-8",
-    "Last-Modified": "foobar",
-    "Expires": "fizbuzz",
-    "Set-Cookie": [
+    "content-type": "application/json; charset=utf-8",
+    "last-modified": "foobar",
+    "expires": "fizbuzz",
+    "set-cookie": [
       "foo=bar; Domain=.github.com; Path=/",
-      "fiz=baz; Domain=.github.com; Path=/"
+      "fiz=baz; Domain=.github.com; Path=/",
+      "foo=baz; Domain=.github.com; Path=/"
     ]
   });
 
diff --git a/tests/test_intercept.js b/tests/test_intercept.js
index 0c9a03f..6255d07 100644
--- a/tests/test_intercept.js
+++ b/tests/test_intercept.js
@@ -2,6 +2,7 @@
 
 var fs      = require('fs');
 var nock    = require('../.');
+var url     = require('url');
 var http    = require('http');
 var https   = require('https');
 var util    = require('util');
@@ -2105,53 +2106,84 @@ test("two scopes with the same request are consumed", function(t) {
   }
 });
 
-test("allow unmocked option works", {skip: process.env.AIRPLANE}, function(t) {
-  var scope = nock('http://www.google.com', {allowUnmocked: true})
-    .get('/abc')
-    .reply(200, 'Hey!')
-    .get('/wont/get/here')
-    .reply(200, 'Hi!');
+test("allow unmocked option works", function(t) {
+  t.plan(7)
+
+  const server = http.createServer((request, response) => {
+    t.pass('server received a request')
+
+    switch (url.parse(request.url).pathname) {
+      case '/':
+        response.writeHead(200)
+        response.write('server served a response')
+        break
+      case '/not/available':
+        response.writeHead(404)
+        break
+      case '/abc':
+        response.writeHead(200)
+        response.write('server served a response')
+        break
+    }
 
-  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();
-  }
+    response.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();
-  }
+  server.listen(() => {
+    const scope = nock(`http://localhost:${server.address().port}`, {allowUnmocked: true})
+      .get('/abc')
+      .reply(304, 'served from our mock')
+      .get('/wont/get/here')
+      .reply(304, 'served from our mock')
 
-  http.request({
-      host: "www.google.com"
-    , path: "/abc"
-    , port: 80
-    }, function(res) {
-      res.on('end', firstIsDone);
+    function secondIsDone() {
+      t.ok(! scope.isDone())
+
+      http.request({
+        host: "localhost",
+        path: "/",
+        port: server.address().port
+      }, response => {
+        response.destroy()
+
+        t.assert(response.statusCode == 200, 'Do not intercept /');
+
+        server.close(t.end)
+      }).end()
+    }
+
+    function firstIsDone() {
+      t.ok(! scope.isDone())
+
+      http.request({
+        host: "localhost",
+        path: "/not/available",
+        port: server.address().port
+      }, response => {
+        t.assert(response.statusCode === 404, 'Server says it does not exist')
+
+        response.on('data', function() {})
+        response.on('end', secondIsDone)
+      }).end()
+    }
+
+    const request = http.request({
+      host: "localhost",
+      path: "/abc",
+      port: server.address().port
+    }, response => {
+      t.assert(response.statusCode == 304, 'Intercept /abc')
+
+      response.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();
-});
+      response.resume()
+    })
+
+    request.on('error', t.error)
+    request.end()
+  })
+})
 
 test("default reply headers work", function(t) {
   nock('http://default.reply.headers.com')
@@ -2655,31 +2687,55 @@ test("persist reply with file", function(t) {
   }, t.end.bind(t));
 });
 
-test('(re-)activate after restore', {skip: process.env.AIRPLANE}, function(t) {
-  var scope = nock('http://google.com')
-    .get('/')
-    .reply(200, 'Hello, World!');
+test('(re-)activate after restore', function(t) {
+  t.plan(7)
 
-  nock.restore();
-  t.false(nock.isActive());
+  const server = http.createServer((request, response) => {
+    t.pass('server received a request')
 
-  http.get('http://google.com/', function(res) {
-    res.resume();
-    res.on('end', function() {
-      t.ok(!scope.isDone());
+    switch (url.parse(request.url).pathname) {
+      case '/':
+        response.writeHead(200)
+        response.write('server served a response')
+        break
+    }
+
+    response.end()
+  })
+
+  server.listen(() => {
+    const scope = nock(`http://localhost:${server.address().port}`)
+      .get('/')
+      .reply(304, 'served from our mock')
+
+      nock.restore()
+      t.false(nock.isActive())
+
+      http.get(`http://localhost:${server.address().port}`, function(res) {
+        res.resume()
+
+        t.is(200, res.statusCode)
 
-      nock.activate();
-      t.true(nock.isActive());
-      http.get('http://google.com', function(res) {
-        res.resume();
         res.on('end', function() {
-          t.ok(scope.isDone());
-          t.end();
-        });
-      }).end();
-    });
-  }).end();
-});
+          t.ok(!scope.isDone())
+
+          nock.activate()
+          t.true(nock.isActive())
+          http.get(`http://localhost:${server.address().port}`, function(res) {
+            res.resume()
+
+            t.is(304, res.statusCode)
+
+            res.on('end', function() {
+              t.ok(scope.isDone())
+
+              server.close(t.end)
+            });
+          })
+        })
+      })
+  })
+})
 
 test("allow unmocked option works with https", {skip: process.env.AIRPLANE}, function(t) {
   t.plan(5)
@@ -2725,7 +2781,9 @@ test("allow unmocked option works with https", {skip: process.env.AIRPLANE}, fun
   }).end();
 });
 
-test('allow unmocked post with json data', {skip: process.env.AIRPLANE}, function(t) {
+// TODO: remove skip as part of https://github.com/node-nock/nock/issues/1077
+// test('allow unmocked post with json data', {skip: process.env.AIRPLANE}, function(t) {
+test('allow unmocked post with json data', {skip: true}, function(t) {
   nock('https://httpbin.org', { allowUnmocked: true }).
     get("/abc").
     reply(200, "Hey!");
@@ -2742,7 +2800,9 @@ test('allow unmocked post with json data', {skip: process.env.AIRPLANE}, functio
   });
 });
 
-test('allow unmocked passthrough with mismatched bodies', {skip: process.env.AIRPLANE}, function(t) {
+// TODO: remove skip as part of https://github.com/node-nock/nock/issues/1077
+// test('allow unmocked passthrough with mismatched bodies', {skip: process.env.AIRPLANE}, function(t) {
+test('allow unmocked passthrough with mismatched bodies', {skip: true}, function(t) {
   nock('http://httpbin.org', { allowUnmocked: true }).
     post("/post", {some: 'otherdata'}).
     reply(404, "Hey!");