mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-01 19:46:01 +01:00
closes #5463 , invitation tests
This commit is contained in:
@@ -272,35 +272,34 @@ SocketUser.invite = function (socket, email, callback) {
|
|||||||
return callback(new Error('[[error:forum-not-invite-only]]'));
|
return callback(new Error('[[error:forum-not-invite-only]]'));
|
||||||
}
|
}
|
||||||
|
|
||||||
var max = meta.config.maximumInvites;
|
async.waterfall([
|
||||||
|
function (next) {
|
||||||
|
user.isAdministrator(socket.uid, next);
|
||||||
|
},
|
||||||
|
function (isAdmin, next) {
|
||||||
|
if (registrationType === 'admin-invite-only' && !isAdmin) {
|
||||||
|
return next(new Error('[[error:no-privileges]]'));
|
||||||
|
}
|
||||||
|
|
||||||
|
var max = parseInt(meta.config.maximumInvites, 10);
|
||||||
|
if (!max) {
|
||||||
|
return user.sendInvitationEmail(socket.uid, email, callback);
|
||||||
|
}
|
||||||
|
|
||||||
user.isAdministrator(socket.uid, function (err, admin) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
if (registrationType === 'admin-invite-only' && !admin) {
|
|
||||||
return callback(new Error('[[error:no-privileges]]'));
|
|
||||||
}
|
|
||||||
if (max) {
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function (next) {
|
function (next) {
|
||||||
user.getInvitesNumber(socket.uid, next);
|
user.getInvitesNumber(socket.uid, next);
|
||||||
},
|
},
|
||||||
function (invites, next) {
|
function (invites, next) {
|
||||||
if (!admin && invites > max) {
|
if (!isAdmin && invites >= max) {
|
||||||
return next(new Error('[[error:invite-maximum-met, ' + invites + ', ' + max + ']]'));
|
return next(new Error('[[error:invite-maximum-met, ' + invites + ', ' + max + ']]'));
|
||||||
}
|
}
|
||||||
next();
|
|
||||||
},
|
|
||||||
function (next) {
|
|
||||||
user.sendInvitationEmail(socket.uid, email, next);
|
user.sendInvitationEmail(socket.uid, email, next);
|
||||||
}
|
}
|
||||||
], callback);
|
], next);
|
||||||
} else {
|
|
||||||
user.sendInvitationEmail(socket.uid, email, callback);
|
|
||||||
}
|
}
|
||||||
});
|
], callback);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SocketUser.getUserByUID = function (socket, uid, callback) {
|
SocketUser.getUserByUID = function (socket, uid, callback) {
|
||||||
|
|||||||
@@ -61,9 +61,7 @@ module.exports = function (User) {
|
|||||||
if (exists) {
|
if (exists) {
|
||||||
return next(new Error('[[error:email-taken]]'));
|
return next(new Error('[[error:email-taken]]'));
|
||||||
}
|
}
|
||||||
next();
|
|
||||||
},
|
|
||||||
function (next) {
|
|
||||||
async.parallel([
|
async.parallel([
|
||||||
function (next) {
|
function (next) {
|
||||||
db.setAdd('invitation:uid:' + uid, email, next);
|
db.setAdd('invitation:uid:' + uid, email, next);
|
||||||
@@ -131,11 +129,11 @@ module.exports = function (User) {
|
|||||||
return next(new Error('[[error:invalid-username]]'));
|
return next(new Error('[[error:invalid-username]]'));
|
||||||
}
|
}
|
||||||
async.parallel([
|
async.parallel([
|
||||||
function deleteFromReferenceList(next) {
|
function (next) {
|
||||||
db.setRemove('invitation:uid:' + invitedByUid, email, next);
|
deleteFromReferenceList(invitedByUid, email, next);
|
||||||
},
|
},
|
||||||
function deleteInviteKey(next) {
|
function (next) {
|
||||||
db.delete('invitation:email:' + email, callback);
|
db.delete('invitation:email:' + email, next);
|
||||||
}
|
}
|
||||||
], function (err) {
|
], function (err) {
|
||||||
next(err);
|
next(err);
|
||||||
@@ -146,7 +144,37 @@ module.exports = function (User) {
|
|||||||
|
|
||||||
User.deleteInvitationKey = function (email, callback) {
|
User.deleteInvitationKey = function (email, callback) {
|
||||||
callback = callback || function () {};
|
callback = callback || function () {};
|
||||||
db.delete('invitation:email:' + email, callback);
|
|
||||||
|
async.waterfall([
|
||||||
|
function (next) {
|
||||||
|
User.getInvitingUsers(next);
|
||||||
|
},
|
||||||
|
function (uids, next) {
|
||||||
|
async.each(uids, function (uid, next) {
|
||||||
|
deleteFromReferenceList(uid, email, next);
|
||||||
|
}, next);
|
||||||
|
},
|
||||||
|
function (next) {
|
||||||
|
db.delete('invitation:email:' + email, next);
|
||||||
|
}
|
||||||
|
], callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function deleteFromReferenceList(uid, email, callback) {
|
||||||
|
async.waterfall([
|
||||||
|
function (next) {
|
||||||
|
db.setRemove('invitation:uid:' + uid, email, next);
|
||||||
|
},
|
||||||
|
function (next) {
|
||||||
|
db.setCount('invitation:uid:' + uid, next);
|
||||||
|
},
|
||||||
|
function (count, next) {
|
||||||
|
if (count === 0) {
|
||||||
|
return db.setRemove('invitation:uids', uid, next);
|
||||||
|
}
|
||||||
|
setImmediate(next);
|
||||||
|
}
|
||||||
|
], callback);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
154
test/user.js
154
test/user.js
@@ -513,8 +513,7 @@ describe('User', function () {
|
|||||||
it('should upload profile picture', function (done) {
|
it('should upload profile picture', function (done) {
|
||||||
helpers.copyFile(
|
helpers.copyFile(
|
||||||
path.join(nconf.get('base_dir'), 'test/files/test.png'),
|
path.join(nconf.get('base_dir'), 'test/files/test.png'),
|
||||||
path.join(nconf.get('base_dir'), 'test/files/test_copy.png')
|
path.join(nconf.get('base_dir'), 'test/files/test_copy.png'), function (err) {
|
||||||
, function (err) {
|
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
var picture = {
|
var picture = {
|
||||||
path: path.join(nconf.get('base_dir'), 'test/files/test_copy.png'),
|
path: path.join(nconf.get('base_dir'), 'test/files/test_copy.png'),
|
||||||
@@ -572,7 +571,7 @@ describe('User', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return error if no plugins listening for filter:uploadImage when uploading from url', function (done) {
|
it('should return error if no plugins listening for filter:uploadImage when uploading from url', function (done) {
|
||||||
var url = nconf.get('url') + '/logo.png';
|
var url = nconf.get('url') + '/assets/logo.png';
|
||||||
User.uploadFromUrl(uid, url, function (err) {
|
User.uploadFromUrl(uid, url, function (err) {
|
||||||
assert.equal(err.message, '[[error:no-plugin]]');
|
assert.equal(err.message, '[[error:no-plugin]]');
|
||||||
done();
|
done();
|
||||||
@@ -595,7 +594,7 @@ describe('User', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return error if the file is too big when uploading from url', function (done) {
|
it('should return error if the file is too big when uploading from url', function (done) {
|
||||||
var url = nconf.get('url') + '/logo.png';
|
var url = nconf.get('url') + '/assets/logo.png';
|
||||||
meta.config.maximumProfileImageSize = 1;
|
meta.config.maximumProfileImageSize = 1;
|
||||||
|
|
||||||
function filterMethod(data, callback) {
|
function filterMethod(data, callback) {
|
||||||
@@ -613,7 +612,7 @@ describe('User', function () {
|
|||||||
it('should error with invalid data', function (done) {
|
it('should error with invalid data', function (done) {
|
||||||
var socketUser = require('../src/socket.io/user');
|
var socketUser = require('../src/socket.io/user');
|
||||||
|
|
||||||
socketUser.uploadProfileImageFromUrl({uid: uid}, {uid: uid, url: ''}, function (err, uploadedPicture) {
|
socketUser.uploadProfileImageFromUrl({uid: uid}, {uid: uid, url: ''}, function (err) {
|
||||||
assert.equal(err.message, '[[error:invalid-data]]');
|
assert.equal(err.message, '[[error:invalid-data]]');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -621,7 +620,7 @@ describe('User', function () {
|
|||||||
|
|
||||||
it('should upload picture when uploading from url', function (done) {
|
it('should upload picture when uploading from url', function (done) {
|
||||||
var socketUser = require('../src/socket.io/user');
|
var socketUser = require('../src/socket.io/user');
|
||||||
var url = nconf.get('url') + '/logo.png';
|
var url = nconf.get('url') + '/assets/logo.png';
|
||||||
meta.config.maximumProfileImageSize = '';
|
meta.config.maximumProfileImageSize = '';
|
||||||
|
|
||||||
function filterMethod(data, callback) {
|
function filterMethod(data, callback) {
|
||||||
@@ -1006,6 +1005,149 @@ describe('User', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('invites', function () {
|
||||||
|
var socketUser = require('../src/socket.io/user');
|
||||||
|
var inviterUid;
|
||||||
|
|
||||||
|
before(function (done) {
|
||||||
|
User.create({
|
||||||
|
username: 'inviter',
|
||||||
|
email: 'inviter@nodebb.org'
|
||||||
|
}, function (err, uid) {
|
||||||
|
assert.ifError(err);
|
||||||
|
inviterUid = uid;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should error with invalid data', function (done) {
|
||||||
|
socketUser.invite({uid: inviterUid}, null, function (err) {
|
||||||
|
assert.equal(err.message, '[[error:invalid-data]]');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should eror if forum is not invite only', function (done) {
|
||||||
|
socketUser.invite({uid: inviterUid}, 'invite1@test.com', function (err) {
|
||||||
|
assert.equal(err.message, '[[error:forum-not-invite-only]]');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should error if user is not admin and type is admin-invite-only', function (done) {
|
||||||
|
meta.config.registrationType = 'admin-invite-only';
|
||||||
|
socketUser.invite({uid: inviterUid}, 'invite1@test.com', function (err) {
|
||||||
|
assert.equal(err.message, '[[error:no-privileges]]');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should send invitation email', function (done) {
|
||||||
|
meta.config.registrationType = 'invite-only';
|
||||||
|
socketUser.invite({uid: inviterUid}, 'invite1@test.com', function (err) {
|
||||||
|
assert.ifError(err);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should error if ouf of invitations', function (done) {
|
||||||
|
meta.config.maximumInvites = 1;
|
||||||
|
socketUser.invite({uid: inviterUid}, 'invite2@test.com', function (err) {
|
||||||
|
assert.equal(err.message, '[[error:invite-maximum-met, ' + 1 + ', ' + 1 + ']]');
|
||||||
|
meta.config.maximumInvites = 5;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should error if email exists', function (done) {
|
||||||
|
socketUser.invite({uid: inviterUid}, 'inviter@nodebb.org', function (err) {
|
||||||
|
assert.equal(err.message, '[[error:email-taken]]');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should send invitation email', function (done) {
|
||||||
|
socketUser.invite({uid: inviterUid}, 'invite2@test.com', function (err) {
|
||||||
|
assert.ifError(err);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get user\'s invites', function (done) {
|
||||||
|
User.getInvites(inviterUid, function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.deepEqual(data, ['invite1@test.com', 'invite2@test.com']);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get all invites', function (done) {
|
||||||
|
User.getAllInvites(function (err, data) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.deepEqual(data, [ { uid: inviterUid, invitations: [ 'invite1@test.com', 'invite2@test.com' ] } ]);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail to verify invitation with invalid data', function (done) {
|
||||||
|
User.verifyInvitation({token: '', email: ''}, function (err) {
|
||||||
|
assert.equal(err.message, '[[error:invalid-data]]');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail to verify invitation with invalid email', function (done) {
|
||||||
|
User.verifyInvitation({token: 'test', email: 'doesnotexist@test.com'}, function (err) {
|
||||||
|
assert.equal(err.message, '[[error:invalid-token]]');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should verify installation with no errors', function (done) {
|
||||||
|
db.get('invitation:email:' + 'invite1@test.com', function (err, token) {
|
||||||
|
assert.ifError(err);
|
||||||
|
User.verifyInvitation({token: token, email: 'invite1@test.com'}, function (err) {
|
||||||
|
assert.ifError(err);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should error with invalid username', function (done) {
|
||||||
|
User.deleteInvitation('doesnotexist', 'test@test.com', function (err) {
|
||||||
|
assert.equal(err.message, '[[error:invalid-username]]');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should delete invitation', function (done) {
|
||||||
|
var socketAdmin = require('../src/socket.io/admin');
|
||||||
|
socketAdmin.user.deleteInvitation({uid: inviterUid}, {invitedBy: 'inviter', email: 'invite1@test.com'}, function (err) {
|
||||||
|
assert.ifError(err);
|
||||||
|
db.isSetMember('invitation:uid:' + inviterUid, 'invite1@test.com', function (err, isMember) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.equal(isMember, false);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should delete invitation key', function (done) {
|
||||||
|
User.deleteInvitationKey('invite2@test.com', function (err) {
|
||||||
|
assert.ifError(err);
|
||||||
|
db.isSetMember('invitation:uid:' + inviterUid, 'invite2@test.com', function (err, isMember) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.equal(isMember, false);
|
||||||
|
db.isSetMember('invitation:uids', inviterUid, function (err, isMember) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.equal(isMember, false);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user