From c1501db292ab7ab31f1a3821279fb29319cb8098 Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Sat, 30 May 2015 12:08:32 -0500 Subject: [PATCH 1/3] Refactor chat related things into own service --- karma.conf.js | 1 + test/spec/chatServicesSpec.js | 90 +++++++++++++++++++++ website/public/js/app.js | 6 +- website/public/js/controllers/groupsCtrl.js | 26 +++--- website/public/js/services/chatServices.js | 28 +++++++ website/public/js/services/groupServices.js | 26 ------ website/public/manifest.json | 1 + website/src/controllers/groups.js | 3 + 8 files changed, 138 insertions(+), 43 deletions(-) create mode 100644 test/spec/chatServicesSpec.js create mode 100644 website/public/js/services/chatServices.js diff --git a/karma.conf.js b/karma.conf.js index 53a7e4999b..46144335c2 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -45,6 +45,7 @@ module.exports = function(config) { "common/script/public/userServices.js", "common/script/public/directives.js", "website/public/js/services/groupServices.js", + "website/public/js/services/chatServices.js", "website/public/js/services/memberServices.js", "website/public/js/services/guideServices.js", "website/public/js/services/challengeServices.js", diff --git a/test/spec/chatServicesSpec.js b/test/spec/chatServicesSpec.js new file mode 100644 index 0000000000..32cc655c67 --- /dev/null +++ b/test/spec/chatServicesSpec.js @@ -0,0 +1,90 @@ +'use strict'; + +describe('Chat Service', function() { + var $httpBackend, $http, chat, user; + + beforeEach(function() { + module(function($provide) { + var usr = specHelper.newUser(); + $provide.value('User', {user:usr}); + }); + + inject(function(_$httpBackend_, Chat, User) { + $httpBackend = _$httpBackend_; + chat = Chat; + user = User; + }); + }); + + describe('utils', function() { + it('calls chat post endpoint', function() { + var payload = { + gid: 'habitrpg', + message: 'Chat', + previousMsg: 'previous-msg-id' + } + + $httpBackend.expectPOST('/api/v2/groups/habitrpg/chat?message=Chat&previousMsg=previous-msg-id').respond(); + chat.utils.postChat(payload, undefined); + $httpBackend.flush(); + }); + + it('calls chat like endpoint', function() { + var payload = { + gid: 'habitrpg', + messageId: 'msg-id' + } + + $httpBackend.expectPOST('/api/v2/groups/habitrpg/chat/msg-id/like').respond(); + chat.utils.like(payload, undefined); + $httpBackend.flush(); + }); + + it('calls delete chat endpoint', function() { + var payload = { + gid: 'habitrpg', + messageId: 'msg-id' + } + + $httpBackend.expectDELETE('/api/v2/groups/habitrpg/chat/msg-id').respond(); + chat.utils.deleteChatMessage(payload, undefined); + $httpBackend.flush(); + }); + + it('calls flag chat endpoint', function() { + var payload = { + gid: 'habitrpg', + messageId: 'msg-id' + } + + $httpBackend.expectPOST('/api/v2/groups/habitrpg/chat/msg-id/flag').respond(); + chat.utils.flagChatMessage(payload, undefined); + $httpBackend.flush(); + }); + + it('calls clear flags endpoint', function() { + var payload = { + gid: 'habitrpg', + messageId: 'msg-id' + } + + $httpBackend.expectPOST('/api/v2/groups/habitrpg/chat/msg-id/clearflags').respond(); + chat.utils.clearFlagCount(payload, undefined); + $httpBackend.flush(); + }); + }); + + describe('seenMessage(gid)', function() { + it('calls chat seen endpoint', function() { + $httpBackend.expectPOST('/api/v2/groups/habitrpg/chat/seen').respond(); + chat.seenMessage('habitrpg'); + $httpBackend.flush(); + }); + + it('removes newMessages for a specific guild from user object', function() { + user.user.newMessages = {habitrpg: "foo"}; + chat.seenMessage('habitrpg'); + expect(user.user.newMessages.habitrpg).to.not.exist; + }); + }); +}); diff --git a/website/public/js/app.js b/website/public/js/app.js index 94bcb81b3c..cde6ae5a3a 100644 --- a/website/public/js/app.js +++ b/website/public/js/app.js @@ -120,11 +120,11 @@ window.habitrpg = angular.module('habitrpg', .state('options.social.guilds.detail', { url: '/:gid', templateUrl: 'partials/options.social.guilds.detail.html', - controller: ['$scope', 'Groups', '$stateParams', - function($scope, Groups, $stateParams){ + controller: ['$scope', 'Groups', 'Chat', '$stateParams', + function($scope, Groups, Chat, $stateParams){ Groups.Group.get({gid:$stateParams.gid}, function(group){ $scope.group = group; - Groups.seenMessage(group._id); + Chat.seenMessage(group._id); }); }] }) diff --git a/website/public/js/controllers/groupsCtrl.js b/website/public/js/controllers/groupsCtrl.js index c9eb2e37e7..2067ffa21e 100644 --- a/website/public/js/controllers/groupsCtrl.js +++ b/website/public/js/controllers/groupsCtrl.js @@ -159,8 +159,8 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' }; }]) - .controller("MemberModalCtrl", ['$scope', '$rootScope', 'Members', 'Shared', '$http', 'Notification', 'Groups', '$controller', - function($scope, $rootScope, Members, Shared, $http, Notification, Groups, $controller) { + .controller("MemberModalCtrl", ['$scope', '$rootScope', 'Members', 'Shared', '$http', 'Notification', 'Groups', 'Chat', '$controller', + function($scope, $rootScope, Members, Shared, $http, Notification, Groups, Chat, $controller) { $controller('RootCtrl', {$scope: $scope}); @@ -199,13 +199,13 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' } $scope.reportAbuse = function(reporter, message, groupId) { message.flags[reporter._id] = true; - Groups.Group.flagChatMessage({gid: groupId, messageId: message.id}, undefined, function(data){ + Chat.utils.flagChatMessage({gid: groupId, messageId: message.id}, undefined, function(data){ Notification.text(window.env.t('abuseReported')); $scope.$close(); }); } $scope.clearFlagCount = function(message, groupId) { - Groups.Group.clearFlagCount({gid: groupId, messageId: message.id}, undefined, function(data){ + Chat.utils.clearFlagCount({gid: groupId, messageId: message.id}, undefined, function(data){ message.flagCount = 0; Notification.text("Flags cleared"); $scope.$close(); @@ -286,7 +286,7 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' }); }]) - .controller('ChatCtrl', ['$scope', 'Groups', 'User', '$http', 'ApiUrl', 'Notification', 'Members', '$rootScope', function($scope, Groups, User, $http, ApiUrl, Notification, Members, $rootScope){ + .controller('ChatCtrl', ['$scope', 'Groups', 'Chat', 'User', '$http', 'ApiUrl', 'Notification', 'Members', '$rootScope', function($scope, Groups, Chat, User, $http, ApiUrl, Notification, Members, $rootScope){ $scope.message = {content:''}; $scope._sending = false; @@ -312,7 +312,7 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' if (_.isEmpty(message) || $scope._sending) return; $scope._sending = true; var previousMsg = (group.chat && group.chat[0]) ? group.chat[0].id : false; - Groups.Group.postChat({gid: group._id, message:message, previousMsg: previousMsg}, undefined, function(data){ + Chat.utils.postChat({gid: group._id, message:message, previousMsg: previousMsg}, undefined, function(data){ if(data.chat){ group.chat = data.chat; }else if(data.message){ @@ -329,7 +329,7 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' if(message.uuid === User.user.id || (User.user.backer && User.user.contributor.admin)){ var previousMsg = (group.chat && group.chat[0]) ? group.chat[0].id : false; if(confirm('Are you sure you want to delete this message?')){ - Groups.Group.deleteChatMessage({gid:group._id, messageId:message.id, previousMsg:previousMsg}, undefined, function(data){ + Chat.utils.deleteChatMessage({gid:group._id, messageId:message.id, previousMsg:previousMsg}, undefined, function(data){ if(data.chat) group.chat = data.chat; var i = _.findIndex(group.chat, {id: message.id}); @@ -348,9 +348,7 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' } else { message.likes[User.user._id] = true; } - //Chat.Chat.like({gid:group._id,mid:message.id}); - - $http.post(ApiUrl.get() + '/api/v2/groups/' + group._id + '/chat/' + message.id + '/like'); + Chat.utils.like({ gid:group._id, messageId:message.id }, undefined); } $scope.flagChatMessage = function(groupId,message) { @@ -390,7 +388,7 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' $scope.sync = function(group){ group.$get(); //When the user clicks fetch recent messages we need to update that the user has seen the new messages - Groups.seenMessage(group._id); + Chat.seenMessage(group._id); } // List of Ordering options for the party members list @@ -499,15 +497,15 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' } ]) - .controller("PartyCtrl", ['$rootScope','$scope', 'Groups', 'User', 'Challenges', '$state', '$compile', - function($rootScope,$scope, Groups, User, Challenges, $state, $compile) { + .controller("PartyCtrl", ['$rootScope','$scope', 'Groups', 'Chat', 'User', 'Challenges', '$state', '$compile', + function($rootScope,$scope, Groups, Chat, User, Challenges, $state, $compile) { $scope.type = 'party'; $scope.text = window.env.t('party'); $scope.group = $rootScope.party = Groups.party(); $scope.newGroup = new Groups.Group({type:'party'}); - Groups.seenMessage($scope.group._id); + Chat.seenMessage($scope.group._id); $scope.create = function(group){ group.$save(function(){ diff --git a/website/public/js/services/chatServices.js b/website/public/js/services/chatServices.js new file mode 100644 index 0000000000..5e6c2f7728 --- /dev/null +++ b/website/public/js/services/chatServices.js @@ -0,0 +1,28 @@ +'use strict'; + +angular.module('habitrpg').factory('Chat', +['$resource', '$q', '$http', 'ApiUrl', 'User', +function($resource, $q, $http, ApiUrl, User) { + var utils = $resource(ApiUrl.get() + '/api/v2/groups/:gid', + {gid:'@_id', messageId: '@_messageId'}, + { + postChat: {method: "POST", url: ApiUrl.get() + '/api/v2/groups/:gid/chat'}, + like: {method: 'POST', isArray: true, url: ApiUrl.get() + '/api/v2/groups/:gid/chat/:messageId/like'}, + deleteChatMessage: {method: "DELETE", url: ApiUrl.get() + '/api/v2/groups/:gid/chat/:messageId'}, + flagChatMessage: {method: "POST", url: ApiUrl.get() + '/api/v2/groups/:gid/chat/:messageId/flag'}, + clearFlagCount: {method: "POST", url: ApiUrl.get() + '/api/v2/groups/:gid/chat/:messageId/clearflags'}, + }); + + var chatService = { + seenMessage: seenMessage, + utils: utils + }; + + return chatService; + + function seenMessage(gid) { + // On enter, set chat message to "seen" + $http.post(ApiUrl.get() + '/api/v2/groups/'+gid+'/chat/seen'); + if (User.user.newMessages) delete User.user.newMessages[gid]; + } +}]) diff --git a/website/public/js/services/groupServices.js b/website/public/js/services/groupServices.js index ddd9a69ece..fcd80a619b 100644 --- a/website/public/js/services/groupServices.js +++ b/website/public/js/services/groupServices.js @@ -23,10 +23,6 @@ function(ApiUrl, $resource, $q, $http, User, Challenges) { } }, - postChat: {method: "POST", url: ApiUrl.get() + '/api/v2/groups/:gid/chat'}, - deleteChatMessage: {method: "DELETE", url: ApiUrl.get() + '/api/v2/groups/:gid/chat/:messageId'}, - flagChatMessage: {method: "POST", url: ApiUrl.get() + '/api/v2/groups/:gid/chat/:messageId/flag'}, - clearFlagCount: {method: "POST", url: ApiUrl.get() + '/api/v2/groups/:gid/chat/:messageId/clearflags'}, join: {method: "POST", url: ApiUrl.get() + '/api/v2/groups/:gid/join'}, leave: {method: "POST", url: ApiUrl.get() + '/api/v2/groups/:gid/leave'}, invite: {method: "POST", url: ApiUrl.get() + '/api/v2/groups/:gid/invite'}, @@ -66,12 +62,6 @@ function(ApiUrl, $resource, $q, $http, User, Challenges) { return data.tavern; }, - // On enter, set chat message to "seen" - seenMessage: function(gid){ - $http.post(ApiUrl.get() + '/api/v2/groups/'+gid+'/chat/seen'); - if (User.user.newMessages) delete User.user.newMessages[gid]; - }, - questAccept: function(party){ party.$questAccept() .then(syncUser, logError); @@ -99,19 +89,3 @@ function(ApiUrl, $resource, $q, $http, User, Challenges) { Group: Group } }]) -/** - * TODO Get this working. Make ChatService it's own ngResource, so we can update chat without having to sync the whole - * group object (expensive). Also so we can add chat-specific routes - */ -// .factory('Chat', ['API_URL', '$resource', -// function(API_URL, $resource) { -// var Chat = $resource(API_URL + '/api/v2/groups/:gid/chat/:mid', -// //{gid:'@_id', mid: '@_messageId'}, -// { -// like: {method: 'POST', url: API_URL + '/api/v2/groups/:gid/chat/:mid'} -// //postChat: {method: "POST", url: API_URL + '/api/v2/groups/:gid/chat'}, -// //deleteChatMessage: {method: "DELETE", url: API_URL + '/api/v2/groups/:gid/chat/:messageId'}, -// }); -// return {Chat:Chat}; -// } -// ]); diff --git a/website/public/manifest.json b/website/public/manifest.json index 8bb5d7d275..a32d996971 100644 --- a/website/public/manifest.json +++ b/website/public/manifest.json @@ -43,6 +43,7 @@ "common/script/public/userServices.js", "common/script/public/directives.js", "js/services/groupServices.js", + "js/services/chatServices.js", "js/services/memberServices.js", "js/services/guideServices.js", "js/services/challengeServices.js", diff --git a/website/src/controllers/groups.js b/website/src/controllers/groups.js index 6450504459..11fe413f10 100644 --- a/website/src/controllers/groups.js +++ b/website/src/controllers/groups.js @@ -422,6 +422,9 @@ api.likeChatMessage = function(req, res, next) { group.markModified('chat'); group.save(function(err,_saved){ if (err) return next(err); + // @TODO: We're sending back the entire array of chats back + // Should we just send back the object of the single chat message? + // If not, should we update the group chat when a chat is liked? return res.send(_saved.chat); }) } From d21a3b80bf6848a9cffc7c7b4d376427345b460b Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Sat, 30 May 2015 12:33:51 -0500 Subject: [PATCH 2/3] Remove unused dependency --- website/public/js/services/chatServices.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/public/js/services/chatServices.js b/website/public/js/services/chatServices.js index 5e6c2f7728..5980132c74 100644 --- a/website/public/js/services/chatServices.js +++ b/website/public/js/services/chatServices.js @@ -1,8 +1,8 @@ 'use strict'; angular.module('habitrpg').factory('Chat', -['$resource', '$q', '$http', 'ApiUrl', 'User', -function($resource, $q, $http, ApiUrl, User) { +['$resource', '$http', 'ApiUrl', 'User', +function($resource, $http, ApiUrl, User) { var utils = $resource(ApiUrl.get() + '/api/v2/groups/:gid', {gid:'@_id', messageId: '@_messageId'}, { From fa86cd6d8c13d26bfea797b601d5e2f836a4b95f Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Sat, 30 May 2015 12:42:31 -0500 Subject: [PATCH 3/3] Make phrasing of tests consistent --- test/spec/chatServicesSpec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/spec/chatServicesSpec.js b/test/spec/chatServicesSpec.js index 32cc655c67..e65c36be68 100644 --- a/test/spec/chatServicesSpec.js +++ b/test/spec/chatServicesSpec.js @@ -17,7 +17,7 @@ describe('Chat Service', function() { }); describe('utils', function() { - it('calls chat post endpoint', function() { + it('calls post chat endpoint', function() { var payload = { gid: 'habitrpg', message: 'Chat', @@ -29,7 +29,7 @@ describe('Chat Service', function() { $httpBackend.flush(); }); - it('calls chat like endpoint', function() { + it('calls like chat endpoint', function() { var payload = { gid: 'habitrpg', messageId: 'msg-id'