Ported sendPrivateMessage route and added initial tests

This commit is contained in:
Keith Holliday
2016-03-21 16:02:35 -05:00
parent be9312deb0
commit e9a9079c46
4 changed files with 256 additions and 1 deletions

View File

@@ -117,5 +117,9 @@
"missingPetFoodFeed": "\"pet\" and \"food\" are required parameters.",
"invalidPetName": "Invalid pet name supplied.",
"missingEggHatchingPotionHatch": "\"egg\" and \"hatchingPotion\" are required parameters.",
"invalidTypeEquip": "\"type\" must be one of 'equipped', 'pet', 'mount', 'costume'."
"invalidTypeEquip": "\"type\" must be one of 'equipped', 'pet', 'mount', 'costume'.",
"cannoyBuyItem": "You can't buy this item",
"messageRequired": "A message is required.",
"toUserIDRequired": "A toUserId is required",
"notAuthorizedToSendMessageToThisUser": "Can't send message to this user."
}

View File

@@ -0,0 +1,171 @@
import {
generateUser,
translate as t,
} from '../../../../helpers/api-v3-integration.helper';
import { v4 as generateUUID } from 'uuid';
describe('POST /send-private-message', () => {
let userToSendMessage;
let messageToSend = { message: 'Test Private Message' };
beforeEach(async () => {
userToSendMessage = await generateUser();
});
it('returns error when message is not provided', async () => {
await expect(userToSendMessage.post('/send-private-message'))
.to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: 'Invalid request parameters.',
});
});
it('returns error when toUserId is not provided', async () => {
await expect(userToSendMessage.post('/send-private-message', {
message: messageToSend,
})).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: 'Invalid request parameters.',
});
});
it('returns error when to user is not found', async () => {
await expect(userToSendMessage.post('/send-private-message', {
message: messageToSend,
toUserId: generateUUID(),
})).to.eventually.be.rejected.and.eql({
code: 404,
error: 'NotFound',
message: t('userNotFound'),
});
});
it('returns error when to user has blocked the sender', async () => {
let receiver = await generateUser({'inbox.blocks': [userToSendMessage._id]});
await expect(userToSendMessage.post('/send-private-message', {
message: messageToSend,
toUserId: receiver._id,
})).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('notAuthorizedToSendMessageToThisUser'),
});
});
it('returns error when sender has blocked to user', async () => {
let receiver = await generateUser();
let sender = await generateUser({'inbox.blocks': [receiver._id]});
await expect(sender.post('/send-private-message', {
message: messageToSend,
toUserId: receiver._id,
})).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('notAuthorizedToSendMessageToThisUser'),
});
});
it('returns error when to user has opted out of messaging', async () => {
let receiver = await generateUser({'inbox.optOut': true});
await expect(userToSendMessage.post('/send-private-message', {
message: messageToSend,
toUserId: receiver._id,
})).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('notAuthorizedToSendMessageToThisUser'),
});
});
it('sends a private message to a user', async () => {
let receiver = await generateUser();
await userToSendMessage.post('/send-private-message', {
message: messageToSend,
toUserId: receiver._id,
});
let updatedReceiver = await receiver.get('/user');
let updatedSender = await userToSendMessage.get('/user');
let sendersMessageInReceiversInbox = _.find(updatedReceiver.inbox.messages, (message) => {
return message.uuid === userToSendMessage._id && message.text === messageToSend.message;
});
let sendersMessageInSendersInbox = _.find(updatedSender.inbox.messages, (message) => {
return message.uuid === receiver._id && message.text === messageToSend.message;
});
expect(sendersMessageInReceiversInbox).to.exist;
expect(sendersMessageInSendersInbox).to.exist;
});
it('sends a private message about gems to a user', async () => {
let receiver = await generateUser();
let messageAboutGemsToSend = {
type: 'gems',
gems: {
amount: 2,
},
message: 'Test Message About Gems',
};
await userToSendMessage.post('/send-private-message', {
message: messageAboutGemsToSend,
toUserId: receiver._id,
});
let updatedReceiver = await receiver.get('/user');
let updatedSender = await userToSendMessage.get('/user');
let sendersMessageInReceiversInbox = _.find(updatedReceiver.inbox.messages, (message) => {
return message.uuid === userToSendMessage._id;
});
let sendersMessageInSendersInbox = _.find(updatedSender.inbox.messages, (message) => {
return message.uuid === receiver._id;
});
expect(sendersMessageInReceiversInbox).to.exist;
expect(sendersMessageInReceiversInbox.text).to.equal(`Hello ${receiver.profile.name}, ${userToSendMessage.profile.name} has sent you ${messageAboutGemsToSend.gems.amount} gems! ${messageAboutGemsToSend.message}`);
expect(sendersMessageInSendersInbox).to.exist;
expect(sendersMessageInSendersInbox.text).to.equal(`Hello ${receiver.profile.name}, ${userToSendMessage.profile.name} has sent you ${messageAboutGemsToSend.gems.amount} gems! ${messageAboutGemsToSend.message}`);
});
it('sends a private message about subscriptions to a user', async () => {
let receiver = await generateUser();
let messageAboutSubscriptionToSend = {
type: 'subscription',
subscription: {
key: 'basic_12mo',
},
message: 'Test Message About Subscription',
};
await userToSendMessage.post('/send-private-message', {
message: messageAboutSubscriptionToSend,
toUserId: receiver._id,
});
let updatedReceiver = await receiver.get('/user');
let updatedSender = await userToSendMessage.get('/user');
let sendersMessageInReceiversInbox = _.find(updatedReceiver.inbox.messages, (message) => {
return message.uuid === userToSendMessage._id;
});
let sendersMessageInSendersInbox = _.find(updatedSender.inbox.messages, (message) => {
return message.uuid === receiver._id;
});
expect(sendersMessageInReceiversInbox).to.exist;
expect(sendersMessageInReceiversInbox.text).to.equal(`Hello ${receiver.profile.name}, ${userToSendMessage.profile.name} has sent you 12 months of subscription! ${messageAboutSubscriptionToSend.message}`);
expect(sendersMessageInSendersInbox).to.exist;
expect(sendersMessageInSendersInbox.text).to.equal(`Hello ${receiver.profile.name}, ${userToSendMessage.profile.name} has sent you 12 months of subscription! ${messageAboutSubscriptionToSend.message}`);
});
});

View File

@@ -9,8 +9,13 @@ import { model as Group } from '../../models/group';
import { model as Challenge } from '../../models/challenge';
import {
NotFound,
NotAuthorized,
} from '../../libs/api-v3/errors';
import * as Tasks from '../../models/task';
import {
getUserInfo,
sendTxn as sendTxnEmail,
} from '../../libs/api-v3/email';
let api = {};
@@ -231,4 +236,53 @@ api.getChallengeMemberProgress = {
},
};
/**
* @api {posts} /send-private-message Get a challenge member progress
* @apiVersion 3.0.0
* @apiName SendPrivateMessage
* @apiGroup Members
*
* @apiParam {String} message The message
* @apiParam {UUID} toUserId The toUser _id
*
* @apiSuccess {} Object Returns an empty object
*/
api.sendPrivateMessage = {
method: 'POST',
url: '/send-private-message',
middlewares: [authWithHeaders(), cron],
async handler (req, res) {
req.checkBody('message', res.t('messageRequired')).notEmpty();
req.checkBody('toUserId', res.t('toUserIDRequired')).notEmpty().isUUID();
let validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
let sender = res.locals.user;
let message = req.body.message;
let userToReceiveMessage = await User.findById(req.body.toUserId).exec();
if (!userToReceiveMessage) throw new NotFound(res.t('userNotFound'));
let userBlockedSender = userToReceiveMessage.inbox.blocks.indexOf(sender._id) !== -1;
let userIsBlockBySender = sender.inbox.blocks.indexOf(userToReceiveMessage._id) !== -1;
let userOptedOutOfMessaging = userToReceiveMessage.inbox.optOut;
if (userBlockedSender || userIsBlockBySender || userOptedOutOfMessaging) {
throw new NotAuthorized(res.t('notAuthorizedToSendMessageToThisUser'));
}
await sender.sendMessage(userToReceiveMessage, message);
if (userToReceiveMessage.preferences.emailNotifications.newPM !== false) {
sendTxnEmail(userToReceiveMessage, 'new-pm', [
{name: 'SENDER', content: getUserInfo(sender, ['name']).name},
{name: 'PMS_INBOX_URL', content: '/#/options/groups/inbox'},
]);
}
res.respond(200, {});
},
};
module.exports = api;

View File

@@ -7,6 +7,8 @@ import * as Tasks from './task';
import Q from 'q';
import { schema as TagSchema } from './tag';
import baseModel from '../libs/api-v3/baseModel';
import { chatDefaults } from './group';
import { defaults } from 'lodash';
// import {model as Challenge} from './challenge';
let Schema = mongoose.Schema;
@@ -706,6 +708,30 @@ schema.methods.getGroups = function getUserGroups () {
return userGroups;
};
schema.methods.sendMessage = async function sendMessage (userToReceiveMessage, messageData) {
let msg;
let sender = this;
if (!messageData.type) {
msg = messageData.message;
} else {
msg = `Hello ${userToReceiveMessage.profile.name }, ${sender.profile.name} has sent you `;
msg += messageData.type === 'gems' ? `${messageData.gems.amount} gems! ` : `${shared.content.subscriptionBlocks[messageData.subscription.key].months} months of subscription! `;
msg += messageData.message;
}
shared.refPush(userToReceiveMessage.inbox.messages, chatDefaults(msg, sender));
userToReceiveMessage.inbox.newMessages++;
userToReceiveMessage._v++;
userToReceiveMessage.markModified('inbox.messages');
shared.refPush(sender.inbox.messages, defaults({sent: true}, chatDefaults(msg, userToReceiveMessage)));
sender.markModified('inbox.messages');
let promises = [userToReceiveMessage.save(), sender.save()];
await Q.all(promises);
};
export let model = mongoose.model('User', schema);
// Initially export an empty object so external requires will get