transferGems: use receiver language translation for PM strings #7722 (#8173)

* transferGems: use receiver language translation for PM strings #7722

* chore(test): DRY up transfer gems test

* chore(test): Allow check for language in translation assertion

* chore(test): Add test that member locales are used in transfer gems msg

* sendMessage: optionally take also the message in sender's language

when present, it is stored in the sender's inbox instead of the version
in the target language.

* transferGems: prepare pm in both languages #7722

* sendMessage: take an object for the second parameter instead

* payments: made two more gift strings translatable

* buyGems: send both translations for gifted gems

* buyGems: send push notifications in target user's locale

* createSubscription: send both translations for gifted subs

* createSubscription: send push notifications in target user's locale

* transferGems: send push notifications in target user's locale

* tests: adjust payment tests for translation changes

* added function doc for sendMessage

* tests: added bilingual test for buyGems
This commit is contained in:
Jaka Kranjc 2016-12-16 01:36:54 +01:00 committed by Keith Holliday
parent 3f6a13d209
commit f1a3bd5001
7 changed files with 165 additions and 47 deletions

View file

@ -4,6 +4,14 @@ import {
} from '../../../../helpers/api-v3-integration.helper';
import { v4 as generateUUID } from 'uuid';
function findMessage (messages, receiverId) {
let message = _.find(messages, (inboxMessage) => {
return inboxMessage.uuid === receiverId;
});
return message;
}
describe('POST /members/transfer-gems', () => {
let userToSendMessage;
let receiver;
@ -116,13 +124,8 @@ describe('POST /members/transfer-gems', () => {
let updatedReceiver = await receiver.get('/user');
let updatedSender = await userToSendMessage.get('/user');
let sendersMessageInReceiversInbox = _.find(updatedReceiver.inbox.messages, (inboxMessage) => {
return inboxMessage.uuid === userToSendMessage._id;
});
let sendersMessageInSendersInbox = _.find(updatedSender.inbox.messages, (inboxMessage) => {
return inboxMessage.uuid === receiver._id;
});
let sendersMessageInReceiversInbox = findMessage(updatedReceiver.inbox.messages, userToSendMessage._id);
let sendersMessageInSendersInbox = findMessage(updatedSender.inbox.messages, receiver._id);
let messageSentContent = t('privateMessageGiftIntro', {
receiverName: receiver.profile.name,
@ -150,13 +153,8 @@ describe('POST /members/transfer-gems', () => {
let updatedReceiver = await receiver.get('/user');
let updatedSender = await userToSendMessage.get('/user');
let sendersMessageInReceiversInbox = _.find(updatedReceiver.inbox.messages, (inboxMessage) => {
return inboxMessage.uuid === userToSendMessage._id;
});
let sendersMessageInSendersInbox = _.find(updatedSender.inbox.messages, (inboxMessage) => {
return inboxMessage.uuid === receiver._id;
});
let sendersMessageInReceiversInbox = findMessage(updatedReceiver.inbox.messages, userToSendMessage._id);
let sendersMessageInSendersInbox = findMessage(updatedSender.inbox.messages, receiver._id);
let messageSentContent = t('privateMessageGiftIntro', {
receiverName: receiver.profile.name,
@ -173,4 +171,40 @@ describe('POST /members/transfer-gems', () => {
expect(sendersMessageInSendersInbox.text).to.equal(messageSentContent);
expect(updatedSender.balance).to.equal(0);
});
it('sends transfer gems message in each participant\'s language', async () => {
await receiver.update({
'preferences.language': 'es',
});
await userToSendMessage.update({
'preferences.language': 'cs',
});
await userToSendMessage.post('/members/transfer-gems', {
gemAmount,
toUserId: receiver._id,
});
let updatedReceiver = await receiver.get('/user');
let updatedSender = await userToSendMessage.get('/user');
let sendersMessageInReceiversInbox = findMessage(updatedReceiver.inbox.messages, userToSendMessage._id);
let sendersMessageInSendersInbox = findMessage(updatedSender.inbox.messages, receiver._id);
let [receieversMessageContent, sendersMessageContent] = ['es', 'cs'].map((lang) => {
let messageContent = t('privateMessageGiftIntro', {
receiverName: receiver.profile.name,
senderName: userToSendMessage.profile.name,
}, lang);
messageContent += t('privateMessageGiftGemsMessage', {gemAmount}, lang);
return `\`${messageContent}\` `;
});
expect(sendersMessageInReceiversInbox).to.exist;
expect(sendersMessageInReceiversInbox.text).to.equal(receieversMessageContent);
expect(sendersMessageInSendersInbox).to.exist;
expect(sendersMessageInSendersInbox.text).to.equal(sendersMessageContent);
expect(updatedSender.balance).to.equal(0);
});
});

View file

@ -5,6 +5,7 @@ import notifications from '../../../../../website/server/libs/pushNotifications'
import { model as User } from '../../../../../website/server/models/user';
import { model as Group } from '../../../../../website/server/models/group';
import moment from 'moment';
import { translate as t } from '../../../../helpers/api-v3-integration.helper';
import {
generateGroup,
} from '../../../../helpers/api-unit.helper.js';
@ -181,9 +182,10 @@ describe('payments/index', () => {
it('sends a private message about the gift', async () => {
await api.createSubscription(data);
let msg = '\`Hello recipient, sender has sent you 3 months of subscription!\`';
expect(user.sendMessage).to.be.calledOnce;
expect(user.sendMessage).to.be.calledWith(recipient, '\`Hello recipient, sender has sent you 3 months of subscription!\`');
expect(user.sendMessage).to.be.calledWith(recipient, { receiverMsg: msg, senderMsg: msg });
});
it('sends an email about the gift', async () => {
@ -697,14 +699,37 @@ describe('payments/index', () => {
it('sends a message from purchaser to recipient', async () => {
await api.buyGems(data);
let msg = '\`Hello recipient, sender has sent you 4 gems!\`';
expect(user.sendMessage).to.be.calledWith(recipient, '\`Hello recipient, sender has sent you 4 gems!\`');
expect(user.sendMessage).to.be.calledWith(recipient, { receiverMsg: msg, senderMsg: msg });
});
it('sends a push notification if user did not gift to self', async () => {
await api.buyGems(data);
expect(notifications.sendNotification).to.be.calledOnce;
});
it('sends gem donation message in each participant\'s language', async () => {
await recipient.update({
'preferences.language': 'es',
});
await user.update({
'preferences.language': 'cs',
});
await api.buyGems(data);
let [recipientsMessageContent, sendersMessageContent] = ['es', 'cs'].map((lang) => {
let messageContent = t('giftedGemsFull', {
username: recipient.profile.name,
sender: user.profile.name,
gemAmount: data.gift.gems.amount,
}, lang);
return `\`${messageContent}\``;
});
expect(user.sendMessage).to.be.calledWith(recipient, { receiverMsg: recipientsMessageContent, senderMsg: sendersMessageContent });
});
});
});
});

View file

@ -7,8 +7,8 @@ const STRING_DOES_NOT_EXIST_MSG = /^String '.*' not found.$/;
// Use this to verify error messages returned by the server
// That way, if the translated string changes, the test
// will not break. NOTE: it checks against errors with string as well.
export function translate (key, variables) {
let translatedString = i18n.t(key, variables);
export function translate (key, variables, language) {
let translatedString = i18n.t(key, variables, language);
expect(translatedString).to.not.be.empty;
expect(translatedString).to.not.eql(STRING_ERROR_MSG);

View file

@ -113,8 +113,10 @@
"sentGems": "Sent gems!",
"giftedGems": "Gifted Gems",
"giftedGemsInfo": "<%= name %> gifted you <%= amount %> Gems",
"giftedGemsFull": "Hello <%= username %>, <%= sender %> has sent you <%= gemAmount %> gems!",
"giftedSubscription": "Gifted Subscription",
"giftedSubscriptionInfo": "<%= name %> gifted you a <%= months %> month subscription",
"giftedSubscriptionFull": "Hello <%= username %>, <%= sender %> has sent you <%= monthCount %> months of subscription!",
"invitedParty": "Invited To Party",
"invitedGuild": "Invited To Guild",
"importantAnnouncements": "Your account is inactive",

View file

@ -422,7 +422,7 @@ api.sendPrivateMessage = {
throw new NotAuthorized(res.t('notAuthorizedToSendMessageToThisUser'));
}
await sender.sendMessage(receiver, message);
await sender.sendMessage(receiver, { receiverMsg: message });
if (receiver.preferences.emailNotifications.newPM !== false) {
sendTxnEmail(receiver, 'new-pm', [
@ -492,18 +492,27 @@ api.transferGems = {
let promises = [receiver.save(), sender.save()];
await Bluebird.all(promises);
let message = res.t('privateMessageGiftIntro', {
receiverName: receiver.profile.name,
senderName: sender.profile.name,
// generate the message in both languages, so both users can understand it
let receiverLang = receiver.preferences.language;
let senderLang = sender.preferences.language;
let [receiverMsg, senderMsg] = [receiverLang, senderLang].map((lang) => {
let messageContent = res.t('privateMessageGiftIntro', {
receiverName: receiver.profile.name,
senderName: sender.profile.name,
}, lang);
messageContent += res.t('privateMessageGiftGemsMessage', {gemAmount}, lang);
messageContent = `\`${messageContent}\` `;
if (req.body.message) {
messageContent += req.body.message;
}
return messageContent;
});
message += res.t('privateMessageGiftGemsMessage', {gemAmount});
message = `\`${message}\` `;
if (req.body.message) {
message += req.body.message;
}
await sender.sendMessage(receiver, message);
await sender.sendMessage(receiver, {
senderMsg,
receiverMsg,
});
let byUsername = getUserInfo(sender, ['name']).name;
@ -516,8 +525,8 @@ api.transferGems = {
if (receiver.preferences.pushNotifications.giftedGems !== false) {
sendPushNotification(receiver,
{
title: res.t('giftedGems'),
message: res.t('giftedGemsInfo', {amount: gemAmount, name: byUsername}),
title: res.t('giftedGems', receiverLang),
message: res.t('giftedGemsInfo', {amount: gemAmount, name: byUsername}, receiverLang),
identifier: 'giftedGems',
payload: {replyTo: sender._id},
});

View file

@ -138,13 +138,31 @@ api.createSubscription = async function createSubscription (data) {
if (!group) data.user.purchased.txnCount++;
if (data.gift) {
let message = `\`Hello ${data.gift.member.profile.name}, ${data.user.profile.name} has sent you ${shared.content.subscriptionBlocks[data.gift.subscription.key].months} months of subscription!\``;
if (data.gift.message) message += ` ${data.gift.message}`;
data.user.sendMessage(data.gift.member, message);
let byUserName = getUserInfo(data.user, ['name']).name;
// generate the message in both languages, so both users can understand it
let languages = [data.user.preferences.language, data.gift.member.preferences.language];
let senderMsg = shared.i18n.t('giftedSubscriptionFull', {
username: data.gift.member.profile.name,
sender: byUserName,
monthCount: shared.content.subscriptionBlocks[data.gift.subscription.key].months,
}, languages[0]);
senderMsg = `\`${senderMsg}\``;
let receiverMsg = shared.i18n.t('giftedSubscriptionFull', {
username: data.gift.member.profile.name,
sender: byUserName,
monthCount: shared.content.subscriptionBlocks[data.gift.subscription.key].months,
}, languages[1]);
receiverMsg = `\`${receiverMsg}\``;
if (data.gift.message) {
receiverMsg += ` ${data.gift.message}`;
senderMsg += ` ${data.gift.message}`;
}
data.user.sendMessage(data.gift.member, { receiverMsg, senderMsg });
if (data.gift.member.preferences.emailNotifications.giftedSubscription !== false) {
txnEmail(data.gift.member, 'gifted-subscription', [
{name: 'GIFTER', content: byUserName},
@ -156,8 +174,8 @@ api.createSubscription = async function createSubscription (data) {
if (data.gift.member.preferences.pushNotifications.giftedSubscription !== false) {
sendPushNotification(data.gift.member,
{
title: shared.i18n.t('giftedSubscription'),
message: shared.i18n.t('giftedSubscriptionInfo', {months, name: byUserName}),
title: shared.i18n.t('giftedSubscription', languages[1]),
message: shared.i18n.t('giftedSubscriptionInfo', {months, name: byUserName}, languages[1]),
identifier: 'giftedSubscription',
payload: {replyTo: data.user._id},
}
@ -276,9 +294,28 @@ api.buyGems = async function buyGems (data) {
let byUsername = getUserInfo(data.user, ['name']).name;
let gemAmount = data.gift.gems.amount || 20;
let message = `\`Hello ${data.gift.member.profile.name}, ${data.user.profile.name} has sent you ${gemAmount} gems!\``;
if (data.gift.message) message += ` ${data.gift.message}`;
data.user.sendMessage(data.gift.member, message);
// generate the message in both languages, so both users can understand it
let languages = [data.user.preferences.language, data.gift.member.preferences.language];
let senderMsg = shared.i18n.t('giftedGemsFull', {
username: data.gift.member.profile.name,
sender: byUsername,
gemAmount,
}, languages[0]);
senderMsg = `\`${senderMsg}\``;
let receiverMsg = shared.i18n.t('giftedGemsFull', {
username: data.gift.member.profile.name,
sender: byUsername,
gemAmount,
}, languages[1]);
receiverMsg = `\`${receiverMsg}\``;
if (data.gift.message) {
receiverMsg += ` ${data.gift.message}`;
senderMsg += ` ${data.gift.message}`;
}
data.user.sendMessage(data.gift.member, { receiverMsg, senderMsg });
if (data.gift.member.preferences.emailNotifications.giftedGems !== false) {
txnEmail(data.gift.member, 'gifted-gems', [
@ -292,8 +329,8 @@ api.buyGems = async function buyGems (data) {
sendPushNotification(
data.gift.member,
{
title: shared.i18n.t('giftedGems'),
message: shared.i18n.t('giftedGemsInfo', {amount: gemAmount, name: byUsername}),
title: shared.i18n.t('giftedGems', languages[1]),
message: shared.i18n.t('giftedGemsInfo', {amount: gemAmount, name: byUsername}, languages[1]),
identifier: 'giftedGems',
}
);

View file

@ -20,15 +20,26 @@ schema.methods.getGroups = function getUserGroups () {
return userGroups;
};
schema.methods.sendMessage = async function sendMessage (userToReceiveMessage, message) {
let sender = this;
common.refPush(userToReceiveMessage.inbox.messages, chatDefaults(message, sender));
/**
* Sends a message to a user. Archives a copy in sender's inbox.
*
* @param userToReceiveMessage The receiver
* @param options
* @param options.receiverMsg The message to send to the receiver
* @param options.senderMsg The message to archive instead of receiverMsg
* @return N/A
*/
schema.methods.sendMessage = async function sendMessage (userToReceiveMessage, options) {
let sender = this;
let senderMsg = options.senderMsg || options.receiverMsg;
common.refPush(userToReceiveMessage.inbox.messages, chatDefaults(options.receiverMsg, sender));
userToReceiveMessage.inbox.newMessages++;
userToReceiveMessage._v++;
userToReceiveMessage.markModified('inbox.messages');
common.refPush(sender.inbox.messages, defaults({sent: true}, chatDefaults(message, userToReceiveMessage)));
common.refPush(sender.inbox.messages, defaults({sent: true}, chatDefaults(senderMsg, userToReceiveMessage)));
sender.markModified('inbox.messages');
let promises = [userToReceiveMessage.save(), sender.save()];