UNPKG

rest-handler

Version:

A module for creating a request handler that does REST style routing

350 lines (281 loc) 10.5 kB
var chai = require('chai'); chai.Assertion.includeStack = true; require('chai').should(); var MockRequest = require('./MockRequest'); var MockResponse = require('./MockResponse'); var expect = require('chai').expect; describe('default GET method routing configuration', function() { var myRestHandler = require('..').create({ routes: [ '/cars', '/cars/:carId', '/trucks', '/trucks/:truckId' ] }); var router = myRestHandler.getMethodRouter('*'); it('should contain 4 routes', function() { expect(router.getRoutes().length).to.equal(4); }); it('should contain routes that we expect', function() { expect(router.getRoutes()[0].toString()).to.equal('/cars'); expect(router.getRoutes()[1].toString()).to.equal('/cars/:carId'); expect(router.getRoutes()[2].toString()).to.equal('/trucks'); expect(router.getRoutes()[3].toString()).to.equal('/trucks/:truckId'); }); it('should find match /cars', function() { var match = router.findRoute('/cars'); expect(match).to.not.equal(null); expect(match.route.toString()).to.equal('/cars'); }); it('should find match /cars/123', function() { var match = router.findRoute('/cars/123'); expect(match.params.carId).to.equal('123'); expect(match.route.toString(match.params)).to.equal('/cars/123'); }); it('should not find match /cars/123/bad', function() { var match = router.findRoute('/cars/123/bad'); expect(match).to.equal(null); }); it('should support resetting of routing table', function() { router.reset(); expect(router.getRoutes().length).to.equal(0); }); }); describe('route request', function() { var carsResponse = { cars: [ { _id: 'car1' }, { _id: 'car2' } ] }; var myRestHandler = require('..') .create() .before(function(rest) { rest.beforeInvoked = true; rest.next(); }) .middleware({ init: function(restHandler) { restHandler.on('route', function(event) { var route = event.route; if (route.path === '/route-specific-middleware') { route.addBefore(function(rest) { rest.specialMiddlewareAdded = true; rest.next(); }); } }); } }); [ { path: '/cars', method: 'GET', before: function(rest) { rest.routeBeforeInvoked = true; rest.next(); }, handler: function(rest) { rest.send(carsResponse); } }, { path: '/cars', method: 'POST', handler: function(rest) { rest.send({ success: true }); } }, { path: '/cars/:carId', handler: function(rest) { rest.send({ _id: rest.params.carId }); } }, { path: '/cause/error', handler: function(rest) { rest.error('Danger! System overheating.'); } }, { path: '/cause/error/:statusCode', handler: function(rest) { rest.error(Number(rest.params.statusCode), 'Danger! System overheating.'); } }, { path: '/echo/body', handler: function(rest) { rest.getBody(function(err, body) { rest.send(body); }); } }, { path: '/echo/parsed-body', handler: function(rest) { rest.getParsedBody(function(err, body) { rest.send(body); }); } }, { path: '/route-specific-middleware', handler: function(rest) { rest.send('Success'); } } ].forEach(function(routeConfig) { myRestHandler.addRoute(routeConfig); }); it('should send 404 for unrecognized route', function() { var req = new MockRequest(); req.url = '/does/not/exist'; var res = new MockResponse(); myRestHandler.handle(req, res); expect(res.statusCode).to.equal(404); }); it('should format response as application/json', function() { var req = new MockRequest(); req.url = '/cars'; var res = new MockResponse(); myRestHandler.handle(req, res); expect(res.getHeader('Content-Type')).to.equal('application/json'); expect(JSON.parse(res.mock_getWritten())).to.deep.equal(carsResponse); }); it('should return method not allowed if route match found but not for exact method', function() { var req = new MockRequest(); req.url = '/cars'; req.method = 'PATCH'; var res = new MockResponse(); myRestHandler.handle(req, res); expect(res.getHeader('Allow')).to.equal('GET,POST'); expect(res.statusCode).to.equal(405); expect(res.mock_getWritten()).to.equal('Method Not Allowed'); }); it('should handle parameters', function() { var req = new MockRequest(); req.url = '/cars/123'; var res = new MockResponse(); var rest = myRestHandler.handle(req, res); expect(res.getHeader('Content-Type')).to.equal('application/json'); expect(rest.params.carId).to.equal('123'); expect(JSON.parse(res.mock_getWritten())).to.deep.equal({ _id: '123' }); }); it('should serialize errors and use default 500 status code', function() { var req = new MockRequest(); req.url = '/cause/error'; var res = new MockResponse(); var rest = myRestHandler.handle(req, res); expect(res.getHeader('Content-Type')).to.equal('text/plain'); expect(rest.res.statusCode).to.equal(500); expect(res.mock_getWritten()).to.equal('Danger! System overheating.'); }); it('should support middleware added via before()', function() { var req = new MockRequest(); req.url = '/cause/error'; var res = new MockResponse(); var rest = myRestHandler.handle(req, res); expect(rest.beforeInvoked).to.equal(true); }); it('should support middleware with an init function', function() { var req = new MockRequest(); req.url = '/route-specific-middleware'; var res = new MockResponse(); var rest = myRestHandler.handle(req, res); expect(rest.url.path).to.equal('/route-specific-middleware'); expect(rest.route._before.length).to.equal(1); expect(rest.specialMiddlewareAdded).to.equal(true); }); it('should support route-specific middleware', function() { var req = new MockRequest(); req.url = '/cars'; var res = new MockResponse(); var rest = myRestHandler.handle(req, res); expect(rest.routeBeforeInvoked).to.equal(true); }); it('should serialize errors and use given status code', function() { var req = new MockRequest(); req.url = '/cause/error/400'; var res = new MockResponse(); var rest = myRestHandler.handle(req, res); expect(res.getHeader('Content-Type')).to.equal('text/plain'); expect(rest.res.statusCode).to.equal(400); expect(res.mock_getWritten()).to.equal('Danger! System overheating.'); }); it('should support rest.getBody()', function() { var req = new MockRequest({ method: 'POST', // simulate chunks of data data: [new Buffer('this '), new Buffer('is '), new Buffer('a '), new Buffer('test')] }); req.url = '/echo/body'; var res = new MockResponse(); var rest = myRestHandler.handle(req, res); expect(res.getHeader('Content-Type')).to.equal('text/plain'); expect(rest.res.statusCode).to.equal(200); expect(res.mock_getWritten()).to.equal('this is a test'); }); it('should support rest.getBodyBuffer()', function() { var req = new MockRequest({ method: 'POST', // simulate chunks of data data: [new Buffer('this '), new Buffer('is '), new Buffer('a '), new Buffer('test')] }); req.url = '/echo/body'; var res = new MockResponse(); var rest = myRestHandler.handle(req, res); expect(res.getHeader('Content-Type')).to.equal('text/plain'); expect(rest.res.statusCode).to.equal(200); expect(res.mock_getWritten()).to.equal((new Buffer('this is a test')).toString()); }); it('should support rest.getParsedBody()', function() { var req = new MockRequest({ method: 'POST', // simulate chunks of data data: [new Buffer('{'), new Buffer('"a":'), new Buffer('123'), new Buffer('}')] }); req.url = '/echo/parsed-body'; var res = new MockResponse(); var rest = myRestHandler.handle(req, res); expect(res.getHeader('Content-Type')).to.equal('application/json'); expect(rest.res.statusCode).to.equal(200); expect(JSON.parse(res.mock_getWritten())).to.deep.equal({ a: 123 }); }); }); describe('notFound overrride', function() { var myRestHandler = require('..') .create({ onRouteNotFound: function(message, req, res, socket) { if (typeof message !== "string") { res = req; req = message; } res.setHeader('Content-Type', 'text/plain'); res.statusCode = 200; res.end("Custom Handler"); } }); it('should send 200 for unrecognized route', function() { var req = new MockRequest(); req.url = '/does/not/exist'; var res = new MockResponse(); myRestHandler.handle(req, res); expect(res.statusCode).to.equal(200); expect(res.mock_getWritten()).to.equal("Custom Handler"); }); });