From b4e90a229b2b618aa6e4ac1349314ea1dd0d85e2 Mon Sep 17 00:00:00 2001 From: Eran Hammer Date: Thu, 1 Nov 2012 09:08:56 -0700 Subject: [PATCH 1/3] Add test for helper with invalid key --- test/integration/request.js | 16 +- test/unit/server.js | 636 +++++++++++++++++++----------------- 2 files changed, 344 insertions(+), 308 deletions(-) diff --git a/test/integration/request.js b/test/integration/request.js index 11c39af93..bf2cb579d 100755 --- a/test/integration/request.js +++ b/test/integration/request.js @@ -17,7 +17,7 @@ describe('Request', function () { { method: 'GET', path: '/custom', config: { handler: customErrorHandler } }, ]); - var makeRequest = function (path, callback) { + var makeRequest = function (method, path, callback) { var next = function (res) { @@ -25,7 +25,7 @@ describe('Request', function () { }; server.inject({ - method: 'GET', + method: method, url: path }, next); } @@ -45,11 +45,21 @@ describe('Request', function () { it('returns custom error response', function (done) { - makeRequest('/custom', function (rawRes) { + makeRequest('GET', '/custom', function (rawRes) { var headers = parseHeaders(rawRes.raw.res); expect(headers['Content-Type']).to.equal('text/plain'); done(); }); }); + + it('returns valid OPTIONS response', function (done) { + + makeRequest('OPTIONS', '/custom', function (rawRes) { + + var headers = parseHeaders(rawRes.raw.res); + expect(headers['Access-Control-Allow-Origin']).to.equal('*'); + done(); + }); + }); }); \ No newline at end of file diff --git a/test/unit/server.js b/test/unit/server.js index bc9f6055f..659066206 100755 --- a/test/unit/server.js +++ b/test/unit/server.js @@ -4,420 +4,446 @@ var expect = require('chai').expect; var libPath = process.env.TEST_COV ? '../../lib-cov/' : '../../lib/'; var Server = require(libPath + 'server'); -require('../suite')(function(useRedis, useMongo) { - describe('Server', function () { +describe('Server', function () { + + it('throws an error constructed without new', function (done) { + var fn = function () { + Server('0.0.0.0', 8086, {}); + }; + expect(fn).throws(Error, 'Server must be instantiated using new'); + done(); + }); + + it('defaults to port 80 when no port is provided', function (done) { + var server = new Server(); + expect(server.settings.port).to.be.equal(80); + done(); + }); + + it('defaults to localhost when no host is provided', function (done) { + var server = new Server(); + expect(server.settings.host).to.be.equal('localhost'); + done(); + }); + + it('doesn\'t throw an error when host and port are provided', function (done) { + var fn = function () { + var server = new Server('0.0.0.0', 8083); + }; + expect(fn).to.not.throw(Error); + done(); + }); + + it('throws an error when double port config is provided', function (done) { + var fn = function () { + var server = new Server(8080, 8084); + }; + expect(fn).throws(Error); + done(); + }); + + it('throws an error when double host config is provided', function (done) { + var fn = function () { + var server = new Server('0.0.0.0', 'localhost'); + }; + expect(fn).throws(Error); + done(); + }); + + it('throws an error when unknown arg type is provided', function (done) { + var fn = function () { + var server = new Server(true); + }; + expect(fn).throws(Error); + done(); + }); + + it('throws an error when an incomplete authentication config is provided', function (done) { + var fn = function () { + var server = new Server('0.0.0.0', 8084, { authentication: {} }); + }; + expect(fn).throws(Error); + done(); + }); + + it('doesn\'t throw an error when disabling authentication', function (done) { + var fn = function () { + var server = new Server('0.0.0.0', 8085, { authentication: false }); + }; + expect(fn).to.not.throw(Error); + done(); + }); + + it('doesn\'t throw an error when enabling docs', function (done) { + var fn = function () { + var server = new Server('0.0.0.0', 8086, { docs: true }); + }; + expect(fn).to.not.throw(Error); + done(); + }); + + it('doesn\'t throw an error when enabling the debug console', function (done) { + var fn = function () { + var server = new Server('0.0.0.0', 8087, { debug: { websocketPort: 3002 } }); + }; + expect(fn).to.not.throw(Error); + done(); + }); + + it('doesn\'t throw an error when disabling cache', function (done) { + var fn = function () { + var server = new Server('0.0.0.0', 8088, { cache: false }); + }; + expect(fn).to.not.throw(Error); + done(); + }); + + it('assigns _monitor when config enables monitor', function (done) { + var server = new Server('0.0.0.0', 8082, { monitor: true }); + expect(server._monitor).to.exist; + done(); + }); + - it('throws an error constructed without new', function (done) { + describe('#_match', function () { + + it('throws an error when the method parameter is null', function (done) { var fn = function () { - Server('0.0.0.0', 8086, {}); + var server = new Server('0.0.0.0', 8092); + server._match(null, '/test'); }; - expect(fn).throws(Error, 'Server must be instantiated using new'); + expect(fn).to.throw(Error, 'The method parameter must be provided'); done(); }); - it('defaults to port 80 when no port is provided', function (done) { - var server = new Server(); - expect(server.settings.port).to.be.equal(80); + it('throws an error when the path parameter is null', function (done) { + var fn = function () { + var server = new Server('0.0.0.0', 8091); + server._match('POST', null); + }; + expect(fn).to.throw(Error, 'The path parameter must be provided'); done(); }); - it('defaults to localhost when no host is provided', function (done) { - var server = new Server(); - expect(server.settings.host).to.be.equal('localhost'); + it('returns null when no routes are added', function (done) { + var server = new Server('0.0.0.0', 8092); + var result = server._match('GET', '/test'); + + expect(result).to.not.exist; done(); }); - it('doesn\'t throw an error when host and port are provided', function (done) { + it('returns the route when there is a match', function (done) { + var server = new Server('0.0.0.0', 8092); + server.addRoute({ + method: 'GET', + path: '/test', + handler: function () { } + }); + var result = server._match('GET', '/test'); + + expect(result).exist; + expect(result.path).to.equal('/test'); + done(); + }); + }); + + + describe('#start', function () { + + it('doesn\'t throw an error', function (done) { var fn = function () { - var server = new Server('0.0.0.0', 8083); + var server = new Server('0.0.0.0', 8088); + server.start(); }; expect(fn).to.not.throw(Error); done(); }); + }); + - it('throws an error when double port config is provided', function (done) { + describe('#stop', function () { + + it('doesn\'t throw an error when the server is started', function (done) { var fn = function () { - var server = new Server(8080, 8084); + var server = new Server('0.0.0.0', 8089); + server.listener.on('listening', function () { + server.stop(); + done(); + }); + + server.start(); }; - expect(fn).throws(Error); - done(); + expect(fn).to.not.throw(Error); }); - it('throws an error when double host config is provided', function (done) { + it('throws an error when the server isn\'t started', function (done) { var fn = function () { - var server = new Server('0.0.0.0', 'localhost'); + var server = new Server('0.0.0.0', 8090); + server.stop(); }; - expect(fn).throws(Error); + expect(fn).to.throw(Error); done(); }); + }); - it('throws an error when unknown arg type is provided', function (done) { + + describe('#setRoutesDefaults', function () { + + it('throws an error when a default handler is provided', function (done) { var fn = function () { - var server = new Server(true); + var server = new Server('0.0.0.0', 8091); + server.setRoutesDefaults({ handler: function () { } }); }; - expect(fn).throws(Error); + expect(fn).to.throw(Error, 'Defaults cannot include a handler'); + done(); + }); + + it('changes the value of routeDefaults with the passed in object', function (done) { + var server = new Server('0.0.0.0', 8092); + server.setRoutesDefaults({ item: true }); + expect(server.routeDefaults.item).to.be.true; done(); }); + }); + - it('throws an error when an incomplete authentication config is provided', function (done) { + describe('#addRoute', function () { + + it('throws an error when a route is passed in that is missing a path', function (done) { var fn = function () { - var server = new Server('0.0.0.0', 8084, { authentication: {} }); + var route = { + }; + var server = new Server('0.0.0.0', 8093); + server.addRoute(route); }; - expect(fn).throws(Error); + expect(fn).to.throw(Error, 'Route options missing path'); done(); }); - it('doesn\'t throw an error when disabling authentication', function (done) { + it('throws an error when a route is passed in that is missing a method', function (done) { var fn = function () { - var server = new Server('0.0.0.0', 8085, { authentication: false }); + var route = { + path: '/test' + }; + var server = new Server('0.0.0.0', 8094); + server.addRoute(route); }; - expect(fn).to.not.throw(Error); + expect(fn).to.throw(Error, 'Route options missing method'); done(); }); - it('doesn\'t throw an error when enabling docs', function (done) { + it('throws an error when a route is passed in that is missing a handler', function (done) { var fn = function () { - var server = new Server('0.0.0.0', 8086, { docs: true }); + var route = { + path: '/test', + method: 'put' + }; + var server = new Server('0.0.0.0', 8095); + server.addRoute(route); }; - expect(fn).to.not.throw(Error); + expect(fn).to.throw(Error); done(); }); - it('doesn\'t throw an error when enabling the debug console', function (done) { - var fn = function () { - var server = new Server('0.0.0.0', 8087, { debug: { websocketPort: 3002 } }); + it('adds route to correct _routes method property', function (done) { + var route = { + path: '/test', + method: 'put', + handler: function () { } }; - expect(fn).to.not.throw(Error); + var server = new Server('0.0.0.0', 8096); + server.addRoute(route); + + expect(server._routes.put[0]).to.exist; + expect(server._routes.put[0].path).to.equal('/test'); done(); }); + }); + + describe('#addRoutes', function () { - it('doesn\'t throw an error when disabling cache', function (done) { + it('throws an error when null routes are passed in', function (done) { var fn = function () { - var server = new Server('0.0.0.0', 8088, { cache: false }); + var server = new Server('0.0.0.0', 8097); + server.addRoutes(null); }; - expect(fn).to.not.throw(Error); + expect(fn).to.throw(Error); done(); }); - it('assigns _monitor when config enables monitor', function (done) { - var server = new Server('0.0.0.0', 8082, { monitor: true }); - expect(server._monitor).to.exist; + it('adds to routes object with the passed in routes values', function (done) { + var routes = [{ + path: '/test', + method: 'put', + handler: function () { } + }, { + path: '/test', + method: 'post', + handler: function () { } + }]; + var server = new Server('0.0.0.0', 8098); + server.addRoutes(routes); + + expect(server._routes.put[0].path).to.equal('/test'); done(); }); + }); + describe('#addHelper', function () { - describe('#_match', function () { - - it('throws an error when the method parameter is null', function (done) { - var fn = function () { - var server = new Server('0.0.0.0', 8092); - server._match(null, '/test'); - }; - expect(fn).to.throw(Error, 'The method parameter must be provided'); - done(); - }); - - it('throws an error when the path parameter is null', function (done) { - var fn = function () { - var server = new Server('0.0.0.0', 8091); - server._match('POST', null); - }; - expect(fn).to.throw(Error, 'The path parameter must be provided'); - done(); - }); - - it('returns null when no routes are added', function (done) { - var server = new Server('0.0.0.0', 8092); - var result = server._match('GET', '/test'); - - expect(result).to.not.exist; - done(); - }); - - it('returns the route when there is a match', function (done) { - var server = new Server('0.0.0.0', 8092); - server.addRoute({ - method: 'GET', - path: '/test', - handler: function () { } - }); - var result = server._match('GET', '/test'); - - expect(result).exist; - expect(result.path).to.equal('/test'); - done(); - }); + it('throws an error when name is not a string', function (done) { + var fn = function () { + var server = new Server('0.0.0.0', 8097); + server.addHelper(0, function () { }); + }; + expect(fn).to.throw(Error); + done(); }); - - describe('#start', function () { - - it('doesn\'t throw an error', function (done) { - var fn = function () { - var server = new Server('0.0.0.0', 8088); - server.start(); - }; - expect(fn).to.not.throw(Error); - done(); - }); + it('throws an error when method is not a function', function (done) { + var fn = function () { + var server = new Server('0.0.0.0', 8097); + server.addHelper('user', 'function'); + }; + expect(fn).to.throw(Error); + done(); }); - - describe('#stop', function () { - - it('doesn\'t throw an error when the server is started', function (done) { - var fn = function () { - var server = new Server('0.0.0.0', 8089); - server.listener.on('listening', function () { - server.stop(); - done(); - }); - - server.start(); - }; - expect(fn).to.not.throw(Error); - }); - - it('throws an error when the server isn\'t started', function (done) { - var fn = function () { - var server = new Server('0.0.0.0', 8090); - server.stop(); - }; - expect(fn).to.throw(Error); - done(); - }); + it('throws an error when options is not an object', function (done) { + var fn = function () { + var server = new Server('0.0.0.0', 8097); + server.addHelper('user', function () { }, 'options'); + }; + expect(fn).to.throw(Error); + done(); }); - - describe('#setRoutesDefaults', function () { - - it('throws an error when a default handler is provided', function (done) { - var fn = function () { - var server = new Server('0.0.0.0', 8091); - server.setRoutesDefaults({ handler: function () { } }); - }; - expect(fn).to.throw(Error, 'Defaults cannot include a handler'); - done(); - }); - - it('changes the value of routeDefaults with the passed in object', function (done) { - var server = new Server('0.0.0.0', 8092); - server.setRoutesDefaults({ item: true }); - expect(server.routeDefaults.item).to.be.true; - done(); - }); + it('throws an error when options.generateKey is not a function', function (done) { + var fn = function () { + var server = new Server('0.0.0.0', 8097); + server.addHelper('user', function () { }, { generateKey: 'function' }); + }; + expect(fn).to.throw(Error); + done(); }); - - describe('#addRoute', function () { - - it('throws an error when a route is passed in that is missing a path', function (done) { - var fn = function () { - var route = { - }; - var server = new Server('0.0.0.0', 8093); - server.addRoute(route); - }; - expect(fn).to.throw(Error, 'Route options missing path'); - done(); - }); - - it('throws an error when a route is passed in that is missing a method', function (done) { - var fn = function () { - var route = { - path: '/test' - }; - var server = new Server('0.0.0.0', 8094); - server.addRoute(route); - }; - expect(fn).to.throw(Error, 'Route options missing method'); - done(); - }); - - it('throws an error when a route is passed in that is missing a handler', function (done) { - var fn = function () { - var route = { - path: '/test', - method: 'put' - }; - var server = new Server('0.0.0.0', 8095); - server.addRoute(route); - }; - expect(fn).to.throw(Error); - done(); - }); - - it('adds route to correct _routes method property', function (done) { - var route = { - path: '/test', - method: 'put', - handler: function () { } - }; - var server = new Server('0.0.0.0', 8096); - server.addRoute(route); - - expect(server._routes.put[0]).to.exist; - expect(server._routes.put[0].path).to.equal('/test'); - done(); - }); + it('throws an error when options.cache is not valid', function (done) { + var fn = function () { + var server = new Server('0.0.0.0', 8097, { cache: 'redis' }); + server.addHelper('user', function () { }, { cache: { mode: 'none', expiresIn: 3000 } }); + }; + expect(fn).to.throw(Error); + done(); }); - describe('#addRoutes', function () { + it('throws an error when options.cache is not enabled but server cache is not', function (done) { + var fn = function () { + var server = new Server('0.0.0.0', 8097); + server.addHelper('user', function () { }, { cache: { expiresIn: 3000 } }); + }; + expect(fn).to.throw(Error); + done(); + }); - it('throws an error when null routes are passed in', function (done) { - var fn = function () { - var server = new Server('0.0.0.0', 8097); - server.addRoutes(null); - }; - expect(fn).to.throw(Error); - done(); - }); + it('returns a valid result when calling a helper without using the cache', function (done) { - it('adds to routes object with the passed in routes values', function (done) { - var routes = [{ - path: '/test', - method: 'put', - handler: function () { } - }, { - path: '/test', - method: 'post', - handler: function () { } - }]; - var server = new Server('0.0.0.0', 8098); - server.addRoutes(routes); + var server = new Server('0.0.0.0', 8097); + server.addHelper('user', function (id, next) { return next({ id: id }); }); + server.helpers.user(4, function (result) { - expect(server._routes.put[0].path).to.equal('/test'); + result.id.should.be.equal(4); done(); }); }); - describe('#addHelper', function () { + it('returns a different result when calling a helper without using the cache', function (done) { - it('throws an error when name is not a string', function (done) { - var fn = function () { - var server = new Server('0.0.0.0', 8097); - server.addHelper(0, function () { }); - }; - expect(fn).to.throw(Error); - done(); - }); + var server = new Server('0.0.0.0', 8097); + var gen = 0; + server.addHelper('user', function (id, next) { return next({ id: id, gen: ++gen }); }); + server.helpers.user(4, function (result1) { - it('throws an error when method is not a function', function (done) { - var fn = function () { - var server = new Server('0.0.0.0', 8097); - server.addHelper('user', 'function'); - }; - expect(fn).to.throw(Error); - done(); - }); - - it('throws an error when options is not an object', function (done) { - var fn = function () { - var server = new Server('0.0.0.0', 8097); - server.addHelper('user', function () { }, 'options'); - }; - expect(fn).to.throw(Error); - done(); - }); + result1.id.should.be.equal(4); + result1.gen.should.be.equal(1); + server.helpers.user(4, function (result2) { - it('throws an error when options.generateKey is not a function', function (done) { - var fn = function () { - var server = new Server('0.0.0.0', 8097); - server.addHelper('user', function () { }, { generateKey: 'function' }); - }; - expect(fn).to.throw(Error); - done(); + result2.id.should.be.equal(4); + result2.gen.should.be.equal(2); + done(); + }); }); + }); - it('throws an error when options.cache is not valid', function (done) { - var fn = function () { - var server = new Server('0.0.0.0', 8097, { cache: 'redis' }); - server.addHelper('user', function () { }, { cache: { mode: 'none', expiresIn: 3000 } }); - }; - expect(fn).to.throw(Error); - done(); - }); + describe('with cache', function () { - it('throws an error when options.cache is not enabled but server cache is not', function (done) { - var fn = function () { - var server = new Server('0.0.0.0', 8097); - server.addHelper('user', function () { }, { cache: { expiresIn: 3000 } }); - }; - expect(fn).to.throw(Error); - done(); - }); + it('returns a valid result when calling a helper using the cache', function (done) { - it('returns a valid result when calling a helper without using the cache', function (done) { + var server = new Server('0.0.0.0', 8097, { cache: 'memory' }); + var gen = 0; + server.addHelper('user', function (id, next) { return next({ id: id, gen: ++gen }); }, { cache: { expiresIn: 2000 } }); + var id = Math.random(); + server.helpers.user(id, function (result1) { - var server = new Server('0.0.0.0', 8097); - server.addHelper('user', function (id, next) { return next({ id: id }); }); - server.helpers.user(4, function (result) { + result1.id.should.be.equal(id); + result1.gen.should.be.equal(1); + server.helpers.user(id, function (result2) { - result.id.should.be.equal(4); - done(); + result2.id.should.be.equal(id); + result2.gen.should.be.equal(1); + done(); + }); }); }); - it('returns a different result when calling a helper without using the cache', function (done) { + it('returns valid results when calling a helper (with different keys) using the cache', function (done) { - var server = new Server('0.0.0.0', 8097); + var server = new Server('0.0.0.0', 8097, { cache: 'memory' }); var gen = 0; - server.addHelper('user', function (id, next) { return next({ id: id, gen: ++gen }); }); - server.helpers.user(4, function (result1) { + server.addHelper('user', function (id, next) { return next({ id: id, gen: ++gen }); }, { cache: { expiresIn: 2000 } }); + var id1 = Math.random(); + server.helpers.user(id1, function (result1) { - result1.id.should.be.equal(4); + result1.id.should.be.equal(id1); result1.gen.should.be.equal(1); - server.helpers.user(4, function (result2) { + var id2 = Math.random(); + server.helpers.user(id2, function (result2) { - result2.id.should.be.equal(4); + result2.id.should.be.equal(id2); result2.gen.should.be.equal(2); done(); }); }); }); - describe('with cache', function() { + it('returns new object (not cached) when second key generation fails when using the cache', function (done) { - if (useRedis) { - it('returns a valid result when calling a helper using the cache', function (done) { + var server = new Server('0.0.0.0', 8097, { cache: 'memory' }); + var id1 = Math.random(); + var gen = 0; + var helper = function (id, next) { - var server = new Server('0.0.0.0', 8097, { cache: 'redis' }); - var gen = 0; - server.addHelper('user', function (id, next) { return next({ id: id, gen: ++gen }); }, { cache: { expiresIn: 2000 } }); - var id = Math.random(); - server.helpers.user(id, function (result1) { + if (typeof id === 'function') { + id = id1; + } - result1.id.should.be.equal(id); - result1.gen.should.be.equal(1); - server.helpers.user(id, function (result2) { + return next({ id: id, gen: ++gen }); + }; - result2.id.should.be.equal(id); - result2.gen.should.be.equal(1); - done(); - }); - }); - }); + server.addHelper('user', helper, { cache: { expiresIn: 2000 } }); - it('returns valid results when calling a helper (with different keys) using the cache', function (done) { + server.helpers.user(id1, function (result1) { - var server = new Server('0.0.0.0', 8097, { cache: 'redis' }); - var gen = 0; - server.addHelper('user', function (id, next) { return next({ id: id, gen: ++gen }); }, { cache: { expiresIn: 2000 } }); - var id1 = Math.random(); - server.helpers.user(id1, function (result1) { + result1.id.should.be.equal(id1); + result1.gen.should.be.equal(1); - result1.id.should.be.equal(id1); - result1.gen.should.be.equal(1); - var id2 = Math.random(); - server.helpers.user(id2, function (result2) { + server.helpers.user(function () { }, function (result2) { - result2.id.should.be.equal(id2); - result2.gen.should.be.equal(2); - done(); - }); - }); + result2.id.should.be.equal(id1); + result2.gen.should.be.equal(2); + done(); }); - } + }); }); }); }); From eb8bd85332f33a6066e216b1f8f61b06f4df42d1 Mon Sep 17 00:00:00 2001 From: Eran Hammer Date: Thu, 1 Nov 2012 09:18:04 -0700 Subject: [PATCH 2/3] Add server tls config test --- test/unit/server.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/unit/server.js b/test/unit/server.js index 659066206..e1f068d5e 100755 --- a/test/unit/server.js +++ b/test/unit/server.js @@ -1,5 +1,6 @@ // Load modules +var Https = require('https'); var expect = require('chai').expect; var libPath = process.env.TEST_COV ? '../../lib-cov/' : '../../lib/'; var Server = require(libPath + 'server'); @@ -104,6 +105,15 @@ describe('Server', function () { done(); }); + it('creates an https server when passed tls options', function (done) { + var tls = { + }; + + var server = new Server('0.0.0.0', 8082, { tls: tls }); + expect(server.listener instanceof Https.Server).to.equal(true); + done(); + }); + describe('#_match', function () { From fa4d5fedc859bb2ab511ead70a3ab456e6681791 Mon Sep 17 00:00:00 2001 From: Eran Hammer Date: Mon, 22 Oct 2012 14:57:34 -0700 Subject: [PATCH 3/3] Allow non 4xx 5xx codes in pass-through errors --- lib/error.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/error.js b/lib/error.js index f67bdea84..9fdf302eb 100755 --- a/lib/error.js +++ b/lib/error.js @@ -120,7 +120,14 @@ internals.Error.passThrough = function (code, payload, contentType) { return response; }; - var err = new internals.Error(code, 'Pass-through', { toResponse: format }); + var err = new internals.Error(500, 'Pass-through', { toResponse: format }); // 500 code is only used internally and is not exposed when sent + + err.passThrough = { + code: code, + payload: payload, + contentType: contentType + }; + return err; };