Skip to content
This repository was archived by the owner on May 29, 2019. It is now read-only.

Add support for non-default models #57

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 90 additions & 13 deletions lib/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ var assert = require('assert');
var request = require('supertest');
var expect = require('chai').expect;

var DEFAULT_USER_MODEL = 'user';
var DEFAULT_ACCESS_TOKEN_MODEL = 'accessToken';
var DEFAULT_ROLE_MODEL = 'Role';
var DEFAULT_ROLE_MAPPING_MODEL = 'roleMapping';

_beforeEach.withApp = function(app) {
if (app.models.User) {
// Speed up the password hashing algorithm
Expand All @@ -36,7 +41,7 @@ _beforeEach.cleanDatasource = function(dsName) {
this.app.datasources[dsName].automigrate();
this.app.datasources[dsName].connector.ids = {};
}

done();
});
}
Expand Down Expand Up @@ -77,7 +82,7 @@ _beforeEach.withArgs = function() {
}

_beforeEach.givenModel = function(modelName, attrs, optionalHandler) {
var modelKey = modelName;
var modelKey;

if(typeof attrs === 'function') {
optionalHandler = attrs;
Expand All @@ -91,10 +96,17 @@ _beforeEach.givenModel = function(modelName, attrs, optionalHandler) {
attrs = attrs || {};

beforeEach(function(done) {
if(modelName === '__USERMODEL__') {
modelName = this.userModel ? this.userModel : 'user';

if (modelName === '__USERMODEL__') {
modelName = this.userModel ?
this.userModel : DEFAULT_USER_MODEL;
} else if (modelName === '__ACCESSTOKENMODEL__') {
modelName = this.accessTokenModel ?
this.accessTokenModel : DEFAULT_ACCESS_TOKEN_MODEL;
}

modelKey = modelName;

var test = this;
var app = this.app;
var model = app.models[modelName];
Expand Down Expand Up @@ -134,32 +146,75 @@ _beforeEach.withUserModel = function(model) {
});
};

_beforeEach.withAccessTokenModel = function(model) {
beforeEach(function(done) {
this.accessTokenModel = model;
done();
});
};

_beforeEach.withRoleModel = function(model) {
beforeEach(function(done) {
this.roleModel = model;
done();
});
};

_beforeEach.withRoleMappingModel = function(model) {
beforeEach(function(done) {
this.roleMappingModel = model;
done();
});
};

_beforeEach.givenUser = function(attrs, optionalHandler) {
_beforeEach.givenModel('__USERMODEL__', attrs, optionalHandler);
}

_beforeEach.givenUserWithRole = function (attrs, role, optionalHandler) {
_beforeEach.givenUser(attrs, function (done) {
var test = this;
test.app.models.Role.findOrCreate({name: role}, function (err, result) {

var roleModelName = test.roleModel ?
test.roleModel : DEFAULT_ROLE_MODEL;

var Role = test.app.models[roleModelName];

if (!Role) {
return done('Role model with name ' +
roleModelName + ' not found');
}

Role.findOrCreate({name: role}, function (err, result) {
if(err) {
console.error(err.message);
if(err.details) console.error(err.details);
return done(err);
}

test.userRole = result;
test.app.models.roleMapping.create(

var roleMappingModelName = test.roleMappingModel ?
test.roleMappingModel : DEFAULT_ROLE_MAPPING_MODEL;

var RoleMapping = test.app.models[roleMappingModelName];

if (!RoleMapping) {
return done('RoleMapping model with name ' +
roleMappingModelName + ' not found');
}

RoleMapping.create(
{principalId: test.user.id,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The User model name also needs to be dynamically resolved. So, test.user.id will not resolve. Something like below would work:

var userModelName = test.userModel ?  test.userModel : DEFAULT_USER_MODEL;
RoleMapping.create(
    {principalId: test[userModelName].id,
    principalType: RoleMapping.USER,
    roleId: result.id}, ..)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zero5100 I would also suggest to add more tests to test the new and impacted existing methods.

principalType: test.app.models.roleMapping.USER,
principalType: RoleMapping.USER,
roleId: result.id},
function (err, result) {
if(err) {
console.error(err.message);
if(err.details) console.error(err.details);
return done(err);
}

test.userRoleMapping = result;
done();
}
Expand Down Expand Up @@ -189,7 +244,18 @@ _beforeEach.givenUserWithRole = function (attrs, role, optionalHandler) {
_beforeEach.givenLoggedInUser = function(credentials, optionalHandler) {
_beforeEach.givenUser(credentials, function(done) {
var test = this;
this.app.models[this.userModel].constructor.login(credentials, function(err, token) {

var userModelName = this.userModel ?
this.userModel : DEFAULT_USER_MODEL;

var User = test.app.models[userModelName];

if (!User) {
return done('User model with name ' +
userModelName + ' not found');
}

User.login(credentials, function(err, token) {
if(err) {
done(err);
} else {
Expand All @@ -212,7 +278,18 @@ _beforeEach.givenLoggedInUser = function(credentials, optionalHandler) {
_beforeEach.givenLoggedInUserWithRole = function(credentials, role, optionalHandler){
_beforeEach.givenUserWithRole(credentials, role, function(done) {
var test = this;
this.app.models[this.userModel].constructor.login(credentials, function(err, token) {

var userModelName = test.userModel ?
test.userModel : DEFAULT_USER_MODEL;

var User = test.app.models[userModelName];

if (!User) {
return done('User model with name ' +
userModelName + ' not found');
}

User.login(credentials, function(err, token) {
if(err) {
done(err);
} else {
Expand All @@ -233,11 +310,11 @@ _beforeEach.givenLoggedInUserWithRole = function(credentials, role, optionalHand
}

_beforeEach.givenAnUnauthenticatedToken = function(attrs, optionalHandler) {
_beforeEach.givenModel('accessToken', attrs, optionalHandler);
_beforeEach.givenModel('__ACCESSTOKENMODEL__', attrs, optionalHandler);
}

_beforeEach.givenAnAnonymousToken = function(attrs, optionalHandler) {
_beforeEach.givenModel('accessToken', {id: '$anonymous'}, optionalHandler);
_beforeEach.givenModel('__ACCESSTOKENMODEL__', {id: '$anonymous'}, optionalHandler);
}

_describe.whenCalledRemotely = function(verb, url, data, cb) {
Expand Down Expand Up @@ -323,7 +400,7 @@ _describe.whenCalledByUserWithRole = function (credentials, role, verb, url, dat
describe('when called by logged in user with role ' + role, function () {
_beforeEach.givenLoggedInUserWithRole(credentials, role);
_describe.whenCalledRemotely(verb, url, data, cb);
});
});
}

_describe.whenCalledAnonymously = function(verb, url, data, cb) {
Expand Down
17 changes: 15 additions & 2 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ describe('helpers', function () {
'shouldBeAllowedWhenCalledUnauthenticated',
'shouldBeDeniedWhenCalledUnauthenticated',
'shouldBeAllowedWhenCalledByUser',
'shouldBeDeniedWhenCalledByUser']
'shouldBeDeniedWhenCalledByUser',
'shouldBeAllowedWhenCalledByUserWithRole',
'shouldBeDeniedWhenCalledByUserWithRole']
.forEach(function(func) {
it('should have a method named ' + func, function () {
assert.equal(typeof helpers.it[func], 'function');
Expand All @@ -30,8 +32,11 @@ describe('helpers', function () {
describe('helpers.describe', function() {
['staticMethod',
'instanceMethod',
'whenCalledRemotely',
'whenLoggedInAsUser',
'whenLoggedInAsUserWithRole',
'whenCalledByUser',
'whenCalledByUserWithRole',
'whenCalledAnonymously',
'whenCalledUnauthenticated']
.forEach(function(func) {
Expand All @@ -42,10 +47,18 @@ describe('helpers', function () {
});

describe('helpers.beforeEach', function() {
['withArgs',
['withApp',
'cleanDatasource',
'withArgs',
'givenModel',
'withUserModel',
'withAccessTokenModel',
'withRoleModel',
'withRoleMappingModel',
'givenUser',
'givenUserWithRole',
'givenLoggedInUser',
'givenLoggedInUserWithRole',
'givenAnUnauthenticatedToken',
'givenAnAnonymousToken']
.forEach(function(func) {
Expand Down