From 57a5444335f804cb0d0131883921b15c9118f339 Mon Sep 17 00:00:00 2001 From: Hannah Wolfe Date: Wed, 30 Jul 2014 15:02:25 +0100 Subject: [PATCH] User API ability to filter users by role refs #3446 - This only covers the API changes needed for #3446 --- core/server/models/user.js | 41 ++++++++++++--- .../integration/model/model_users_spec.js | 52 +++++++++++++++++-- 2 files changed, 81 insertions(+), 12 deletions(-) diff --git a/core/server/models/user.js b/core/server/models/user.js index 7d94523c27..06d15910ce 100644 --- a/core/server/models/user.js +++ b/core/server/models/user.js @@ -167,7 +167,7 @@ User = ghostBookshelf.Model.extend({ options = options || {}; var userCollection = Users.forge(), - userQuery; + roleInstance = options.role !== undefined ? Role.forge({name: options.role}) : false; if (options.limit && options.limit !== 'all') { options.limit = parseInt(options.limit) || 15; @@ -213,14 +213,28 @@ User = ghostBookshelf.Model.extend({ .query('offset', options.limit * (options.page - 1)); } - userQuery = userCollection - .query('orderBy', 'last_login', 'DESC') - .query('orderBy', 'name', 'ASC') - .query('orderBy', 'created_at', 'DESC') - .fetch(_.omit(options, 'page', 'limit')); + function fetchRoleQuery() { + if (roleInstance) { + return roleInstance.fetch(); + } + return false; + } + return when(fetchRoleQuery()) + .then(function () { - return when(userQuery) + if (roleInstance) { + userCollection + .query('join', 'roles_users', 'roles_users.user_id', '=', 'users.id') + .query('where', 'roles_users.role_id', '=', roleInstance.id); + } + + return userCollection + .query('orderBy', 'last_login', 'DESC') + .query('orderBy', 'name', 'ASC') + .query('orderBy', 'created_at', 'DESC') + .fetch(_.omit(options, 'page', 'limit')); + }) // Fetch pagination information .then(function () { @@ -236,6 +250,11 @@ User = ghostBookshelf.Model.extend({ qb.where(options.where); } + if (roleInstance) { + qb.join('roles_users', 'roles_users.user_id', '=', 'users.id'); + qb.where('roles_users.role_id', '=', roleInstance.id); + } + return qb.count(tableName + '.' + idAttribute + ' as aggregate'); }) @@ -276,6 +295,14 @@ User = ghostBookshelf.Model.extend({ } } + if (roleInstance) { + meta.filters = {}; + if (!roleInstance.isNew()) { + meta.filters.roles = [roleInstance.toJSON()]; + } + } + + return data; }) .catch(errors.logAndThrowError); diff --git a/core/test/integration/model/model_users_spec.js b/core/test/integration/model/model_users_spec.js index 6ae7fc51b8..3ca080a808 100644 --- a/core/test/integration/model/model_users_spec.js +++ b/core/test/integration/model/model_users_spec.js @@ -127,7 +127,7 @@ describe('User Model', function run() { }); describe('Basic Operations', function () { - beforeEach(testUtils.setup('owner', 'role')); + beforeEach(testUtils.setup('users:roles')); it('sets last login time on successful login', function (done) { var userData = testUtils.DataGenerator.forModel.users[0]; @@ -163,17 +163,59 @@ describe('User Model', function run() { }); it('can findAll', function (done) { - UserModel.findAll().then(function (results) { should.exist(results); - - results.length.should.be.above(0); + results.length.should.equal(4); done(); }).catch(done); }); + it('can findPage (default)', function (done) { + UserModel.findPage().then(function (results) { + should.exist(results); + + results.meta.pagination.page.should.equal(1); + results.meta.pagination.limit.should.equal(15); + results.meta.pagination.pages.should.equal(1); + results.users.length.should.equal(4); + + done(); + }).catch(done); + }); + + it('can findPage by role', function (done) { + return testUtils.fixtures.createExtraUsers().then(function () { + return UserModel.findPage({role: 'Administrator'}); + }).then(function (results) { + results.meta.pagination.page.should.equal(1); + results.meta.pagination.limit.should.equal(15); + results.meta.pagination.pages.should.equal(1); + results.meta.pagination.total.should.equal(2); + results.users.length.should.equal(2); + + return UserModel.findPage({role: 'Owner'}); + }).then(function (results) { + results.meta.pagination.page.should.equal(1); + results.meta.pagination.limit.should.equal(15); + results.meta.pagination.pages.should.equal(1); + results.meta.pagination.total.should.equal(1); + results.users.length.should.equal(1); + + return UserModel.findPage({role: 'Editor', limit: 1}); + }).then(function (results) { + results.meta.pagination.page.should.equal(1); + results.meta.pagination.limit.should.equal(1); + results.meta.pagination.pages.should.equal(2); + results.meta.pagination.total.should.equal(2); + results.users.length.should.equal(1); + + done(); + }).catch(done); + }); + + it('can findOne', function (done) { var firstUser; @@ -214,7 +256,7 @@ describe('User Model', function run() { }); it('can add', function (done) { - var userData = testUtils.DataGenerator.forModel.users[2]; + var userData = testUtils.DataGenerator.forModel.users[4]; sandbox.stub(UserModel, 'gravatarLookup', function (userData) { return when.resolve(userData);