check for membership when leaving public guild, fix memberCount update when leaving group, add missing files

This commit is contained in:
Matteo Pagliazzi
2016-02-28 01:11:45 +01:00
parent 733da70b48
commit 5e68589ac8
6 changed files with 62 additions and 14 deletions

View File

@@ -3,6 +3,8 @@ import {
checkExistence, checkExistence,
createAndPopulateGroup, createAndPopulateGroup,
sleep, sleep,
generateUser,
translate as t,
} from '../../../../helpers/api-v3-integration.helper'; } from '../../../../helpers/api-v3-integration.helper';
import { import {
each, each,
@@ -20,6 +22,7 @@ describe('POST /groups/:groupId/leave', () => {
let groupToLeave; let groupToLeave;
let leader; let leader;
let member; let member;
let memberCount;
beforeEach(async () => { beforeEach(async () => {
let { group, groupLeader, members } = await createAndPopulateGroup({ let { group, groupLeader, members } = await createAndPopulateGroup({
@@ -30,6 +33,16 @@ describe('POST /groups/:groupId/leave', () => {
groupToLeave = group; groupToLeave = group;
leader = groupLeader; leader = groupLeader;
member = members[0]; member = members[0];
memberCount = group.memberCount;
});
it('prevents non members from leaving', async () => {
let user = await generateUser();
await expect(user.post(`/groups/${groupToLeave._id}/leave`)).to.eventually.be.rejected.and.eql({
code: 404,
error: 'NotFound',
message: t('groupNotFound'),
});
}); });
it(`lets user leave a ${groupType}`, async () => { it(`lets user leave a ${groupType}`, async () => {
@@ -39,14 +52,16 @@ describe('POST /groups/:groupId/leave', () => {
expect(userThatLeftGroup.guilds).to.be.empty; expect(userThatLeftGroup.guilds).to.be.empty;
expect(userThatLeftGroup.party._id).to.not.exist; expect(userThatLeftGroup.party._id).to.not.exist;
await groupToLeave.sync();
expect(groupToLeave.memberCount).to.equal(memberCount - 1);
}); });
it(`sets a new group leader when leader leaves a ${groupType}`, async () => { it(`sets a new group leader when leader leaves a ${groupType}`, async () => {
await leader.post(`/groups/${groupToLeave._id}/leave`); await leader.post(`/groups/${groupToLeave._id}/leave`);
let groupToLeaveWithNewLeader = await member.get(`/groups/${groupToLeave._id}`); await groupToLeave.sync();
expect(groupToLeave.memberCount).to.equal(memberCount - 1);
expect(groupToLeaveWithNewLeader.leader._id).to.equal(member._id); expect(groupToLeave.leader).to.equal(member._id);
}); });
context('With challenges', () => { context('With challenges', () => {

View File

@@ -0,0 +1,3 @@
describe('GET /user/auth/logout', () => {
// TODO Test manually
});

View File

@@ -0,0 +1,18 @@
import {
generateUser,
} from '../../../../../helpers/api-integration/v3';
import moment from 'moment';
describe('POST /user/auth/firebase', () => {
let user;
before(async () => {
user = await generateUser();
});
it('returns a Firebase token', async () => {
let {token, expires} = await user.post('/user/auth/firebase');
expect(moment(expires).isValid()).to.be.true;
expect(token).to.be.a('string');
});
});

View File

@@ -83,7 +83,7 @@ export async function createAndPopulateGroup (settings = {}) {
}) })
); );
group.update({ memberCount: numberOfMembers + 1}); await group.update({ memberCount: numberOfMembers + 1});
let invitees = await Q.all( let invitees = await Q.all(
times(numberOfInvites, () => { times(numberOfInvites, () => {

View File

@@ -332,7 +332,7 @@ api.leaveGroup = {
let validationErrors = req.validationErrors(); let validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors; if (validationErrors) throw validationErrors;
let group = await Group.getGroup({user, groupId: req.params.groupId, fields: '-chat'}); // Do not fetch chat let group = await Group.getGroup({user, groupId: req.params.groupId, fields: '-chat', requireMembership: true});
if (!group) throw new NotFound(res.t('groupNotFound')); if (!group) throw new NotFound(res.t('groupNotFound'));
// During quests, checke wheter user can leave // During quests, checke wheter user can leave
@@ -590,7 +590,7 @@ api.inviteToGroup = {
let validationErrors = req.validationErrors(); let validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors; if (validationErrors) throw validationErrors;
let group = await Group.getGroup({user, groupId: req.params.groupId, fields: '-chat'}); // Do not fetch chat TODO other fields too? let group = await Group.getGroup({user, groupId: req.params.groupId, fields: '-chat'});
if (!group) throw new NotFound(res.t('groupNotFound')); if (!group) throw new NotFound(res.t('groupNotFound'));
let uuids = req.body.uuids; let uuids = req.body.uuids;

View File

@@ -121,16 +121,24 @@ schema.post('remove', function postRemoveGroup (group) {
firebase.deleteGroup(group._id); firebase.deleteGroup(group._id);
}); });
schema.statics.getGroup = function getGroup (options = {}) { schema.statics.getGroup = async function getGroup (options = {}) {
let {user, groupId, fields, optionalMembership = false, populateLeader = false} = options; let {user, groupId, fields, optionalMembership = false, populateLeader = false, requireMembership = false} = options;
let query; let query;
let isParty = groupId === 'party' || user.party._id === groupId;
let isGuild = user.guilds.indexOf(groupId) !== -1;
// When requireMembership is true check that user is member even in public guild
if (requireMembership && !isParty && !isGuild) {
return null;
}
// When optionalMembership is true it's not required for the user to be a member of the group // When optionalMembership is true it's not required for the user to be a member of the group
if (groupId === 'party' || user.party._id === groupId) { if (isParty) {
query = {type: 'party', _id: user.party._id}; query = {type: 'party', _id: user.party._id};
} else if (optionalMembership === true) { } else if (optionalMembership === true) {
query = {_id: groupId}; query = {_id: groupId};
} else if (user.guilds.indexOf(groupId) !== -1) { } else if (isGuild) {
query = {type: 'guild', _id: groupId}; query = {type: 'guild', _id: groupId};
} else { } else {
query = {type: 'guild', privacy: 'public', _id: groupId}; query = {type: 'guild', privacy: 'public', _id: groupId};
@@ -139,7 +147,8 @@ schema.statics.getGroup = function getGroup (options = {}) {
let mQuery = this.findOne(query); let mQuery = this.findOne(query);
if (fields) mQuery.select(fields); if (fields) mQuery.select(fields);
if (populateLeader === true) mQuery.populate('leader', nameFields); if (populateLeader === true) mQuery.populate('leader', nameFields);
return mQuery.exec(); let group = await mQuery.exec();
return group;
}; };
// When converting to json remove chat messages with more than 1 flag and remove all flags info // When converting to json remove chat messages with more than 1 flag and remove all flags info
@@ -591,13 +600,16 @@ schema.methods.leave = async function leaveGroup (user, keep = 'keep-all') {
// otherwise just remove a member TODO create User.methods.removeFromGroup? // otherwise just remove a member TODO create User.methods.removeFromGroup?
if (group.type === 'guild') { if (group.type === 'guild') {
promises.push(User.update({_id: user._id}, {$pull: {guilds: group._id } }).exec()); promises.push(User.update({_id: user._id}, {$pull: {guilds: group._id}}).exec());
} else { } else {
promises.push(User.update({_id: user._id}, {$set: {party: {} } }).exec()); promises.push(User.update({_id: user._id}, {$set: {party: {}}}).exec());
} }
// If the leader is leaving (or if the leader previously left, and this wasn't accounted for) // If the leader is leaving (or if the leader previously left, and this wasn't accounted for)
let update = { memberCount: group.memberCount - 1 }; let update = {
$inc: {memberCount: -1},
};
if (group.leader === user._id) { if (group.leader === user._id) {
let query = group.type === 'party' ? {'party._id': group._id} : {guilds: group._id}; let query = group.type === 'party' ? {'party._id': group._id} : {guilds: group._id};
query._id = {$ne: user._id}; query._id = {$ne: user._id};