From e3c79fbdfa3fabc7ef239653c49dd54d0ad83937 Mon Sep 17 00:00:00 2001 From: Keith Holliday Date: Sun, 22 May 2016 02:55:45 +0100 Subject: [PATCH] Added tags update route. Added sort to user service (#7381) * Added tags update route. Added sort to user service * Change update tasks route to reorder tasks * Fixed linting issue * Changed params for reorder tags route * Fixed not found tag and added test --- common/locales/en/tasks.json | 1 + common/script/ops/sortTag.js | 5 ++- .../integration/tags/POST-tag-reorder.test.js | 44 +++++++++++++++++++ .../js/directives/hrpg-sort-tags.directive.js | 2 +- website/client/js/services/tagsServices.js | 9 ++++ website/client/js/services/userServices.js | 5 +++ website/server/controllers/api-v3/tags.js | 35 +++++++++++++++ 7 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 test/api/v3/integration/tags/POST-tag-reorder.test.js diff --git a/common/locales/en/tasks.json b/common/locales/en/tasks.json index 5b32829f81..b9180af3bf 100644 --- a/common/locales/en/tasks.json +++ b/common/locales/en/tasks.json @@ -73,6 +73,7 @@ "clearTags": "Clear", "hideTags": "Hide", "showTags": "Show", + "toRequired": "You must supply a to value", "startDate": "Start Date", "startDateHelpTitle": "When should this task start?", "startDateHelp": "Set the date for which this task takes effect. Will not be due on earlier days.", diff --git a/common/script/ops/sortTag.js b/common/script/ops/sortTag.js index 29756a8b82..c1fc42f330 100644 --- a/common/script/ops/sortTag.js +++ b/common/script/ops/sortTag.js @@ -7,7 +7,10 @@ module.exports = function sortTag (user, req = {}) { let to = _.get(req, 'query.to'); let fromParam = _.get(req, 'query.from'); - if (!to || !fromParam) { + let invalidTo = !to && to !== 0; + let invalidFrom = !fromParam && fromParam !== 0; + + if (invalidTo || invalidFrom) { throw new BadRequest('?to=__&from=__ are required'); } diff --git a/test/api/v3/integration/tags/POST-tag-reorder.test.js b/test/api/v3/integration/tags/POST-tag-reorder.test.js new file mode 100644 index 0000000000..0710cecf3e --- /dev/null +++ b/test/api/v3/integration/tags/POST-tag-reorder.test.js @@ -0,0 +1,44 @@ +import { + generateUser, + translate as t, +} from '../../../../helpers/api-integration/v3'; + +describe('POST /reorder-tags', () => { + let user; + + before(async () => { + user = await generateUser(); + }); + + it('returns error when no parameters are provided', async () => { + await expect(user.post('/reorder-tags')) + .to.eventually.be.rejected.and.eql({ + code: 400, + error: 'BadRequest', + message: 'Invalid request parameters.', + }); + }); + + it('returns error when tag is not found', async () => { + await expect(user.post('/reorder-tags', {tagId: 'fake-id', to: 3})) + .to.eventually.be.rejected.and.eql({ + code: 404, + error: 'NotFound', + message: t('tagNotFound'), + }); + }); + + it('updates tags', async () => { + let tag1Name = 'Tag 1'; + let tag2Name = 'Tag 2'; + await user.post('/tags', {name: tag1Name}); + await user.post('/tags', {name: tag2Name}); + await user.sync(); + + await user.post('/reorder-tags', {tagId: user.tags[4].id, to: 3}); + await user.sync(); + + expect(user.tags[3].name).to.equal(tag2Name); + expect(user.tags[4].name).to.equal(tag1Name); + }); +}); diff --git a/website/client/js/directives/hrpg-sort-tags.directive.js b/website/client/js/directives/hrpg-sort-tags.directive.js index 93fb115116..9a9e3d49bb 100644 --- a/website/client/js/directives/hrpg-sort-tags.directive.js +++ b/website/client/js/directives/hrpg-sort-tags.directive.js @@ -19,7 +19,7 @@ User.sortTag({ query: { from: ui.item.data('startIndex'), - to:ui.item.index() + to: ui.item.index() } }); } diff --git a/website/client/js/services/tagsServices.js b/website/client/js/services/tagsServices.js index a31ecc155e..2a430282b6 100644 --- a/website/client/js/services/tagsServices.js +++ b/website/client/js/services/tagsServices.js @@ -34,6 +34,14 @@ angular.module('habitrpg') }); }; + function sortTag (tagId, to) { + return $http({ + method: 'POST', + url: 'api/v3/reorder-tags', + data: {tagId: tagId, to: to}, + }); + }; + function deleteTag (tagId) { return $http({ method: 'DELETE', @@ -46,6 +54,7 @@ angular.module('habitrpg') createTag: createTag, getTag: getTag, updateTag: updateTag, + sortTag: sortTag, deleteTag: deleteTag, }; }]); diff --git a/website/client/js/services/userServices.js b/website/client/js/services/userServices.js index 4dfdb84e49..70b8821c6d 100644 --- a/website/client/js/services/userServices.js +++ b/website/client/js/services/userServices.js @@ -267,6 +267,11 @@ angular.module('habitrpg') Tags.updateTag(data.params.id, data.body); }, + sortTag: function (data) { + user.ops.sortTag(data); + Tags.sortTag(user.tags[data.query.from].id, data.query.to); + }, + deleteTag: function(data) { user.ops.deleteTag(data); save(); diff --git a/website/server/controllers/api-v3/tags.js b/website/server/controllers/api-v3/tags.js index 69117e6fd7..250c343537 100644 --- a/website/server/controllers/api-v3/tags.js +++ b/website/server/controllers/api-v3/tags.js @@ -113,6 +113,41 @@ api.updateTag = { }, }; +/** + * @api {post} /api/v3/reorder-tags Reorder a tag + * @apiVersion 3.0.0 + * @apiName ReorderTags + * @apiGroup Tag + * + * @apiParam {tagId} UUID Id of the tag to move + * @apiParam {to} number Position the tag is moving to + * + * @apiSuccess {object} data An empty object + */ +api.reorderTags = { + method: 'POST', + url: '/reorder-tags', + middlewares: [authWithHeaders()], + async handler (req, res) { + let user = res.locals.user; + + req.checkBody('to', res.t('toRequired')).notEmpty(); + req.checkBody('tagId', res.t('tagIdRequired')).notEmpty(); + + let validationErrors = req.validationErrors(); + if (validationErrors) throw validationErrors; + + let tagIndex = _.findIndex(user.tags, function findTag (tag) { + return tag.id === req.body.tagId; + }); + if (tagIndex === -1) throw new NotFound(res.t('tagNotFound')); + user.tags.splice(req.body.to, 0, user.tags.splice(tagIndex, 1)[0]); + + await user.save(); + res.respond(200, {}); + }, +}; + /** * @api {delete} /api/v3/tag/:tagId Delete a user tag given its id * @apiVersion 3.0.0