mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-18 15:17:25 +01:00
Delete private guilds or parties when last member leaves.
This commit is contained in:
@@ -11,7 +11,7 @@ describe "Guilds", ->
|
|||||||
registerNewUser ->
|
registerNewUser ->
|
||||||
User.findByIdAndUpdate user._id,
|
User.findByIdAndUpdate user._id,
|
||||||
$set:
|
$set:
|
||||||
"balance": 10
|
"balance": 40
|
||||||
, (err, _user) ->
|
, (err, _user) ->
|
||||||
done()
|
done()
|
||||||
, true
|
, true
|
||||||
@@ -150,6 +150,28 @@ describe "Guilds", ->
|
|||||||
expectCode res, 204
|
expectCode res, 204
|
||||||
done()
|
done()
|
||||||
|
|
||||||
|
it "deletes a group when the last member leaves", (done) ->
|
||||||
|
groupToDeleteAfterLeave = undefined
|
||||||
|
request.post(baseURL + "/groups").send(
|
||||||
|
name: "TestGroupToDeleteAfteLeave"
|
||||||
|
type: "guild"
|
||||||
|
privacy: "private"
|
||||||
|
).end (res) ->
|
||||||
|
groupToDeleteAfterLeave = res.body
|
||||||
|
async.waterfall [
|
||||||
|
(cb) ->
|
||||||
|
request.post(baseURL + "/groups/" + groupToDeleteAfterLeave._id + "/leave")
|
||||||
|
.end (res) ->
|
||||||
|
expectCode res, 204
|
||||||
|
cb()
|
||||||
|
|
||||||
|
(cb) ->
|
||||||
|
request.post(baseURL + "/groups/" + groupToDeleteAfterLeave._id)
|
||||||
|
.end (res) ->
|
||||||
|
expectCode res, 404
|
||||||
|
cb()
|
||||||
|
], done
|
||||||
|
|
||||||
context "removing users groups", ->
|
context "removing users groups", ->
|
||||||
it "allows guild leaders to remove a member (but not themselves)", (done) ->
|
it "allows guild leaders to remove a member (but not themselves)", (done) ->
|
||||||
guildToRemoveMember = undefined
|
guildToRemoveMember = undefined
|
||||||
|
|||||||
@@ -511,8 +511,77 @@ api.leave = function(req, res, next) {
|
|||||||
|
|
||||||
// When removing the user from challenges, should we keep the tasks?
|
// When removing the user from challenges, should we keep the tasks?
|
||||||
var keep = (/^remove-all/i).test(req.query.keep) ? 'remove-all' : 'keep-all';
|
var keep = (/^remove-all/i).test(req.query.keep) ? 'remove-all' : 'keep-all';
|
||||||
|
async.parallel([
|
||||||
group.leave(user, keep, function(err){
|
// Remove active quest from user if they're leaving the party
|
||||||
|
function(cb){
|
||||||
|
if (group.type != 'party') return cb(null,{},1);
|
||||||
|
user.party.quest = Group.cleanQuestProgress();
|
||||||
|
user.save(cb);
|
||||||
|
},
|
||||||
|
// Remove user from group challenges
|
||||||
|
function(cb){
|
||||||
|
async.waterfall([
|
||||||
|
// Find relevant challenges
|
||||||
|
function(cb2) {
|
||||||
|
Challenge.find({
|
||||||
|
_id: {$in: user.challenges}, // Challenges I am in
|
||||||
|
group: group._id // that belong to the group I am leaving
|
||||||
|
}, cb2);
|
||||||
|
},
|
||||||
|
// Update each challenge
|
||||||
|
function(challenges, cb2) {
|
||||||
|
Challenge.update(
|
||||||
|
{_id:{$in: _.pluck(challenges, '_id')}},
|
||||||
|
{$pull:{members:user._id}},
|
||||||
|
{multi: true},
|
||||||
|
function(err) {
|
||||||
|
cb2(err, challenges); // pass `challenges` above to cb
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
// Unlink the challenge tasks from user
|
||||||
|
function(challenges, cb2) {
|
||||||
|
async.waterfall(challenges.map(function(chal) {
|
||||||
|
return function(cb3) {
|
||||||
|
var i = user.challenges.indexOf(chal._id)
|
||||||
|
if (~i) user.challenges.splice(i,1);
|
||||||
|
user.unlink({cid:chal._id, keep:keep}, cb3);
|
||||||
|
}
|
||||||
|
}), cb2);
|
||||||
|
}
|
||||||
|
], cb);
|
||||||
|
},
|
||||||
|
// Update the group
|
||||||
|
function(cb){
|
||||||
|
var update = {$pull:{members:user._id}};
|
||||||
|
if (group.type == 'party' && group.quest.key){
|
||||||
|
update['$unset'] = {};
|
||||||
|
update['$unset']['quest.members.' + user._id] = 1;
|
||||||
|
}
|
||||||
|
// FIXME do we want to remove the group `if group.members.length == 0` ? (well, 1 since the update hasn't gone through yet)
|
||||||
|
if (group.members.length > 1) {
|
||||||
|
var seniorMember = _.find(group.members, function (m) {return m != user._id});
|
||||||
|
// If the leader is leaving (or if the leader previously left, and this wasn't accounted for)
|
||||||
|
var leader = group.leader;
|
||||||
|
if (leader == user._id || !~group.members.indexOf(leader)) {
|
||||||
|
update['$set'] = update['$set'] || {};
|
||||||
|
update['$set'].leader = seniorMember;
|
||||||
|
}
|
||||||
|
leader = group.quest && group.quest.leader;
|
||||||
|
if (leader && (leader == user._id || !~group.members.indexOf(leader))) {
|
||||||
|
update['$set'] = update['$set'] || {};
|
||||||
|
update['$set']['quest.leader'] = seniorMember;
|
||||||
|
}
|
||||||
|
update['$inc'] = {memberCount: -1};
|
||||||
|
Group.update({_id:group._id}, update, cb);
|
||||||
|
} else if (group.members.length === 1) {
|
||||||
|
//We don't delete public groups when they are empty
|
||||||
|
if (group.privacy === 'private' || group.type === 'party') {
|
||||||
|
Group.remove({_id:group._id}, cb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],function(err){
|
||||||
if (err) return next(err);
|
if (err) return next(err);
|
||||||
user = group = keep = null;
|
user = group = keep = null;
|
||||||
return res.send(204);
|
return res.send(204);
|
||||||
|
|||||||
Reference in New Issue
Block a user