Comparing version 0.8.0 to 0.8.1
@@ -49,19 +49,17 @@ // Load modules | ||
exports._oauth = function (code, description) { | ||
exports.format = function (error) { | ||
return exports.create('OAuth', 400, description, { type: 'oauth', error: code }); | ||
}; | ||
if (error.hasOwnProperty('toResponse') && | ||
typeof error.toResponse === 'function') { | ||
return error.toResponse(); | ||
} | ||
exports.format = function (error) { | ||
var err = { | ||
error: error.text, | ||
code: error.code, | ||
message: (error.code >= 500 && error.code < 600 ? 'An internal server error occurred' : error.message) | ||
}; | ||
if (error.type === 'oauth') { | ||
return { error: error.error, error_description: error.text }; | ||
} | ||
else if (error.code >= 500 && error.code < 600) { | ||
return { error: error.text, message: 'An internal server error occurred', code: error.code }; | ||
} | ||
else { | ||
return { error: error.text, message: error.message, code: error.code }; | ||
} | ||
return err; | ||
}; | ||
@@ -68,0 +66,0 @@ |
@@ -104,3 +104,3 @@ // Load modules | ||
if (isBailed) { | ||
return; // next() already called | ||
return; // next() already called | ||
} | ||
@@ -114,28 +114,27 @@ | ||
if (level === 'parse') { | ||
request.payload = {}; | ||
if (level !== 'parse') { // 'raw' | ||
return next(); | ||
} | ||
unwrapper(payload, encoding, request, function (err, result) { | ||
request.payload = {}; | ||
if (err) { | ||
return next(Err.badRequest("Invalid gzip: " + err)); | ||
} | ||
unwrapper(payload, encoding, request, function (err, result) { | ||
if (result) { | ||
try { | ||
request.payload = parserFunc(result); | ||
} | ||
catch (err) { | ||
return next(Err.badRequest('Invalid JSON body')); | ||
} | ||
if (err) { | ||
return next(Err.badRequest("Invalid gzip: " + err)); | ||
} | ||
if (result) { | ||
try { | ||
request.payload = parserFunc(result); | ||
} | ||
catch (err) { | ||
return next(Err.badRequest('Invalid JSON body')); | ||
} | ||
} | ||
return next(); | ||
}) | ||
} | ||
else { | ||
return next(); | ||
} | ||
}) | ||
}); | ||
}; | ||
145
lib/proxy.js
@@ -20,6 +20,9 @@ // Load modules | ||
Utils.assert(options, 'Missing options'); | ||
Utils.assert(options.host, 'Missing destination host option'); | ||
Utils.assert(!options.passThrough || !route.cache.isMode('server'), 'Cannot use pass-through proxy mode with caching') | ||
Utils.assert(options.host || options.mapUri, 'Missing options.host and no options.mapUri'); | ||
Utils.assert(!options.passThrough || !route.cache.isMode('server'), 'Cannot use pass-through proxy mode with caching'); | ||
Utils.assert(!options.mapUri || typeof options.mapUri === 'function', 'options.mapUri must be a function'); | ||
Utils.assert(!options.postResponse || typeof options.postResponse === 'function', 'options.postResponse must be a function'); | ||
Utils.assert(!options.hasOwnProperty('isCustomPostResponse'), 'Cannot manually set options.isCustomPostResponse'); | ||
this.settings = Utils.clone(options); // Options can be reused | ||
this.settings = Utils.clone(options); // Options can be reused | ||
this.settings.protocol = this.settings.protocol || 'http'; | ||
@@ -29,2 +32,7 @@ this.settings.port = this.settings.port || (this.settings.protocol === 'http' ? 80 : 443); | ||
this.settings.passHeaders = this.settings.passThrough || false; | ||
this.settings.mapUri = this.settings.mapUri || internals.mapUri; // function (request, settings, function (err, uri, query)) | ||
this.settings.isCustomPostResponse = !!this.settings.postResponse; | ||
this.settings.postResponse = this.settings.postResponse || internals.postResponse; // function (request, settings, response, payload) | ||
return this; | ||
}; | ||
@@ -39,87 +47,94 @@ | ||
var req = request.raw.req; | ||
self.settings.mapUri(request, self.settings, function (err, uri, query) { | ||
var options = { | ||
url: self.settings.protocol + '://' + self.settings.host + ':' + self.settings.port + request.path, | ||
method: request.method, | ||
qs: request.query, | ||
headers: {} | ||
}; | ||
if (err) { | ||
return request.reply(err); | ||
} | ||
if (self.settings.passThrough) { | ||
options.headers = Utils.clone(req.headers); | ||
delete options.headers.host; | ||
} | ||
var req = request.raw.req; | ||
if (self.settings.xforward) { | ||
options.headers['x-forwarded-for'] = (options.headers['x-forwarded-for'] ? options.headers['x-forwarded-for'] + ',' : '') + req.connection.remoteAddress || req.socket.remoteAddress; | ||
options.headers['x-forwarded-port'] = (options.headers['x-forwarded-port'] ? options.headers['x-forwarded-port'] + ',' : '') + req.connection.remotePort || req.socket.remotePort; | ||
options.headers['x-forwarded-proto'] = (options.headers['x-forwarded-proto'] ? options.headers['x-forwarded-proto'] + ',' : '') + self.settings.protocol; | ||
} | ||
var options = { | ||
url: uri, | ||
method: request.method, | ||
qs: query, | ||
headers: {} | ||
}; | ||
if (request.method === 'get' || | ||
request.method === 'head') { | ||
if (self.settings.passThrough) { // Never set with cache | ||
options.headers = Utils.clone(req.headers); | ||
delete options.headers.host; | ||
} | ||
// No caching (pipe) | ||
if (!request._route || | ||
!request._route.cache.isMode('server')) { | ||
if (self.settings.xforward) { | ||
options.headers['x-forwarded-for'] = (options.headers['x-forwarded-for'] ? options.headers['x-forwarded-for'] + ',' : '') + req.connection.remoteAddress || req.socket.remoteAddress; | ||
options.headers['x-forwarded-port'] = (options.headers['x-forwarded-port'] ? options.headers['x-forwarded-port'] + ',' : '') + req.connection.remotePort || req.socket.remotePort; | ||
options.headers['x-forwarded-proto'] = (options.headers['x-forwarded-proto'] ? options.headers['x-forwarded-proto'] + ',' : '') + self.settings.protocol; | ||
} | ||
var reqStream = Request(options); | ||
var isGet = (request.method === 'get' || request.method === 'head'); | ||
reqStream.on('response', function(resStream) { | ||
request.reply.stream(resStream); | ||
if (self.settings.isCustomPostResponse || // Custom response method | ||
(isGet && request._route && request._route.cache.isMode('server'))) { // GET/HEAD with Cache | ||
// Callback interface | ||
Request(options, function (err, response, payload) { | ||
// Request handles all redirect responses (3xx) and will return an err if redirection fails | ||
if (err) { | ||
return request.reply(Err.internal('Proxy error', err)); | ||
} | ||
return self.settings.postResponse(request, self.settings, response, payload); | ||
}); | ||
return; | ||
} | ||
else { | ||
// Cache (parse response) | ||
Request(options, function (err, response, payload) { | ||
// Stream interface | ||
if (err) { | ||
return request.reply(Err.internal('Proxy error', err)); | ||
} | ||
if (!isGet && | ||
request.rawBody) { | ||
if (response.statusCode >= 400) { | ||
return request.reply(Err.internal('Error proxy response', payload)); | ||
options.headers['Content-Type'] = req.headers['content-type']; | ||
options.body = request.rawBody; | ||
} | ||
if (response.headers['content-type']) { | ||
request.reply.type(response.headers['content-type']); | ||
} | ||
var reqStream = Request(options); | ||
var headerKeys = Object.keys(response.headers); | ||
for (var i = 0, il = headerKeys.length; i < il; ++i) { | ||
var headerKey = headerKeys[i]; | ||
if (headerKey !== 'content-length') { | ||
request.reply.header(headerKey, response.headers[headerKey]); | ||
} | ||
if (!isGet && | ||
request._route && | ||
request._route.config.payload === 'stream') { | ||
request.raw.req.pipe(reqStream); | ||
} | ||
return request.reply(payload); | ||
}); | ||
} | ||
else { | ||
if (request.rawBody) { | ||
options.headers['Content-Type'] = req.headers['content-type']; | ||
options.body = request.rawBody; | ||
reqStream.on('response', function (resStream) { | ||
request.reply.stream(resStream); // Request._respond will pass-through headers and status code | ||
}); | ||
} | ||
}); | ||
}; | ||
}; | ||
var reqStream = Request(options); | ||
if (request._route && | ||
request._route.config.payload === 'stream') { | ||
internals.mapUri = function (request, settings, callback) { | ||
request.raw.req.pipe(reqStream); | ||
} | ||
return callback(null, settings.protocol + '://' + settings.host + ':' + settings.port + request.path, request.query); | ||
}; | ||
reqStream.on('response', function(resStream) { | ||
request.reply.stream(resStream); // Request._respond will pass-through headers and status code | ||
}); | ||
} | ||
}; | ||
internals.postResponse = function (request, settings, response, payload) { | ||
if (response.statusCode >= 400) { | ||
return request.reply(Err.internal('Error proxy response', { code: response.statusCode, payload: payload })); | ||
} | ||
if (response.headers['content-type']) { | ||
request.reply.type(response.headers['content-type']); | ||
} | ||
return request.reply(payload); | ||
}; | ||
@@ -299,2 +299,3 @@ // Load modules | ||
Utils.assert(stream instanceof Stream, 'request.reply.stream() requires a stream'); | ||
Utils.assert(!self._route || !self._route.cache.isMode('server'), 'Cannot reply using a stream when caching enabled'); | ||
process(stream); | ||
@@ -332,3 +333,3 @@ }; | ||
this.reply.header = function(name, value) { | ||
this.reply.header = function (name, value) { | ||
@@ -434,3 +435,3 @@ response.options.headers = response.options.headers || {}; | ||
var self = this; | ||
return function (callback) { | ||
@@ -552,3 +553,3 @@ | ||
internals.Request.prototype._setCache = function(headers) { | ||
internals.Request.prototype._setCache = function (headers) { | ||
@@ -704,7 +705,7 @@ if (this._route && | ||
// Check if data is a node HTTP response (data.*) or a (mikeal's) Request object (data.response.*) | ||
if (!self._route || | ||
!self._route.config.proxy || | ||
self._route.config.proxy.passThrough) { // Pass headers only if not proxy or proxy with pass-through set | ||
var responseHeaders = data.response ? data.response.headers : data.headers; | ||
@@ -720,3 +721,3 @@ if (responseHeaders) { | ||
self.raw.req.on('close', function() { | ||
self.raw.req.on('close', function () { | ||
@@ -723,0 +724,0 @@ data.destroy.bind(data); |
// Load modules | ||
var Fs = require('fs'); | ||
var Http = require('http'); | ||
@@ -95,8 +94,3 @@ var Https = require('https'); | ||
if (this.settings.tls) { | ||
var tls = { | ||
key: Fs.readFileSync(this.settings.tls.key), | ||
cert: Fs.readFileSync(this.settings.tls.cert) | ||
}; | ||
this.listener = Https.createServer(tls, this._dispatch()); | ||
this.listener = Https.createServer(this.settings.tls, this._dispatch()); | ||
} | ||
@@ -103,0 +97,0 @@ else { |
@@ -184,11 +184,11 @@ // Load modules | ||
else { | ||
request.reply(Err._oauth('invalid_grant', 'Mismatching refresh token client id')); | ||
request.reply(internals.error('invalid_grant', 'Mismatching refresh token client id')); | ||
} | ||
} | ||
else { | ||
request.reply(Err._oauth('invalid_grant', 'Invalid refresh token')); | ||
request.reply(internals.error('invalid_grant', 'Invalid refresh token')); | ||
} | ||
} | ||
else { | ||
request.reply(Err._oauth('invalid_request', 'Missing refresh_token')); | ||
request.reply(internals.error('invalid_request', 'Missing refresh_token')); | ||
} | ||
@@ -210,3 +210,3 @@ } | ||
// Unsupported grant type | ||
request.reply(Err._oauth('unsupported_grant_type', 'Unknown or unsupported grant type')); | ||
request.reply(internals.error('unsupported_grant_type', 'Unknown or unsupported grant type')); | ||
} | ||
@@ -216,3 +216,3 @@ } | ||
// Bad client authentication | ||
request.reply(Err._oauth('invalid_client', 'Invalid client identifier or secret')); | ||
request.reply(internals.error('invalid_client', 'Invalid client identifier or secret')); | ||
} | ||
@@ -222,3 +222,3 @@ } | ||
// Unknown client | ||
request.reply(Err._oauth('invalid_client', 'Invalid client identifier or secret')); | ||
request.reply(internals.error('invalid_client', 'Invalid client identifier or secret')); | ||
} | ||
@@ -392,3 +392,3 @@ }); | ||
return Err._oauth('invalid_request', 'Request cannot include both Basic and payload client authentication'); | ||
return internals.error('invalid_request', 'Request cannot include both Basic and payload client authentication'); | ||
} | ||
@@ -406,3 +406,3 @@ | ||
else { | ||
return Err._oauth('invalid_request', 'Unsupported HTTP authentication scheme'); | ||
return internals.error('invalid_request', 'Unsupported HTTP authentication scheme'); | ||
} | ||
@@ -417,3 +417,3 @@ } | ||
else { | ||
return Err._oauth('invalid_request', 'Request missing client authentication'); | ||
return internals.error('invalid_request', 'Request missing client authentication'); | ||
} | ||
@@ -485,1 +485,20 @@ } | ||
internals.error = function (code, description) { | ||
var err = new Error(); | ||
err.message = 'OAuth'; | ||
err.code = 400; | ||
err.text = description; | ||
err.type = 'oauth'; | ||
err.error = code; | ||
err.toResponse = function () { | ||
return { error: code, error_description: description }; | ||
}; | ||
return err; | ||
}; | ||
@@ -5,3 +5,3 @@ { | ||
"homepage": "http://hapijs.com", | ||
"version": "0.8.0", | ||
"version": "0.8.1", | ||
"author": "Eran Hammer <eran@hueniverse.com> (http://hueniverse.com)", | ||
@@ -8,0 +8,0 @@ "contributors":[ |
@@ -394,3 +394,3 @@ ![hapi Logo](https://raw.github.com/walmartlabs/hapi/master/images/hapi.png) | ||
### Configuration options | ||
### Configuration options | ||
@@ -404,2 +404,3 @@ * `path` - the absolute path or regular expression to match against incoming requests. Path comparison is configured using the server [`router`](#router) option. String paths can include named identifiers prefixed with _':'_ as described in [Path Parameters](#path-processing). | ||
* `tags` - route tags (array of strings). | ||
* `handler` - an alternative location for the route handler function. Same as the `handler` option in the parent level. Can only include one handler per route. | ||
* `query` - validation rules for incoming requests' query component (the key-value part of the URI between _?_ and _#_). Defaults to no query parameters allowed. See [Query Validation](#query-validation) for more information. | ||
@@ -426,2 +427,31 @@ * `schema` - validation rules for incoming requests' payload (request body). Defaults to no validation (any payload allowed). Set to an empty object _'{}'_ to forbid payloads. See [Payload Validation](#payload-validation) for more information. | ||
The `config` option was defined for easily spliting the routing table definition from the individual route information. For example: | ||
```javascript | ||
var Hapi = require('hapi'); | ||
var server = new Hapi.Server(); | ||
// Option 1 - add handler directly in route definition | ||
var handler1 = function (request) { | ||
request.reply('ok'); | ||
} | ||
server.addRoute({ method: 'GET', path: '/option1', handler: handler1 }); | ||
// Option 2 - add handler in seprate config object | ||
var config2 = { | ||
payload: 'raw', | ||
// ... additional config options ... | ||
handler: function (request) { | ||
request.reply('ok'); | ||
} | ||
}; | ||
server.addRoute({ method: 'GET', path: '/option2', config: config2}); | ||
``` | ||
### Override Route Defaults | ||
@@ -471,2 +501,3 @@ | ||
- _'path'_ - the request URI's path component. | ||
- _'method'_ - the request method as a _lowercase_ string. (Examples: `'get'`, `'post'`). | ||
- _'query'_ - an object containing the query parameters. | ||
@@ -473,0 +504,0 @@ - _'params'_ - an object containing the path named parameters as described in [Path Parameters](#parameters). |
// Load modules | ||
var Stream = require('stream'); | ||
var expect = require('chai').expect; | ||
@@ -27,4 +28,9 @@ var Sinon = require('sinon'); | ||
var badHandler = function (request) { | ||
request.reply.stream(new Stream); | ||
}; | ||
function setupServer(done) { | ||
_server = new Hapi.Server('0.0.0.0', 18085); | ||
_server = new Hapi.Server('0.0.0.0', 18085, { cache: 'memory' }); | ||
_server.addRoutes([ | ||
@@ -34,3 +40,4 @@ { method: 'GET', path: '/profile', config: { handler: profileHandler, cache: { mode: 'client', expiresIn: 120000 } } }, | ||
{ method: 'GET', path: '/item2', config: { handler: activeItemHandler, cache: { mode: 'none' } } }, | ||
{ method: 'GET', path: '/item3', config: { handler: activeItemHandler, cache: { mode: 'client', expiresIn: 120000 } } } | ||
{ method: 'GET', path: '/item3', config: { handler: activeItemHandler, cache: { mode: 'client', expiresIn: 120000 } } }, | ||
{ method: 'GET', path: '/bad', config: { handler: badHandler, cache: { expiresIn: 120000 } } } | ||
]); | ||
@@ -92,2 +99,12 @@ _server.listener.on('listening', function() { | ||
}); | ||
it('throws error when returning a stream in a cached endpoint handler', function (done) { | ||
function test() { | ||
makeRequest('/bad', function (rawRes) {}); | ||
} | ||
expect(test).to.throw(Error); | ||
done(); | ||
}); | ||
}); |
@@ -7,124 +7,119 @@ // Load modules | ||
require('../suite')(function (useRedis, useMongo) { | ||
describe('Proxy', function() { | ||
describe('Proxy', function () { | ||
before(startServer); | ||
before(startServer); | ||
var _server = null; | ||
var _serverUrl = 'http://127.0.0.1:18092'; | ||
var _server = null; | ||
var _serverUrl = 'http://127.0.0.1:18092'; | ||
function startServer(done) { | ||
function startServer(done) { | ||
var listening = false; | ||
var routeCache = null; | ||
var config = null; | ||
var listening = false; | ||
var config = null; | ||
if (useRedis) { | ||
routeCache = { | ||
mode: 'server', | ||
expiresIn: 500 | ||
}; | ||
var routeCache = { | ||
mode: 'server', | ||
expiresIn: 500 | ||
}; | ||
config = { | ||
cache: { | ||
engine: 'redis', | ||
host: '127.0.0.1', | ||
port: 6379 | ||
} | ||
}; | ||
config = { | ||
cache: { | ||
engine: 'memory', | ||
host: '127.0.0.1', | ||
port: 6379 | ||
} | ||
}; | ||
var dummyServer = new Hapi.Server('0.0.0.0', 18093); | ||
dummyServer.addRoutes([{ method: 'GET', path: '/profile', config: { handler: profile } }, | ||
{ method: 'GET', path: '/item', config: { handler: activeItem } }, | ||
{ method: 'POST', path: '/item', config: { handler: item } }]); | ||
var dummyServer = new Hapi.Server('0.0.0.0', 18093); | ||
dummyServer.addRoutes([{ method: 'GET', path: '/profile', config: { handler: profile } }, | ||
{ method: 'GET', path: '/item', config: { handler: activeItem } }, | ||
{ method: 'POST', path: '/item', config: { handler: item } }]); | ||
_server = new Hapi.Server('0.0.0.0', 18092, config); | ||
_server.addRoutes([ | ||
{ method: 'GET', path: '/profile', config: { proxy: { host: '127.0.0.1', port: 18093, xforward: true, passThrough: true } } }, | ||
{ method: 'GET', path: '/item', config: { proxy: { host: '127.0.0.1', port: 18093 }, cache: routeCache } }, | ||
{ method: 'POST', path: '/item', config: { proxy: { host: '127.0.0.1', port: 18093 } } } | ||
]); | ||
_server = new Hapi.Server('0.0.0.0', 18092, config); | ||
_server.addRoutes([ | ||
{ method: 'GET', path: '/profile', config: { proxy: { host: '127.0.0.1', port: 18093, xforward: true, passThrough: true } } }, | ||
{ method: 'GET', path: '/item', config: { proxy: { host: '127.0.0.1', port: 18093 }, cache: routeCache } }, | ||
{ method: 'POST', path: '/item', config: { proxy: { host: '127.0.0.1', port: 18093 } } } | ||
]); | ||
dummyServer.listener.on('listening', function() { | ||
if (listening) { | ||
done(); | ||
} | ||
else { | ||
listening = true; | ||
} | ||
}); | ||
_server.listener.on('listening', function() { | ||
if (listening) { | ||
done(); | ||
} | ||
else { | ||
listening = true; | ||
} | ||
}); | ||
dummyServer.listener.on('listening', function () { | ||
if (listening) { | ||
done(); | ||
} | ||
else { | ||
listening = true; | ||
} | ||
}); | ||
_server.listener.on('listening', function () { | ||
if (listening) { | ||
done(); | ||
} | ||
else { | ||
listening = true; | ||
} | ||
}); | ||
dummyServer.start(); | ||
_server.start(); | ||
} | ||
dummyServer.start(); | ||
_server.start(); | ||
} | ||
function profile(request) { | ||
request.reply({ | ||
'id': 'fa0dbda9b1b', | ||
'name': 'John Doe' | ||
}); | ||
} | ||
function profile(request) { | ||
request.reply({ | ||
'id': 'fa0dbda9b1b', | ||
'name': 'John Doe' | ||
}); | ||
} | ||
function activeItem(request) { | ||
request.reply({ | ||
'id': '55cf687663', | ||
'name': 'Active Item' | ||
}); | ||
} | ||
function activeItem(request) { | ||
request.reply({ | ||
'id': '55cf687663', | ||
'name': 'Active Item' | ||
}); | ||
} | ||
function item(request) { | ||
request.reply.created('http://google.com')({ | ||
'id': '55cf687663', | ||
'name': 'Item' | ||
}); | ||
} | ||
function item(request) { | ||
request.reply.created('http://google.com')({ | ||
'id': '55cf687663', | ||
'name': 'Item' | ||
}); | ||
} | ||
function makeRequest(options, callback) { | ||
var next = function(err, res) { | ||
return callback(res); | ||
}; | ||
function makeRequest(options, callback) { | ||
var next = function (err, res) { | ||
return callback(res); | ||
}; | ||
options = options || {}; | ||
options.path = options.path || '/'; | ||
options.method = options.method || 'get'; | ||
options = options || {}; | ||
options.path = options.path || '/'; | ||
options.method = options.method || 'get'; | ||
Request({ | ||
method: options.method, | ||
url: _serverUrl + options.path | ||
}, next); | ||
} | ||
Request({ | ||
method: options.method, | ||
url: _serverUrl + options.path | ||
}, next); | ||
} | ||
it('forwards on the response when making a GET request', function(done) { | ||
makeRequest({ path: '/profile' }, function(rawRes) { | ||
expect(rawRes.statusCode).to.equal(200); | ||
expect(rawRes.body).to.contain('John Doe'); | ||
done(); | ||
}); | ||
it('forwards on the response when making a GET request', function (done) { | ||
makeRequest({ path: '/profile' }, function (rawRes) { | ||
expect(rawRes.statusCode).to.equal(200); | ||
expect(rawRes.body).to.contain('John Doe'); | ||
done(); | ||
}); | ||
}); | ||
it('forwards on the response when making a GET request to a route that also accepts a POST', function(done) { | ||
makeRequest({ path: '/item' }, function(rawRes) { | ||
expect(rawRes.statusCode).to.equal(200); | ||
expect(rawRes.body).to.contain('Active Item'); | ||
done(); | ||
}); | ||
it('forwards on the response when making a GET request to a route that also accepts a POST', function (done) { | ||
makeRequest({ path: '/item' }, function (rawRes) { | ||
expect(rawRes.statusCode).to.equal(200); | ||
expect(rawRes.body).to.contain('Active Item'); | ||
done(); | ||
}); | ||
}); | ||
it('forwards on the status code when making a POST request', function(done) { | ||
makeRequest({ path: '/item', method: 'post' }, function(rawRes) { | ||
expect(rawRes.statusCode).to.equal(201); | ||
expect(rawRes.body).to.contain('Item'); | ||
done(); | ||
}); | ||
it('forwards on the status code when making a POST request', function (done) { | ||
makeRequest({ path: '/item', method: 'post' }, function (rawRes) { | ||
expect(rawRes.statusCode).to.equal(201); | ||
expect(rawRes.body).to.contain('Item'); | ||
done(); | ||
}); | ||
}); | ||
}); |
var expect = require('chai').expect; | ||
var Error = process.env.TEST_COV ? require('../../lib-cov/error') : require('../../lib/error'); | ||
var Err = process.env.TEST_COV ? require('../../lib-cov/error') : require('../../lib/error'); | ||
describe('Error', function() { | ||
describe('Err', function() { | ||
@@ -9,3 +9,3 @@ describe('#badRequest', function() { | ||
it('returns a 400 error code', function(done) { | ||
expect(Error.badRequest().code).to.equal(400); | ||
expect(Err.badRequest().code).to.equal(400); | ||
done(); | ||
@@ -15,3 +15,3 @@ }); | ||
it('sets the message with the passed in message', function(done) { | ||
expect(Error.badRequest('my message').message).to.equal('my message'); | ||
expect(Err.badRequest('my message').message).to.equal('my message'); | ||
done(); | ||
@@ -24,3 +24,3 @@ }); | ||
it('returns a 401 error code', function(done) { | ||
expect(Error.unauthorized().code).to.equal(401); | ||
expect(Err.unauthorized().code).to.equal(401); | ||
done(); | ||
@@ -30,3 +30,3 @@ }); | ||
it('sets the message with the passed in message', function(done) { | ||
expect(Error.unauthorized('my message').message).to.equal('my message'); | ||
expect(Err.unauthorized('my message').message).to.equal('my message'); | ||
done(); | ||
@@ -39,3 +39,3 @@ }); | ||
it('returns a 403 error code', function(done) { | ||
expect(Error.forbidden().code).to.equal(403); | ||
expect(Err.forbidden().code).to.equal(403); | ||
done(); | ||
@@ -45,3 +45,3 @@ }); | ||
it('sets the message with the passed in message', function(done) { | ||
expect(Error.forbidden('my message').message).to.equal('my message'); | ||
expect(Err.forbidden('my message').message).to.equal('my message'); | ||
done(); | ||
@@ -54,3 +54,3 @@ }); | ||
it('returns a 404 error code', function(done) { | ||
expect(Error.notFound().code).to.equal(404); | ||
expect(Err.notFound().code).to.equal(404); | ||
done(); | ||
@@ -60,3 +60,3 @@ }); | ||
it('sets the message with the passed in message', function(done) { | ||
expect(Error.notFound('my message').message).to.equal('my message'); | ||
expect(Err.notFound('my message').message).to.equal('my message'); | ||
done(); | ||
@@ -69,3 +69,3 @@ }); | ||
it('returns a 500 error code', function(done) { | ||
expect(Error.internal().code).to.equal(500); | ||
expect(Err.internal().code).to.equal(500); | ||
done(); | ||
@@ -75,3 +75,3 @@ }); | ||
it('sets the message with the passed in message', function(done) { | ||
expect(Error.internal('my message').message).to.equal('my message'); | ||
expect(Err.internal('my message').message).to.equal('my message'); | ||
done(); | ||
@@ -81,3 +81,3 @@ }); | ||
it('passes data on the callback if its passed in', function(done) { | ||
expect(Error.internal('my message', { my: 'data' }).data.my).to.equal('data'); | ||
expect(Err.internal('my message', { my: 'data' }).data.my).to.equal('data'); | ||
done(); | ||
@@ -87,24 +87,13 @@ }); | ||
describe('#_oauth', function() { | ||
describe('#format', function() { | ||
it('returns a 400 error code', function(done) { | ||
expect(Error._oauth('mycode', 'mymessage').code).to.equal(400); | ||
done(); | ||
}); | ||
it('formats a custom error', function (done) { | ||
it('sets the passed in text', function(done) { | ||
expect(Error._oauth('mycode', 'mymessage').text).to.equal('mymessage'); | ||
done(); | ||
}); | ||
var err = new Error(); | ||
err.toResponse = function () { | ||
it('sets the passed in code', function(done) { | ||
expect(Error._oauth('mycode', 'mymessage').error).to.equal('mycode'); | ||
done(); | ||
}); | ||
}); | ||
return { test: true }; | ||
}; | ||
describe('#format', function() { | ||
it('formats oauth errors separately', function(done) { | ||
expect(Error.format({ type: 'oauth', text: 'myerror' }).error_description).to.equal('myerror'); | ||
expect(Err.format(err).test).to.equal(true); | ||
done(); | ||
@@ -114,3 +103,3 @@ }); | ||
it('formats internal errors with a standard message', function(done) { | ||
expect(Error.format({ code: 500 }).message).to.equal('An internal server error occurred'); | ||
expect(Err.format({ code: 500 }).message).to.equal('An internal server error occurred'); | ||
done(); | ||
@@ -117,0 +106,0 @@ }); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
469684
7511
926
50