From ceceb44e78c42f601c24525d190f85a47ba4f48b Mon Sep 17 00:00:00 2001 From: ebarault Date: Tue, 31 Jan 2017 23:07:24 +0100 Subject: [PATCH] Add promise support to built-in model RoleMapping --- common/models/role-mapping.js | 20 ++++-- test/role-mapping.test.js | 116 ++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 6 deletions(-) create mode 100644 test/role-mapping.test.js diff --git a/common/models/role-mapping.js b/common/models/role-mapping.js index 630cbd3c..8dfa5808 100644 --- a/common/models/role-mapping.js +++ b/common/models/role-mapping.js @@ -5,6 +5,7 @@ 'use strict'; var loopback = require('../../lib/loopback'); +var utils = require('../../lib/utils'); /** * The `RoleMapping` model extends from the built in `loopback.Model` type. @@ -26,9 +27,9 @@ module.exports = function(RoleMapping) { RoleMapping.resolveRelatedModels = function() { if (!this.userModel) { var reg = this.registry; - this.roleModel = reg.getModelByType(loopback.Role); - this.userModel = reg.getModelByType(loopback.User); - this.applicationModel = reg.getModelByType(loopback.Application); + this.roleModel = reg.getModelByType('Role'); + this.userModel = reg.getModelByType('User'); + this.applicationModel = reg.getModelByType('Application'); } }; @@ -39,6 +40,7 @@ module.exports = function(RoleMapping) { * @param {Application} application */ RoleMapping.prototype.application = function(callback) { + callback = callback || utils.createPromiseCallback(); this.constructor.resolveRelatedModels(); if (this.principalType === RoleMapping.APPLICATION) { @@ -46,9 +48,10 @@ module.exports = function(RoleMapping) { applicationModel.findById(this.principalId, callback); } else { process.nextTick(function() { - if (callback) callback(null, null); + callback(null, null); }); } + return callback.promise; }; /** @@ -58,15 +61,18 @@ module.exports = function(RoleMapping) { * @param {User} user */ RoleMapping.prototype.user = function(callback) { + callback = callback || utils.createPromiseCallback(); this.constructor.resolveRelatedModels(); + if (this.principalType === RoleMapping.USER) { var userModel = this.constructor.userModel; userModel.findById(this.principalId, callback); } else { process.nextTick(function() { - if (callback) callback(null, null); + callback(null, null); }); } + return callback.promise; }; /** @@ -76,6 +82,7 @@ module.exports = function(RoleMapping) { * @param {User} childUser */ RoleMapping.prototype.childRole = function(callback) { + callback = callback || utils.createPromiseCallback(); this.constructor.resolveRelatedModels(); if (this.principalType === RoleMapping.ROLE) { @@ -83,8 +90,9 @@ module.exports = function(RoleMapping) { roleModel.findById(this.principalId, callback); } else { process.nextTick(function() { - if (callback) callback(null, null); + callback(null, null); }); } + return callback.promise; }; }; diff --git a/test/role-mapping.test.js b/test/role-mapping.test.js new file mode 100644 index 00000000..afc794b0 --- /dev/null +++ b/test/role-mapping.test.js @@ -0,0 +1,116 @@ +// Copyright IBM Corp. 2013,2016. All Rights Reserved. +// Node module: loopback +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +'use strict'; +var expect = require('./helpers/expect'); +var loopback = require('../'); +var Promise = require('bluebird'); + +describe('role-mapping model', function() { + this.timeout(10000); + + var app, oneUser, anApp, aRole; + var models = {}; + + beforeEach(function() { + app = loopback({localRegistry: true, loadBuiltinModels: true}); + app.dataSource('db', {connector: 'memory'}); + + // setup models + ['User', 'Role', 'RoleMapping', 'Application'].map(setupModel); + + // create generic instances + return Promise.all([ + models.User.create({ + username: 'oneUser', + email: 'user@email.com', + password: 'password', + }), + models.Application.create({name: 'anApp'}), + models.Role.create({name: 'aRole'}), + ]) + .spread(function(u, a, r) { + oneUser = u; + anApp = a; + aRole = r; + }); + + // helper + function setupModel(modelName) { + var model = app.registry.getModel(modelName); + app.model(model, {dataSource: 'db'}); + models[modelName] = model; + } + }); + + it('supports .user() with a callback', function(done) { + models.RoleMapping.create( + {principalType: 'USER', principalId: oneUser.id}, + function(err, mapping) { + if (err) done(err); + mapping.user(function(err, user) { + if (err) done(err); + expect(user.id).to.equal(oneUser.id); + done(); + }); + }); + }); + + it('supports .user() returning a promise', function() { + return models.RoleMapping.create({principalType: 'USER', principalId: oneUser.id}) + .then(function(mapping) { + return mapping.user(); + }) + .then(function(user) { + expect(user.id).to.equal(oneUser.id); + }); + }); + + it('supports .application() with a callback', function(done) { + models.RoleMapping.create( + {principalType: 'APP', principalId: anApp.id}, + function(err, mapping) { + if (err) done(err); + mapping.application(function(err, app) { + if (err) done(err); + expect(app.id).to.equal(anApp.id); + done(); + }); + }); + }); + + it('supports .application() returning a promise', function() { + return models.RoleMapping.create({principalType: 'APP', principalId: anApp.id}) + .then(function(mapping) { + return mapping.application(); + }) + .then(function(app) { + expect(app.id).to.equal(anApp.id); + }); + }); + + it('supports .childRole() with a callback', function(done) { + models.RoleMapping.create( + {principalType: 'ROLE', principalId: aRole.id}, + function(err, mapping) { + if (err) done(err); + mapping.childRole(function(err, role) { + if (err) done(err); + expect(role.id).to.equal(aRole.id); + done(); + }); + }); + }); + + it('supports .childRole() returning a promise', function() { + return models.RoleMapping.create({principalType: 'ROLE', principalId: aRole.id}) + .then(function(mapping) { + return mapping.childRole(); + }) + .then(function(role) { + expect(role.id).to.equal(aRole.id); + }); + }); +});