From 1f4a0680ea549ab711f09b0a66bb26a0a754ff9f Mon Sep 17 00:00:00 2001 From: Victor Piousbox Date: Sat, 9 Apr 2016 16:56:03 +0000 Subject: [PATCH] shared-code-private-messages --- common/locales/en/api-v3.json | 1 + common/script/index.js | 6 ++ common/script/ops/blockUser.js | 26 +++++---- common/script/ops/clearPMs.js | 9 ++- common/script/ops/deletePM.js | 12 ++-- tasks/gulp-eslint.js | 3 - .../user/DELETE-user_messages.test.js | 27 +++++++++ .../integration/user/POST-user_block.test.js | 34 +++++++++++ test/common/ops/blockUser.test.js | 44 ++++++++++++++ test/common/ops/clearPMs.test.js | 20 +++++++ test/common/ops/deletePM.test.js | 20 +++++++ website/src/controllers/api-v3/user.js | 57 +++++++++++++++++++ 12 files changed, 235 insertions(+), 24 deletions(-) create mode 100644 test/api/v3/integration/user/DELETE-user_messages.test.js create mode 100644 test/api/v3/integration/user/POST-user_block.test.js create mode 100644 test/common/ops/blockUser.test.js create mode 100644 test/common/ops/clearPMs.test.js create mode 100644 test/common/ops/deletePM.test.js diff --git a/common/locales/en/api-v3.json b/common/locales/en/api-v3.json index 0eb2d4b7a3..ac83dd75f8 100644 --- a/common/locales/en/api-v3.json +++ b/common/locales/en/api-v3.json @@ -104,6 +104,7 @@ "spellNotFound": "Spell \"<%= spellId %>\" not found.", "partyNotFound": "Party not found", "targetIdUUID": "\"targetId\" must be a valid UUID.", + "invalidUUID": "UUID must be valid", "challengeTasksNoCast": "Casting a spell on challenge tasks is not supported.", "spellNotOwned": "You don't own this spell.", "spellLevelTooHigh": "You must be level <%= level %> to use this spell.", diff --git a/common/script/index.js b/common/script/index.js index 1c4bd65db6..a40a589260 100644 --- a/common/script/index.js +++ b/common/script/index.js @@ -115,6 +115,9 @@ import sell from './ops/sell'; import unlock from './ops/unlock'; import revive from './ops/revive'; import rebirth from './ops/rebirth'; +import blockUser from './ops/blockUser'; +import clearPMs from './ops/clearPMs'; +import deletePM from './ops/deletePM'; import reroll from './ops/reroll'; api.ops = { @@ -147,6 +150,9 @@ api.ops = { unlock, revive, rebirth, + blockUser, + clearPMs, + deletePM, reroll, }; diff --git a/common/script/ops/blockUser.js b/common/script/ops/blockUser.js index dd08925640..9663eb57e7 100644 --- a/common/script/ops/blockUser.js +++ b/common/script/ops/blockUser.js @@ -1,13 +1,19 @@ -module.exports = function(user, req, cb) { - var i; - i = user.inbox.blocks.indexOf(req.params.uuid); - if (~i) { - user.inbox.blocks.splice(i, 1); - } else { +import validator from 'validator'; +import i18n from '../../../common/script/i18n'; +import { + BadRequest, +} from '../libs/errors'; + +module.exports = function blockUser (user, req = {}) { + if (!validator.isUUID(req.params.uuid)) throw new BadRequest(i18n.t('invalidUUID', req.language)); + + let i = user.inbox.blocks.indexOf(req.params.uuid); + if (i === -1) { user.inbox.blocks.push(req.params.uuid); + } else { + user.inbox.blocks.splice(i, 1); } - if (typeof user.markModified === "function") { - user.markModified('inbox.blocks'); - } - return typeof cb === "function" ? cb(null, user.inbox.blocks) : void 0; + + user.markModified('inbox.blocks'); + return user.inbox.blocks; }; diff --git a/common/script/ops/clearPMs.js b/common/script/ops/clearPMs.js index 47e0a6ebc6..6a7eb91b39 100644 --- a/common/script/ops/clearPMs.js +++ b/common/script/ops/clearPMs.js @@ -1,7 +1,6 @@ -module.exports = function(user, req, cb) { + +module.exports = function clearPMs (user) { user.inbox.messages = {}; - if (typeof user.markModified === "function") { - user.markModified('inbox.messages'); - } - return typeof cb === "function" ? cb(null, user.inbox.messages) : void 0; + user.markModified('inbox.messages'); + return user.inbox.messages; }; diff --git a/common/script/ops/deletePM.js b/common/script/ops/deletePM.js index ad95bc9ae0..826cf9ee1a 100644 --- a/common/script/ops/deletePM.js +++ b/common/script/ops/deletePM.js @@ -1,7 +1,7 @@ -module.exports = function(user, req, cb) { - delete user.inbox.messages[req.params.id]; - if (typeof user.markModified === "function") { - user.markModified('inbox.messages.' + req.params.id); - } - return typeof cb === "function" ? cb(null, user.inbox.messages) : void 0; +import _ from 'lodash'; + +module.exports = function deletePM (user, req = {}) { + delete user.inbox.messages[_.get(req, 'params.id')]; + user.markModified(`inbox.messages.${req.params.id}`); + return user.inbox.messages; }; diff --git a/tasks/gulp-eslint.js b/tasks/gulp-eslint.js index cad0d88e9c..2ca438f969 100644 --- a/tasks/gulp-eslint.js +++ b/tasks/gulp-eslint.js @@ -11,9 +11,6 @@ const COMMON_FILES = [ // @TODO remove these negations as the files are converted over. '!./common/script/content/index.js', '!./common/script/ops/addPushDevice.js', - '!./common/script/ops/blockUser.js', - '!./common/script/ops/clearPMs.js', - '!./common/script/ops/deletePM.js', '!./common/script/ops/reset.js', '!./common/script/fns/crit.js', '!./common/script/fns/randomDrop.js', diff --git a/test/api/v3/integration/user/DELETE-user_messages.test.js b/test/api/v3/integration/user/DELETE-user_messages.test.js new file mode 100644 index 0000000000..98df8e0209 --- /dev/null +++ b/test/api/v3/integration/user/DELETE-user_messages.test.js @@ -0,0 +1,27 @@ +import { + generateUser, +} from '../../../../helpers/api-integration/v3'; + +describe('DELETE user message', () => { + let user; + + beforeEach(async () => { + user = await generateUser({ inbox: { messages: { first: 'message', second: 'message' } } }); + expect(user.inbox.messages.first).to.eql('message'); + expect(user.inbox.messages.second).to.eql('message'); + }); + + it('one message', async () => { + let result = await user.del('/user/messages/first'); + await user.sync(); + expect(result).to.eql({ second: 'message' }); + expect(user.inbox.messages).to.eql({ second: 'message' }); + }); + + it('clear all', async () => { + let result = await user.del('/user/messages'); + await user.sync(); + expect(user.inbox.messages).to.eql({}); + expect(result).to.eql({}); + }); +}); diff --git a/test/api/v3/integration/user/POST-user_block.test.js b/test/api/v3/integration/user/POST-user_block.test.js new file mode 100644 index 0000000000..51766eb51e --- /dev/null +++ b/test/api/v3/integration/user/POST-user_block.test.js @@ -0,0 +1,34 @@ +import { + generateUser, + translate as t, +} from '../../../../helpers/api-integration/v3'; + +describe('block user', () => { + let user; + let blockedUser; + let blockedUser2; + + beforeEach(async () => { + blockedUser = await generateUser(); + blockedUser2 = await generateUser(); + user = await generateUser({ inbox: { blocks: [blockedUser._id] } }); + expect(user.inbox.blocks.length).to.eql(1); + expect(user.inbox.blocks).to.eql([blockedUser._id]); + }); + + it('validates uuid', async () => { + await expect(user.post('/user/block/1')).to.eventually.be.rejected.and.eql({ + code: 400, + error: 'BadRequest', + message: t('invalidUUID'), + }); + }); + + it('successfully', async () => { + let response = await user.post(`/user/block/${blockedUser2._id}`); + await user.sync(); + expect(response).to.eql([blockedUser._id, blockedUser2._id]); + expect(user.inbox.blocks.length).to.eql(2); + expect(user.inbox.blocks).to.include(blockedUser2._id); + }); +}); diff --git a/test/common/ops/blockUser.test.js b/test/common/ops/blockUser.test.js new file mode 100644 index 0000000000..01b5185ed0 --- /dev/null +++ b/test/common/ops/blockUser.test.js @@ -0,0 +1,44 @@ +import blockUser from '../../../common/script/ops/blockUser'; +import { + generateUser, +} from '../../helpers/common.helper'; +import i18n from '../../../common/script/i18n'; + +describe('shared.ops.blockUser', () => { + let user; + let blockedUser; + let blockedUser2; + + beforeEach(() => { + blockedUser = generateUser(); + blockedUser2 = generateUser(); + user = generateUser(); + expect(user.inbox.blocks).to.eql([]); + }); + + it('validates uuid', (done) => { + try { + blockUser(user, { params: { uuid: 1 } }); + } catch (error) { + expect(error.message).to.eql(i18n.t('invalidUUID')); + done(); + } + }); + + it('blocks user', () => { + let result = blockUser(user, { params: { uuid: blockedUser._id } }); + expect(user.inbox.blocks).to.eql([blockedUser._id]); + expect(result).to.eql([blockedUser._id]); + result = blockUser(user, { params: { uuid: blockedUser2._id } }); + expect(user.inbox.blocks).to.eql([blockedUser._id, blockedUser2._id]); + expect(result).to.eql([blockedUser._id, blockedUser2._id]); + }); + + it('blocks, then unblocks user', () => { + blockUser(user, { params: { uuid: blockedUser._id } }); + expect(user.inbox.blocks).to.eql([blockedUser._id]); + let result = blockUser(user, { params: { uuid: blockedUser._id } }); + expect(user.inbox.blocks).to.eql([]); + expect(result).to.eql([]); + }); +}); diff --git a/test/common/ops/clearPMs.test.js b/test/common/ops/clearPMs.test.js new file mode 100644 index 0000000000..a2ff2a7a0b --- /dev/null +++ b/test/common/ops/clearPMs.test.js @@ -0,0 +1,20 @@ +import clearPMs from '../../../common/script/ops/clearPMs'; +import { + generateUser, +} from '../../helpers/common.helper'; + +describe('shared.ops.clearPMs', () => { + let user; + + beforeEach(() => { + user = generateUser(); + user.inbox.messages = { first: 'message', second: 'message' }; + }); + + it('clears messages', () => { + expect(user.inbox.messages).to.not.eql({}); + let result = clearPMs(user); + expect(user.inbox.messages).to.eql({}); + expect(result).to.eql({}); + }); +}); diff --git a/test/common/ops/deletePM.test.js b/test/common/ops/deletePM.test.js new file mode 100644 index 0000000000..472bede6a3 --- /dev/null +++ b/test/common/ops/deletePM.test.js @@ -0,0 +1,20 @@ +import deletePM from '../../../common/script/ops/deletePM'; +import { + generateUser, +} from '../../helpers/common.helper'; + +describe('shared.ops.clearPMs', () => { + let user; + + beforeEach(() => { + user = generateUser(); + user.inbox.messages = { first: 'message', second: 'message' }; + }); + + it('delete message', () => { + expect(user.inbox.messages).to.not.eql({ second: 'message' }); + let response = deletePM(user, { params: { id: 'first' } }); + expect(user.inbox.messages).to.eql({ second: 'message' }); + expect(response).to.eql({ second: 'message' }); + }); +}); diff --git a/website/src/controllers/api-v3/user.js b/website/src/controllers/api-v3/user.js index a6eb3e9b2c..c69c862bb5 100644 --- a/website/src/controllers/api-v3/user.js +++ b/website/src/controllers/api-v3/user.js @@ -974,6 +974,63 @@ api.userRebirth = { }, }; +/** + * @api {post} /user/block/:uuid blocks and unblocks a user + * @apiVersion 3.0.0 + * @apiName BlockUser + * @apiGroup User + * @apiSuccess {} +**/ +api.blockUser = { + method: 'POST', + middlewares: [authWithHeaders()], + url: '/user/block/:uuid', + async handler (req, res) { + let user = res.locals.user; + let blocks = common.ops.blockUser(user, req); + await user.save(); + res.respond(200, blocks); + }, +}; + +/** + * @api {delete} /user/messages/:id delete this message + * @apiVersion 3.0.0 + * @apiName deleteMessage + * @apiGroup User + * @apiSuccess {} +**/ +api.deleteMessage = { + method: 'DELETE', + middlewares: [authWithHeaders(), cron], + url: '/user/messages/:id', + async handler (req, res) { + let user = res.locals.user; + let messages = common.ops.deletePM(user, req); + await user.save(); + res.respond(200, messages); + }, +}; + +/** + * @api {delete} /user/messages delete all messages + * @apiVersion 3.0.0 + * @apiName clearMessages + * @apiGroup User + * @apiSuccess {} +**/ +api.clearMessages = { + method: 'DELETE', + middlewares: [authWithHeaders(), cron], + url: '/user/messages', + async handler (req, res) { + let user = res.locals.user; + let PMs = common.ops.clearPMs(user, req); + await user.save(); + res.respond(200, PMs); + }, +}; + /* * @api {post} /user/reroll Rerolls a user. * @apiVersion 3.0.0