mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-16 06:07:21 +01:00
Remove and clean up unused invite notif (#15279)
* fix(notifications): remove and clean up unused invite notif * fix(lint): remove unused const * refactor(invites): updateMany in migration, don't load inviter unless needed * fix(lint): remove extra whitespace * fix(groups): remove more broken inviter logic --------- Co-authored-by: Sabe Jones <sabe@habitica.com>
This commit is contained in:
47
migrations/archive/2024/2024_purge_invite_accepted.js
Normal file
47
migrations/archive/2024/2024_purge_invite_accepted.js
Normal file
@@ -0,0 +1,47 @@
|
||||
/* eslint-disable no-console */
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const MIGRATION_NAME = '2024_purge_invite_accepted';
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUsers (userIds) {
|
||||
count += userIds.length;
|
||||
if (count % progressCount === 0) console.warn(`${count} ${userIds[0]}`);
|
||||
|
||||
return await User.updateMany(
|
||||
{ _id: { $in: userIds } },
|
||||
{ $pull: { notifications: { type: 'GROUP_INVITE_ACCEPTED' } } },
|
||||
).exec();
|
||||
}
|
||||
|
||||
export default async function processUsers () {
|
||||
let query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
'notifications.type': 'GROUP_INVITE_ACCEPTED',
|
||||
'auth.timestamps.loggedin': { $gt: new Date('2024-06-25') },
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({ _id: 1 })
|
||||
.select({ _id: 1 })
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
const userIds = users.map(user => user._id);
|
||||
|
||||
await updateUsers(userIds); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -85,22 +85,6 @@ describe('POST /group/:groupId/join', () => {
|
||||
await expect(user.get('/user')).to.eventually.have.nested.property('items.quests.basilist', 1);
|
||||
});
|
||||
|
||||
it('notifies inviting user that their invitation was accepted', async () => {
|
||||
await invitedUser.post(`/groups/${guild._id}/join`);
|
||||
|
||||
const inviter = await user.get('/user');
|
||||
const expectedData = {
|
||||
headerText: t('invitationAcceptedHeader'),
|
||||
bodyText: t('invitationAcceptedBody', {
|
||||
username: invitedUser.auth.local.username,
|
||||
groupName: guild.name,
|
||||
}),
|
||||
};
|
||||
|
||||
expect(inviter.notifications[1].type).to.eql('GROUP_INVITE_ACCEPTED');
|
||||
expect(inviter.notifications[1].data).to.eql(expectedData);
|
||||
});
|
||||
|
||||
it('awards Joined Guild achievement', async () => {
|
||||
await invitedUser.post(`/groups/${guild._id}/join`);
|
||||
|
||||
@@ -155,23 +139,6 @@ describe('POST /group/:groupId/join', () => {
|
||||
await expect(invitedUser.get('/user')).to.eventually.have.nested.property('party._id', party._id);
|
||||
});
|
||||
|
||||
it('notifies inviting user that their invitation was accepted', async () => {
|
||||
await invitedUser.post(`/groups/${party._id}/join`);
|
||||
|
||||
const inviter = await user.get('/user');
|
||||
|
||||
const expectedData = {
|
||||
headerText: t('invitationAcceptedHeader'),
|
||||
bodyText: t('invitationAcceptedBody', {
|
||||
username: invitedUser.auth.local.username,
|
||||
groupName: party.name,
|
||||
}),
|
||||
};
|
||||
|
||||
expect(inviter.notifications[0].type).to.eql('GROUP_INVITE_ACCEPTED');
|
||||
expect(inviter.notifications[0].data).to.eql(expectedData);
|
||||
});
|
||||
|
||||
it('clears invitation from user when joining party', async () => {
|
||||
await invitedUser.post(`/groups/${party._id}/join`);
|
||||
|
||||
|
||||
@@ -610,7 +610,6 @@ api.joinGroup = {
|
||||
|
||||
if (hasInvitation) {
|
||||
isUserInvited = true;
|
||||
inviter = hasInvitation.inviter;
|
||||
} else {
|
||||
isUserInvited = group.privacy !== 'private';
|
||||
}
|
||||
@@ -634,42 +633,28 @@ api.joinGroup = {
|
||||
group.leader = user._id; // If new user is only member -> set as leader
|
||||
}
|
||||
|
||||
let promises = [user.save()];
|
||||
|
||||
if (group.type === 'party') {
|
||||
// For parties we count the number of members from the database to get the correct value.
|
||||
// See #12275 on why this is necessary and only done for parties.
|
||||
const currentMembers = await group.getMemberCount();
|
||||
group.memberCount = currentMembers + 1;
|
||||
} else {
|
||||
group.memberCount += 1;
|
||||
}
|
||||
|
||||
let promises = [group.save(), user.save()];
|
||||
|
||||
// Load the inviter
|
||||
if (inviter) inviter = await User.findById(inviter).exec();
|
||||
|
||||
// Check the inviter again, could be a deleted account
|
||||
if (inviter) {
|
||||
const data = {
|
||||
headerText: common.i18n.t('invitationAcceptedHeader', inviter.preferences.language),
|
||||
bodyText: common.i18n.t('invitationAcceptedBody', {
|
||||
groupName: group.name,
|
||||
username: user.profile.name,
|
||||
}, inviter.preferences.language),
|
||||
};
|
||||
inviter.addNotification('GROUP_INVITE_ACCEPTED', data);
|
||||
|
||||
// Reward Inviter
|
||||
if (group.type === 'party') {
|
||||
if (!inviter.items.quests.basilist) {
|
||||
inviter.items.quests.basilist = 0;
|
||||
}
|
||||
inviter.items.quests.basilist += 1;
|
||||
inviter.markModified('items.quests');
|
||||
promises.push(inviter.save());
|
||||
}
|
||||
}
|
||||
group.memberCount = currentMembers + 1;
|
||||
|
||||
if (group.type === 'party' && inviter) {
|
||||
// Handle awarding party-related achievements
|
||||
if (group.memberCount > 1) {
|
||||
const notification = new UserNotification({ type: 'ACHIEVEMENT_PARTY_UP' });
|
||||
|
||||
@@ -677,20 +662,12 @@ api.joinGroup = {
|
||||
{
|
||||
$or: [{ 'party._id': group._id }, { _id: user._id }],
|
||||
'achievements.partyUp': { $ne: true },
|
||||
_id: { $ne: inviter._id },
|
||||
},
|
||||
{
|
||||
$set: { 'achievements.partyUp': true },
|
||||
$push: { notifications: notification.toObject() },
|
||||
},
|
||||
).exec());
|
||||
|
||||
if (inviter) {
|
||||
if (inviter.achievements.partyUp !== true) {
|
||||
inviter.achievements.partyUp = true;
|
||||
inviter.addNotification('ACHIEVEMENT_PARTY_UP');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (group.memberCount > 3) {
|
||||
@@ -700,22 +677,18 @@ api.joinGroup = {
|
||||
{
|
||||
$or: [{ 'party._id': group._id }, { _id: user._id }],
|
||||
'achievements.partyOn': { $ne: true },
|
||||
_id: { $ne: inviter._id },
|
||||
},
|
||||
{
|
||||
$set: { 'achievements.partyOn': true },
|
||||
$push: { notifications: notification.toObject() },
|
||||
},
|
||||
).exec());
|
||||
}
|
||||
} else {
|
||||
group.memberCount += 1;
|
||||
}
|
||||
|
||||
if (inviter) {
|
||||
if (inviter.achievements.partyOn !== true) {
|
||||
inviter.achievements.partyOn = true;
|
||||
inviter.addNotification('ACHIEVEMENT_PARTY_ON');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
promises.push(group.save());
|
||||
|
||||
const analyticsObject = {
|
||||
uuid: user._id,
|
||||
@@ -727,15 +700,9 @@ api.joinGroup = {
|
||||
privacy: group.privacy,
|
||||
headers: req.headers,
|
||||
invited: isUserInvited,
|
||||
seekingParty: group.type === 'party' ? seekingParty : null,
|
||||
};
|
||||
if (group.type === 'party') {
|
||||
analyticsObject.seekingParty = seekingParty;
|
||||
}
|
||||
if (group.privacy === 'public') {
|
||||
analyticsObject.groupName = group.name;
|
||||
}
|
||||
|
||||
if (inviter) promises.push(inviter.save());
|
||||
promises = await Promise.all(promises);
|
||||
|
||||
if (group.hasNotCancelled()) {
|
||||
@@ -743,7 +710,7 @@ api.joinGroup = {
|
||||
await group.updateGroupPlan();
|
||||
}
|
||||
|
||||
const response = await Group.toJSONCleanChat(promises[0], user);
|
||||
const response = await Group.toJSONCleanChat(group, user);
|
||||
const leader = await User.findById(response.leader).select(nameFields).exec();
|
||||
if (leader) {
|
||||
response.leader = leader.toJSON({ minimize: true });
|
||||
|
||||
Reference in New Issue
Block a user