Merge pull request #3443 from halfdan/30850-users-api

Users API advanced browsing
This commit is contained in:
Hannah Wolfe 2014-07-30 22:47:55 +01:00
commit 5dc457b417
4 changed files with 84 additions and 36 deletions

View File

@ -174,7 +174,8 @@ User = ghostBookshelf.Model.extend({
page: 1, // pagination page
limit: 15,
status: 'active',
where: {}
where: {},
whereIn: {}
}, options);
//TODO: there are multiple statuses that make a user "active" or "invited" - we a way to translate/map them:
@ -186,8 +187,15 @@ User = ghostBookshelf.Model.extend({
// make sure that status is valid
//TODO: need a better way of getting a list of statuses other than hard-coding them...
options.status = _.indexOf(
['active', 'warn-1', 'warn-2', 'warn-3', 'locked', 'invited'],
['active', 'warn-1', 'warn-2', 'warn-3', 'warn-4', 'locked', 'invited', 'inactive'],
options.status) !== -1 ? options.status : 'active';
}
if (options.status === 'active') {
userCollection.query().whereIn('status', ['active', 'warn-1', 'warn-2', 'warn-3', 'warn-4', 'locked']);
} else if (options.status === 'invited') {
userCollection.query().whereIn('status', ['invited', 'invited-pending']);
} else if (options.status !== 'all') {
options.where.status = options.status;
}

View File

@ -38,41 +38,69 @@ describe('Users API', function () {
});
describe('Browse', function () {
function checkBrowseResponse(response) {
should.exist(response);
testUtils.API.checkResponse(response, 'users');
should.exist(response.users);
response.users.should.have.length(7);
testUtils.API.checkResponse(response.users[0], 'user', ['roles']);
testUtils.API.checkResponse(response.users[1], 'user', ['roles']);
testUtils.API.checkResponse(response.users[2], 'user', ['roles']);
testUtils.API.checkResponse(response.users[3], 'user', ['roles']);
}
function checkBrowseResponse(response, count) {
should.exist(response);
testUtils.API.checkResponse(response, 'users');
should.exist(response.users);
response.users.should.have.length(count);
testUtils.API.checkResponse(response.users[0], 'user', ['roles']);
testUtils.API.checkResponse(response.users[1], 'user', ['roles']);
testUtils.API.checkResponse(response.users[2], 'user', ['roles']);
testUtils.API.checkResponse(response.users[3], 'user', ['roles']);
}
it('Owner can browse', function (done) {
UserAPI.browse(context.owner).then(function (response) {
checkBrowseResponse(response);
done();
}).catch(done);
});
it('Owner can browse', function (done) {
UserAPI.browse(context.owner).then(function (response) {
checkBrowseResponse(response, 5);
done();
}).catch(done);
});
it('Admin can browse', function (done) {
UserAPI.browse(context.admin).then(function (response) {
checkBrowseResponse(response);
done();
}).catch(done);
});
it('Admin can browse', function (done) {
UserAPI.browse(context.admin).then(function (response) {
checkBrowseResponse(response, 5);
done();
}).catch(done);
});
it('Editor can browse', function (done) {
UserAPI.browse(context.editor).then(function (response) {
checkBrowseResponse(response, 5);
done();
}).catch(done);
});
it('Author can browse active', function (done) {
UserAPI.browse(context.author).then(function (response) {
checkBrowseResponse(response, 5);
done();
}).catch(done);
});
it('No-auth CANNOT browse', function (done) {
UserAPI.browse().then(function () {
done(new Error('Browse users is not denied without authentication.'));
}, function () {
done();
}).catch(done);
});
it('Can browse invited/invited-pending (admin)', function (done) {
UserAPI.browse(_.extend(testUtils.context.admin, { status: 'invited' })).then(function (response) {
should.exist(response);
testUtils.API.checkResponse(response, 'users');
should.exist(response.users);
response.users.should.have.length(1);
testUtils.API.checkResponse(response.users[0], 'user', ['roles']);
response.users[0].status.should.equal('invited-pending');
it('Editor can browse', function (done) {
UserAPI.browse(context.editor).then(function (response) {
checkBrowseResponse(response);
done();
}).catch(done);
});
it('Author can browse', function (done) {
UserAPI.browse(context.author).then(function (response) {
checkBrowseResponse(response);
checkBrowseResponse(response, 5);
done();
}).catch(done);
});
@ -84,6 +112,13 @@ describe('Users API', function () {
done();
}).catch(done);
});
it('Can browse all', function (done) {
UserAPI.browse(_.extend(testUtils.context.admin, { status: 'all'})).then(function (response) {
checkBrowseResponse(response, 7);
done();
}).catch(done);
});
});
describe('Read', function () {
@ -450,6 +485,7 @@ describe('Users API', function () {
});
});
});
describe('Destroy', function () {
function checkDestroyResponse(response) {
@ -478,7 +514,6 @@ describe('Users API', function () {
UserAPI.destroy(_.extend({}, context.owner, {id: userIdFor.admin}))
.then(function (response) {
checkDestroyResponse(response);
// Editor
return UserAPI.destroy(_.extend({}, context.owner, {id: userIdFor.editor}));
}).then(function (response) {

View File

@ -179,7 +179,7 @@ describe('User Model', function run() {
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);
results.users.length.should.equal(3);
done();
}).catch(done);
@ -193,7 +193,7 @@ describe('User Model', function run() {
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);
results.users.length.should.equal(1);
return UserModel.findPage({role: 'Owner'});
}).then(function (results) {

View File

@ -75,31 +75,36 @@ DataGenerator.Content = {
name: 'Joe Bloggs',
slug: 'joe-blogs',
email: 'jbloggs@example.com',
password: '$2a$10$.pZeeBE0gHXd0PTnbT/ph.GEKgd0Wd3q2pWna3ynTGBkPKnGIKZL6'
password: '$2a$10$.pZeeBE0gHXd0PTnbT/ph.GEKgd0Wd3q2pWna3ynTGBkPKnGIKZL6',
status: 'active'
},
{
name: 'Smith Wellingsworth',
slug: 'smith-wellingsworth',
email: 'swellingsworth@example.com',
password: '$2a$10$.pZeeBE0gHXd0PTnbT/ph.GEKgd0Wd3q2pWna3ynTGBkPKnGIKZL6'
password: '$2a$10$.pZeeBE0gHXd0PTnbT/ph.GEKgd0Wd3q2pWna3ynTGBkPKnGIKZL6',
status: 'invited-pending'
},
{
name: 'Jimothy Bogendath',
slug: 'jimothy-bogendath',
email: 'jbOgendAth@example.com',
password: '$2a$10$.pZeeBE0gHXd0PTnbT/ph.GEKgd0Wd3q2pWna3ynTGBkPKnGIKZL6'
password: '$2a$10$.pZeeBE0gHXd0PTnbT/ph.GEKgd0Wd3q2pWna3ynTGBkPKnGIKZL6',
status: 'warn-1'
},
{
name: 'Slimer McEctoplasm',
slug: 'slimer-mcectoplasm',
email: 'smcectoplasm@example.com',
password: '$2a$10$.pZeeBE0gHXd0PTnbT/ph.GEKgd0Wd3q2pWna3ynTGBkPKnGIKZL6'
password: '$2a$10$.pZeeBE0gHXd0PTnbT/ph.GEKgd0Wd3q2pWna3ynTGBkPKnGIKZL6',
status: 'warn-2'
},
{
name: 'Ivan Email',
slug: 'ivan-email',
email: 'info@ghost.org',
password: '$2a$10$.pZeeBE0gHXd0PTnbT/ph.GEKgd0Wd3q2pWna3ynTGBkPKnGIKZL6'
password: '$2a$10$.pZeeBE0gHXd0PTnbT/ph.GEKgd0Wd3q2pWna3ynTGBkPKnGIKZL6',
status: 'inactive'
}
],