mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-19 15:48:04 +01:00
check for membership when leaving public guild, fix memberCount update when leaving group, add missing files
This commit is contained in:
@@ -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', () => {
|
||||||
|
|||||||
3
test/api/v3/integration/user/auth/GET-logout.test.js
Normal file
3
test/api/v3/integration/user/auth/GET-logout.test.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
describe('GET /user/auth/logout', () => {
|
||||||
|
// TODO Test manually
|
||||||
|
});
|
||||||
18
test/api/v3/integration/user/auth/POST-firebase.test.js
Normal file
18
test/api/v3/integration/user/auth/POST-firebase.test.js
Normal 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');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -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, () => {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -597,7 +606,10 @@ schema.methods.leave = async function leaveGroup (user, keep = 'keep-all') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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};
|
||||||
|
|||||||
Reference in New Issue
Block a user