mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-13 20:57:24 +01:00
fix: remove guild or party when user looks it up if it does not exist
closes #7878 fixes #7724
This commit is contained in:
@@ -3,6 +3,7 @@ import {
|
||||
createAndPopulateGroup,
|
||||
translate as t,
|
||||
} from '../../../../helpers/api-v3-integration.helper';
|
||||
import { v4 as generateUUID } from 'uuid';
|
||||
|
||||
import {
|
||||
each,
|
||||
@@ -170,6 +171,45 @@ describe('GET /groups/:id', () => {
|
||||
message: t('groupNotFound'),
|
||||
});
|
||||
});
|
||||
|
||||
it('removes non-existant guild from user\'s guild list', async () => {
|
||||
let guildId = generateUUID();
|
||||
|
||||
await user.update({
|
||||
guilds: [guildId, generateUUID()],
|
||||
});
|
||||
|
||||
await expect(user.get(`/groups/${guildId}`))
|
||||
.to.eventually.be.rejected.and.eql({
|
||||
code: 404,
|
||||
error: 'NotFound',
|
||||
message: t('groupNotFound'),
|
||||
});
|
||||
|
||||
await user.sync();
|
||||
|
||||
expect(user.guilds).to.have.a.lengthOf(1);
|
||||
expect(user.guilds).to.not.include(guildId);
|
||||
});
|
||||
|
||||
it('removes non-existant party from user\'s party object', async () => {
|
||||
let partyId = generateUUID();
|
||||
|
||||
await user.update({
|
||||
party: { _id: partyId },
|
||||
});
|
||||
|
||||
await expect(user.get(`/groups/${partyId}`))
|
||||
.to.eventually.be.rejected.and.eql({
|
||||
code: 404,
|
||||
error: 'NotFound',
|
||||
message: t('groupNotFound'),
|
||||
});
|
||||
|
||||
await user.sync();
|
||||
|
||||
expect(user.party).to.eql({});
|
||||
});
|
||||
});
|
||||
|
||||
context('Flagged messages', () => {
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
generateUser,
|
||||
translate as t,
|
||||
} from '../../../../helpers/api-v3-integration.helper';
|
||||
import { v4 as generateUUID } from 'uuid';
|
||||
import {
|
||||
each,
|
||||
} from 'lodash';
|
||||
@@ -171,6 +172,19 @@ describe('POST /groups/:groupId/leave', () => {
|
||||
|
||||
expect(userWithoutInvitation.invitations.guilds).to.not.be.empty;
|
||||
});
|
||||
|
||||
it('deletes non existant guild from user when user tries to leave', async () => {
|
||||
let nonExistentGuildId = generateUUID();
|
||||
let userWithNonExistentGuild = await generateUser({guilds: [nonExistentGuildId]});
|
||||
expect(userWithNonExistentGuild.guilds).to.contain(nonExistentGuildId);
|
||||
|
||||
await expect(userWithNonExistentGuild.post(`/groups/${nonExistentGuildId}/leave`))
|
||||
.to.eventually.be.rejected;
|
||||
|
||||
await userWithNonExistentGuild.sync();
|
||||
|
||||
expect(userWithNonExistentGuild.guilds).to.not.contain(nonExistentGuildId);
|
||||
});
|
||||
});
|
||||
|
||||
context('party', () => {
|
||||
@@ -206,5 +220,18 @@ describe('POST /groups/:groupId/leave', () => {
|
||||
expect(userWithoutInvitation.invitations.party).to.be.empty;
|
||||
});
|
||||
});
|
||||
|
||||
it('deletes non existant party from user when user tries to leave', async () => {
|
||||
let nonExistentPartyId = generateUUID();
|
||||
let userWithNonExistentParty = await generateUser({'party._id': nonExistentPartyId});
|
||||
expect(userWithNonExistentParty.party._id).to.be.eql(nonExistentPartyId);
|
||||
|
||||
await expect(userWithNonExistentParty.post(`/groups/${nonExistentPartyId}/leave`))
|
||||
.to.eventually.be.rejected;
|
||||
|
||||
await userWithNonExistentParty.sync();
|
||||
|
||||
expect(userWithNonExistentParty.party).to.eql({});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -327,7 +327,7 @@ describe('Post /groups/:groupId/invite', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('allow inviting a user to a party if he\'s partying solo', async () => {
|
||||
it('allow inviting a user to a party if they are partying solo', async () => {
|
||||
let userToInvite = await generateUser();
|
||||
await userToInvite.post('/groups', { // add user to a party
|
||||
name: 'Another Test Party',
|
||||
@@ -339,5 +339,16 @@ describe('Post /groups/:groupId/invite', () => {
|
||||
});
|
||||
expect((await userToInvite.get('/user')).invitations.party.id).to.equal(party._id);
|
||||
});
|
||||
|
||||
it('allow inviting a user if party id is not associated with a real party', async () => {
|
||||
let userToInvite = await generateUser({
|
||||
party: { _id: generateUUID() },
|
||||
});
|
||||
|
||||
await inviter.post(`/groups/${party._id}/invite`, {
|
||||
uuids: [userToInvite._id],
|
||||
});
|
||||
expect((await userToInvite.get('/user')).invitations.party.id).to.equal(party._id);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -124,8 +124,11 @@ api.getGroup = {
|
||||
let validationErrors = req.validationErrors();
|
||||
if (validationErrors) throw validationErrors;
|
||||
|
||||
let group = await Group.getGroup({user, groupId: req.params.groupId, populateLeader: false});
|
||||
if (!group) throw new NotFound(res.t('groupNotFound'));
|
||||
let groupId = req.params.groupId;
|
||||
let group = await Group.getGroup({user, groupId, populateLeader: false});
|
||||
if (!group) {
|
||||
throw new NotFound(res.t('groupNotFound'));
|
||||
}
|
||||
|
||||
group = Group.toJSONCleanChat(group, user);
|
||||
// Instead of populate we make a find call manually because of https://github.com/Automattic/mongoose/issues/3833
|
||||
@@ -347,8 +350,11 @@ api.leaveGroup = {
|
||||
let validationErrors = req.validationErrors();
|
||||
if (validationErrors) throw validationErrors;
|
||||
|
||||
let group = await Group.getGroup({user, groupId: req.params.groupId, fields: '-chat', requireMembership: true});
|
||||
if (!group) throw new NotFound(res.t('groupNotFound'));
|
||||
let groupId = req.params.groupId;
|
||||
let group = await Group.getGroup({user, groupId, fields: '-chat', requireMembership: true});
|
||||
if (!group) {
|
||||
throw new NotFound(res.t('groupNotFound'));
|
||||
}
|
||||
|
||||
// During quests, checke wheter user can leave
|
||||
if (group.type === 'party') {
|
||||
@@ -510,7 +516,7 @@ async function _inviteByUUID (uuid, group, inviter, req, res) {
|
||||
let userParty = await Group.getGroup({user: userToInvite, groupId: 'party', fields: 'memberCount'});
|
||||
|
||||
// Allow user to be invited to a new party when they're partying solo
|
||||
if (userParty.memberCount !== 1) throw new NotAuthorized(res.t('userAlreadyInAParty'));
|
||||
if (userParty && userParty.memberCount !== 1) throw new NotAuthorized(res.t('userAlreadyInAParty'));
|
||||
}
|
||||
|
||||
userToInvite.invitations.party = {id: group._id, name: group.name, inviter: inviter._id};
|
||||
|
||||
@@ -159,6 +159,17 @@ schema.statics.getGroup = async function getGroup (options = {}) {
|
||||
if (fields) mQuery.select(fields);
|
||||
if (populateLeader === true) mQuery.populate('leader', nameFields);
|
||||
let group = await mQuery.exec();
|
||||
|
||||
if (!group) {
|
||||
if (groupId === user.party._id) {
|
||||
// reset party object to default state
|
||||
user.party = {};
|
||||
} else {
|
||||
removeFromArray(user.guilds, groupId);
|
||||
}
|
||||
await user.save();
|
||||
}
|
||||
|
||||
return group;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user