test/node/httplib_emulation_spec.js in passenger-4.0.36 vs test/node/httplib_emulation_spec.js in passenger-4.0.37

- old
+ new

@@ -89,10 +89,56 @@ } result.keys = keys; return result; } + describe('the request object', function() { + beforeEach(function() { + var state = this.state; + state.setup = function(headers, callback) { + if (!callback) { + callback = headers; + headers = {}; + } + state.headers = createHeaders(headers); + state.createSocket(function(serverSocket, client) { + state.req = HttplibEmulation.createIncomingMessage( + state.headers, serverSocket, ""); + callback(); + }); + } + }); + + specify('.on() returns the request object', function(done) { + var state = this.state; + state.setup(function() { + var result = state.req.on('foo', function() {}); + assert.strictEqual(result, state.req); + done(); + }); + }); + + it('sets no "upgrade" flag if there is no Upgrade header', function(done) { + var state = this.state; + state.setup(function() { + assert.ok(!state.req.upgrade); + done(); + }); + }); + + it('sets the "upgrade" flag if there is an Upgrade header', function(done) { + var state = this.state; + var headers = { + 'HTTP_UPGRADE': 'WebSocket' + }; + state.setup(headers, function() { + assert.ok(state.req.upgrade); + done(); + }); + }); + }); + describe('if the request may have a request body', function() { beforeEach(function() { var state = this.state; state.setup = function(headers, callback) { if (!callback) { @@ -103,11 +149,10 @@ } state.headers = createHeaders(headers); state.createSocket(function(serverSocket, client) { state.req = HttplibEmulation.createIncomingMessage( state.headers, serverSocket, ""); - assert.ok(state.req._mayHaveRequestBody); callback(); }); } }); @@ -163,11 +208,11 @@ assert.ok(state.req._flowing); done(); }); }); - it("sends data events as data is received", function(done) { + specify("the request object emits data events as data is received", function(done) { var state = this.state; var chunks = []; state.req.on('data', function(chunk) { chunks.push(chunk.toString('utf-8')); @@ -180,11 +225,11 @@ chunks.should.eql(["hello"]); done(); }); }); - it("sends the end event after the client closes the socket", function(done) { + specify("the request object emits the end event after the client closes the socket", function(done) { var state = this.state; var finished; function endReachedPrematurely() { assert.fail("end event received prematurely"); @@ -212,11 +257,11 @@ assert.ok(!state.req._flowing); done(); }); }); - it("emits readable events upon receiving data", function(done) { + specify("the request object emits readable events upon receiving data", function(done) { var state = this.state; var readable = 0; state.req.on('readable', function() { readable++; }); @@ -378,11 +423,10 @@ } state.headers = createHeaders(headers); state.createSocket(function(serverSocket, client) { state.req = HttplibEmulation.createIncomingMessage( state.headers, serverSocket, ""); - assert.ok(!state.req._mayHaveRequestBody); callback(); }); } }); @@ -483,9 +527,97 @@ finished = true; done(); } }); state.req.read(10); + }); + }); + }); + + describe('requests with Upgrade header', function() { + beforeEach(function() { + var state = this.state; + state.setup = function(headers, callback) { + if (!callback) { + callback = headers; + headers = { + 'HTTP_UPGRADE': 'websocket' + }; + } + state.headers = createHeaders(headers); + state.createSocket(function(serverSocket, client) { + state.req = HttplibEmulation.createIncomingMessage( + state.headers, serverSocket, ""); + callback(); + }); + } + }); + + specify('the request object emits no data events', function(done) { + var state = this.state; + state.setup(function() { + var hasData = false; + + state.req.on('data', function(data) { + hasData = true; + }); + state.client.write("hello"); + + Helper.shouldNeverHappen(50, function() { + return hasData; + }, done); + }); + }); + + specify('the request object ends immediately', function(done) { + var state = this.state; + state.setup(function() { + var readable = false; + var readData; + var ended = false; + + state.req.on('readable', function() { + readable = true; + readData = state.req.read(100); + }); + state.req.on('end', function() { + ended = true; + }); + + Helper.eventually(50, function() { + return readable && ended; + }, function() { + assert.strictEqual(readData, null); + done(); + }); + }); + }); + + specify('the socket emits data events as data is received', function(done) { + var state = this.state; + state.setup(function() { + var hasData = false; + + state.req.socket.on('data', function(data) { + hasData = true; + }); + state.client.write("hello"); + + Helper.eventually(50, function() { + return hasData; + }, done); + }); + }); + + it('allows reading from the socket', function(done) { + var state = this.state; + state.setup(function() { + state.req.socket.on('readable', function() { + var chunk = state.req.socket.read(5).toString('utf-8'); + chunk.should.eql("hello"); + done(); + }); + state.client.write("hello"); }); }); }); });