UNPKG

mudskipper

Version:

a resourceful routing plugin for hapi

617 lines (516 loc) 19.1 kB
var lab = exports.lab = require('lab').script(); var Hapi = require('hapi'); var Joi = require('joi'); // Declare internals var internals = {}; // Test shortcuts var expect = require('code').expect; var before = lab.before; var after = lab.after; var describe = lab.experiment; var it = lab.test; var internalsSmall1 = { namespace: 'api', resources: { users: { index: function (request, reply) { reply(); }, show: function (request, reply) { reply(); } } } }; var internalsSmall2 = { namespace: 'web', resources: { root: { handler: function (request, reply) { reply(); } } } }; internals.namespace = 'api'; internals.resources = { root: { handler: function (request, reply) { reply({ reply: 'root' }); } }, users: { hasMany: ['articles', 'comments'], index: function (request, reply) { reply({ reply: 'users index' }); }, show: { handler: function (request, reply) { reply({ reply: 'users show ' + (request.params.userId || '5') }); }, config: { validate: { path: { userId: Joi.number() } } } } }, articles: { hasOne: 'users', hasMany: 'comments', index: function (request, reply) { reply({ reply: 'articles index' }); }, show: function (request, reply) { reply({ reply: 'articles show ' + request.params.articleId }); }, create: { handler: function (request, reply) { reply({ reply: 'articles create ' + request.payload.title }).code(201); }, config: { validate: { payload: { title: Joi.string() } } } } }, comments: { hasOne: ['users'], index: function (request, reply) { reply({ reply: 'comments index' }); }, destroy: function (request, reply) { reply({ reply: 'comments destroy ' + request.params.commentId }); } }, bananas: { hasMany: { skins: { index: function (request, reply) { reply({ reply: 'skins index' }); } } }, path: '/banana', show: function (request, reply) { reply({ reply: 'bananas show ' + request.params.bananaId }); } } }; var internalsAdd = { resources: { tests: { index: function (request, reply) { reply('ok'); } } } }; var server, table; describe('plugin', function () { it('can be added to hapi', function (done) { server = new Hapi.Server(); server.connection(); server.register({ register: require('../'), options: internals }, function (err) { expect(err).to.not.exist(); done(); }); }); it('can add more routes after being loaded', function (done) { server.plugins.mudskipper.route(internalsAdd, function () { table = server.table()[0].table; done(); }); }); it('can be loaded twice', function (done) { var server = new Hapi.Server(); server.connection({ labels: 'one' }); server.connection({ labels: 'two' }); server.register({ register: require('../'), options: internalsSmall1 }, { select: 'one' }, function (err) { expect(err).to.not.exist(); server.register({ register: require('../'), options: internalsSmall2 }, { select: 'two' }, function (err) { expect(err).to.not.exist(); var table1 = server.select('one').table()[0].table; var table2 = server.select('two').table()[0].table; expect(table1).to.have.length(2); expect(table2).to.have.length(1); done(); }); }); }); }); describe('root', function () { it('registered the additional route', function (done) { var found = table.filter(function (route) { return (route.method === 'get' && route.path === '/tests'); }); expect(found).to.have.length(1); done(); }); it('registers a route', function (done) { var found = table.filter(function (route) { return (route.method === 'get' && route.path === '/api'); }); expect(found).to.have.length(1); done(); }); it('responds to index', function (done) { server.inject({ method: 'get', url: '/api' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.be.an.object(); expect(res.result.reply).to.deep.equal('root'); done(); }); }); }); describe('users', function () { it('registers base routes', function (done) { var found = table.filter(function (route) { return (route.method === 'get' && route.path === '/api/users') || (route.method === 'get' && route.path === '/api/users/{userId}'); }); expect(found).to.have.length(2); done(); }); it('registers nested routes', function (done) { var found = table.filter(function (route) { return (route.method === 'get' && route.path === '/api/articles/{articleId}/user') || (route.method === 'get' && route.path === '/api/articles/{articleId}/comments/{commentId}/user') || (route.method === 'get' && route.path === '/api/comments/{commentId}/user'); }); expect(found).to.have.length(3); done(); }); it('responds to index', function (done) { server.inject({ method: 'get', url: '/api/users' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.be.an.object(); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('users index'); done(); }); }); it('responds to show', function (done) { server.inject({ method: 'get', url: '/api/users/5' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.be.an.object(); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('users show 5'); done(); }); }); it('responds to show nested on articles', function (done) { server.inject({ method: 'get', url: '/api/articles/5/user' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('users show 5'); done(); }); }); it('responds to show nested on comments', function (done) { server.inject({ method: 'get', url: '/api/comments/5/user' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('users show 5'); done(); }); }); }); describe('articles', function () { it('registers base routes', function (done) { var found = table.filter(function (route) { return (route.method === 'get' && route.path === '/api/articles') || (route.method === 'get' && route.path === '/api/articles/{articleId}') || (route.method === 'post' && route.path === '/api/articles'); }); expect(found).to.have.length(3); done(); }); it('registers nested routes', function (done) { var found = table.filter(function (route) { return (route.method === 'get' && route.path === '/api/users/{userId}/articles') || (route.method === 'get' && route.path === '/api/users/{userId}/articles/{articleId}') || (route.method === 'post' && route.path === '/api/users/{userId}/articles') || (route.method === 'get' && route.path === '/api/comments/{commentId}/user/articles') || (route.method === 'get' && route.path === '/api/comments/{commentId}/user/articles/{articleId}') || (route.method === 'post' && route.path === '/api/comments/{commentId}/user/articles'); }); expect(found).to.have.length(6); done(); }); it('responds to index', function (done) { server.inject({ method: 'get', url: '/api/articles' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('articles index'); done(); }); }); it('responds to show', function (done) { server.inject({ method: 'get', url: '/api/articles/5' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.be.an.object(); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('articles show 5'); done(); }); }); it('responds to create', function (done) { server.inject({ method: 'post', url: '/api/articles', payload: { title: 'test' } }, function (res) { expect(res.statusCode).to.equal(201); expect(res.result).to.be.an.object(); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('articles create test'); done(); }); }); it('responds to index nested on users', function (done) { server.inject({ method: 'get', url: '/api/users/5/articles' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('articles index'); done(); }); }); it('responds to index nested on user nested on comments', function (done) { server.inject({ method: 'get', url: '/api/comments/5/user/articles' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('articles index'); done(); }); }); it('responds to show nested on users', function (done) { server.inject({ method: 'get', url: '/api/users/5/articles/5' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.be.an.object(); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('articles show 5'); done(); }); }); it('responds to show nested on user nested on comments', function (done) { server.inject({ method: 'get', url: '/api/comments/5/user/articles/5' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.be.an.object(); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('articles show 5'); done(); }); }); it('responds to create nested on users', function (done) { server.inject({ method: 'post', url: '/api/users/5/articles', payload: { title: 'test' } }, function (res) { expect(res.statusCode).to.equal(201); expect(res.result).to.be.an.object(); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('articles create test'); done(); }); }); it('responds to create nested on user nested on comments', function (done) { server.inject({ method: 'post', url: '/api/comments/5/user/articles', payload: { title: 'test' } }, function (res) { expect(res.statusCode).to.equal(201); expect(res.result).to.be.an.object(); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('articles create test'); done(); }); }); }); describe('comments', function () { it('registers base routes', function (done) { var found = table.filter(function (route) { return (route.method === 'get' && route.path === '/api/comments') || (route.method === 'delete' && route.path === '/api/comments/{commentId}'); }); expect(found).to.have.length(2); done(); }); it('registers nested routes', function (done) { var found = table.filter(function (route) { return (route.method === 'get' && route.path === '/api/users/{userId}/comments') || (route.method === 'delete' && route.path === '/api/users/{userId}/comments/{commentId}') || (route.method === 'get' && route.path === '/api/articles/{articleId}/comments') || (route.method === 'delete' && route.path === '/api/articles/{articleId}/comments/{commentId}') || (route.method === 'get' && route.path === '/api/articles/{articleId}/user/comments') || (route.method === 'delete' && route.path === '/api/articles/{articleId}/user/comments/{commentId}'); }); expect(found).to.have.length(6); done(); }); it('responds to index', function (done) { server.inject({ method: 'get', url: '/api/comments' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.be.an.object(); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('comments index'); done(); }); }); it('responds to destroy', function (done) { server.inject({ method: 'delete', url: '/api/comments/5' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.be.an.object(); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('comments destroy 5'); done(); }); }); it('responds to index nested on users', function (done) { server.inject({ method: 'get', url: '/api/users/5/comments' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.be.an.object(); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('comments index'); done(); }); }); it('responds to index nested on articles', function (done) { server.inject({ method: 'get', url: '/api/articles/5/comments' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.be.an.object(); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('comments index'); done(); }); }); it('responds to index nested on user nested on articles', function (done) { server.inject({ method: 'get', url: '/api/articles/5/user/comments' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.be.an.object(); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('comments index'); done(); }); }); it('responds to destroy nested on users', function (done) { server.inject({ method: 'delete', url: '/api/users/5/comments/5' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.be.an.object(); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('comments destroy 5'); done(); }); }); it('responds to destroy nested on articles', function (done) { server.inject({ method: 'delete', url: '/api/articles/5/comments/5' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.be.an.object(); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('comments destroy 5'); done(); }); }); it('responds to destroy nested on user nested on articles', function (done) { server.inject({ method: 'delete', url: '/api/articles/5/user/comments/5' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.be.an.object(); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('comments destroy 5'); done(); }); }); }); describe('bananas', function () { it('registers base route', function (done) { var found = table.filter(function (route) { return (route.method === 'get' && route.path === '/banana/{bananaId}'); }); expect(found).to.have.length(1); done(); }); it('responds to show', function (done) { server.inject({ method: 'get', url: '/banana/5' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.be.an.object(); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('bananas show 5'); done(); }); }); }); describe('skins', function () { it('registers the route', function (done) { var found = table.filter(function (route) { return (route.method === 'get' && route.path === '/banana/{bananaId}/skins'); }); expect(found).to.have.length(1); done(); }); it('responds to index', function (done) { server.inject({ method: 'get', url: '/banana/5/skins' }, function (res) { expect(res.statusCode).to.equal(200); expect(res.result).to.be.an.object(); expect(res.result).to.include('reply'); expect(res.result.reply).to.deep.equal('skins index'); done(); }); }); });