correct async/await usages, improve email tests (#15408)

This commit is contained in:
negue
2025-03-17 22:11:38 +01:00
committed by GitHub
parent 8327e69bdd
commit 0c6e254742
4 changed files with 49 additions and 30 deletions

View File

@@ -171,23 +171,23 @@ describe('emails', () => {
expect(got.post).not.to.be.called; expect(got.post).not.to.be.called;
}); });
it('throws error when mail target is only a string', () => { it('throws error when mail target is only a string', async () => {
const emailType = 'an email type'; const emailType = 'an email type';
const mailingInfo = 'my email'; const mailingInfo = 'my email';
expect(sendTxn(mailingInfo, emailType)).to.throw; await expect(sendTxn(mailingInfo, emailType)).to.be.rejectedWith('Argument Error mailingInfoArray: does not contain email or _id');
}); });
it('throws error when mail target has no _id or email', () => { it('throws error when mail target has no _id or email', async () => {
const emailType = 'an email type'; const emailType = 'an email type';
const mailingInfo = { const mailingInfo = {
}; };
expect(sendTxn(mailingInfo, emailType)).to.throw; await expect(sendTxn(mailingInfo, emailType)).to.be.rejectedWith('Argument Error mailingInfoArray: does not contain email or _id');
}); });
it('throws error when variables not an array', () => { it('throws error when variables not an array', async () => {
const emailType = 'an email type'; const emailType = 'an email type';
const mailingInfo = { const mailingInfo = {
name: 'my name', name: 'my name',
@@ -195,9 +195,10 @@ describe('emails', () => {
}; };
const variables = {}; const variables = {};
expect(sendTxn(mailingInfo, emailType, variables)).to.throw; await expect(sendTxn(mailingInfo, emailType, variables)).to.be.rejectedWith('Argument Error variables: is not an array');
}); });
it('throws error when variables array not contain name/content', () => {
it('throws error when variables array not contain name/content', async () => {
const emailType = 'an email type'; const emailType = 'an email type';
const mailingInfo = { const mailingInfo = {
name: 'my name', name: 'my name',
@@ -209,8 +210,9 @@ describe('emails', () => {
}, },
]; ];
expect(sendTxn(mailingInfo, emailType, variables)).to.throw; await expect(sendTxn(mailingInfo, emailType, variables)).to.be.rejectedWith('Argument Error variables: does not contain name or content');
}); });
it('throws no error when variables array contain name but no content', () => { it('throws no error when variables array contain name but no content', () => {
const emailType = 'an email type'; const emailType = 'an email type';
const mailingInfo = { const mailingInfo = {

View File

@@ -120,9 +120,12 @@ api.inviteToQuest = {
// send out invites // send out invites
const inviterVars = getUserInfo(user, ['name', 'email']); const inviterVars = getUserInfo(user, ['name', 'email']);
const membersToEmail = members.filter(async member => { const membersToEmail = [];
for (const member of members) {
// send push notifications while filtering members before sending emails // send push notifications while filtering members before sending emails
if (member.preferences.pushNotifications.invitedQuest !== false) { if (member.preferences.pushNotifications.invitedQuest !== false) {
// eslint-disable-next-line no-await-in-loop
await sendPushNotification( await sendPushNotification(
member, member,
{ {
@@ -141,8 +144,11 @@ api.inviteToQuest = {
quest, quest,
}); });
return member.preferences.emailNotifications.invitedQuest !== false; if (member.preferences.emailNotifications.invitedQuest !== false) {
}); membersToEmail.push(member);
}
}
sendTxnEmail(membersToEmail, `invite-${quest.boss ? 'boss' : 'collection'}-quest`, [ sendTxnEmail(membersToEmail, `invite-${quest.boss ? 'boss' : 'collection'}-quest`, [
{ name: 'QUEST_NAME', content: quest.text() }, { name: 'QUEST_NAME', content: quest.text() },
{ name: 'INVITER', content: inviterVars.name }, { name: 'INVITER', content: inviterVars.name },

View File

@@ -65,7 +65,13 @@ export function getGroupUrl (group) {
return groupUrl; return groupUrl;
} }
// Send a transactional email using Mandrill through the external email server /**
* Send a transactional email using Mandrill through the external email server
*
* Individual "canSend" per type needs to be done before,
* internally it checks by `getUserInfo` if the
* `unsubscribeFromAll` is set to true, if so it won't send the email.
*/
export async function sendTxn (mailingInfoArray, emailType, variables, personalVariables) { export async function sendTxn (mailingInfoArray, emailType, variables, personalVariables) {
if (!Array.isArray(mailingInfoArray)) { if (!Array.isArray(mailingInfoArray)) {
mailingInfoArray = [mailingInfoArray]; // eslint-disable-line no-param-reassign mailingInfoArray = [mailingInfoArray]; // eslint-disable-line no-param-reassign
@@ -73,7 +79,7 @@ export async function sendTxn (mailingInfoArray, emailType, variables, personalV
for (const entry of mailingInfoArray) { for (const entry of mailingInfoArray) {
if (typeof entry === 'string' if (typeof entry === 'string'
&& (typeof entry._id === 'undefined' && typeof entry.email === 'undefined') || (typeof entry._id === 'undefined' && typeof entry.email === 'undefined')
) { ) {
throw new Error('Argument Error mailingInfoArray: does not contain email or _id'); throw new Error('Argument Error mailingInfoArray: does not contain email or _id');
} }

View File

@@ -770,23 +770,28 @@ schema.methods.startQuest = async function startQuest (user) {
const membersToEmail = []; const membersToEmail = [];
// send notifications and webhooks in the background without blocking // send notifications and webhooks in the background without blocking
await members.forEach(async member => { for (const member of members) {
if (member._id !== user._id) { if (member._id === user._id) {
// send push notifications and filter users that disabled emails // early "exit", saving one indention level
// eslint-disable-next-line no-continue
continue;
}
// add email to send if that user did not disabled this email
if (member.preferences.emailNotifications.questStarted !== false) { if (member.preferences.emailNotifications.questStarted !== false) {
membersToEmail.push(member); membersToEmail.push(member);
} }
// send push notifications and filter users that disabled emails // send push notifications if that user did not disabled this notifications
if (member.preferences.pushNotifications.questStarted !== false) { if (member.preferences.pushNotifications.questStarted !== false) {
const memberLang = member.preferences.language; const memberLang = member.preferences.language;
// eslint-disable-next-line no-await-in-loop
await sendPushNotification(member, { await sendPushNotification(member, {
title: quest.text(memberLang), title: quest.text(memberLang),
message: shared.i18n.t('questStarted', memberLang), message: shared.i18n.t('questStarted', memberLang),
identifier: 'questStarted', identifier: 'questStarted',
}); });
} }
}
// Send webhooks // Send webhooks
questActivityWebhook.send(member, { questActivityWebhook.send(member, {
@@ -794,7 +799,7 @@ schema.methods.startQuest = async function startQuest (user) {
group: this, group: this,
quest, quest,
}); });
}); }
// Send emails in bulk // Send emails in bulk
sendTxnEmail(membersToEmail, 'quest-started', [ sendTxnEmail(membersToEmail, 'quest-started', [