From 415418f30ca5bd1832fe27e9bc165f2b79b07b37 Mon Sep 17 00:00:00 2001 From: Keith Holliday Date: Sat, 30 Apr 2016 02:54:25 -0600 Subject: [PATCH] Api v3 members port (#7109) * Ported groups service to user new api v3 and ported dependent controllers * Remove and extra remove inviation code. Fixed group service caching and update group service tests * Fixed test logic and added party cache support * Updated members service to use api v3 * Removed onlys * Added invites to group detail * Removed old user reject invite code --- test/spec/services/memberServicesSpec.js | 78 ++++++++++-- website/public/js/app.js | 12 +- website/public/js/controllers/groupsCtrl.js | 29 +++-- website/public/js/controllers/guildsCtrl.js | 1 - .../public/js/controllers/memberModalCtrl.js | 26 ++-- website/public/js/services/groupServices.js | 2 +- website/public/js/services/memberServices.js | 118 +++++++++++++----- 7 files changed, 196 insertions(+), 70 deletions(-) diff --git a/test/spec/services/memberServicesSpec.js b/test/spec/services/memberServicesSpec.js index d33ccd8c98..1344bf96e7 100644 --- a/test/spec/services/memberServicesSpec.js +++ b/test/spec/services/memberServicesSpec.js @@ -2,6 +2,7 @@ describe('memberServices', function() { var $httpBackend, members; + var apiV3Prefix = '/api/v3'; beforeEach(inject(function (_$httpBackend_, Members) { $httpBackend = _$httpBackend_; @@ -20,10 +21,51 @@ describe('memberServices', function() { expect(members.selectedMember).to.be.undefined; }); + it('calls fetch member', function() { + var memberId = 1; + var memberUrl = apiV3Prefix + '/members/' + memberId; + $httpBackend.expectGET(memberUrl).respond({}); + members.fetchMember(memberId); + $httpBackend.flush(); + }); + + it('calls get group members', function() { + var groupId = 1; + var memberUrl = apiV3Prefix + '/groups/' + groupId + '/members'; + $httpBackend.expectGET(memberUrl).respond({}); + members.getGroupMembers(groupId); + $httpBackend.flush(); + }); + + it('calls get group invites', function() { + var groupId = 1; + var memberUrl = apiV3Prefix + '/groups/' + groupId + '/invites'; + $httpBackend.expectGET(memberUrl).respond({}); + members.getGroupInvites(groupId); + $httpBackend.flush(); + }); + + it('calls get challenge members', function() { + var challengeId = 1; + var memberUrl = apiV3Prefix + '/challenges/' + challengeId + '/members'; + $httpBackend.expectGET(memberUrl).respond({}); + members.getChallengeMembers(challengeId); + $httpBackend.flush(); + }); + + it('calls get challenge members progress', function() { + var challengeId = 1; + var memberId = 2; + var memberUrl = apiV3Prefix + '/challenges/' + challengeId + '/members/' + memberId; + $httpBackend.expectGET(memberUrl).respond({}); + members.getChallengeMemberProgress(challengeId, memberId); + $httpBackend.flush(); + }); + describe('addToMembersList', function() { it('adds member to members object', function() { var member = { _id: 'user_id' }; - members.addToMembersList(member); + members.addToMembersList(member, members); expect(members.members).to.eql({ user_id: { _id: 'user_id' } }); @@ -31,27 +73,37 @@ describe('memberServices', function() { }); describe('selectMember', function() { - it('fetches member if not already in cache', function() { + it('fetches member if not already in cache', function(done) { var uid = 'abc'; - $httpBackend.expectGET('/api/v2/members/' + uid).respond({ _id: uid }); - members.selectMember(uid, function(){}); + var memberResponse = { + data: {_id: uid}, + } + $httpBackend.expectGET(apiV3Prefix + '/members/' + uid).respond(memberResponse); + members.selectMember(uid) + .then(function () { + expect(members.selectedMember._id).to.eql(uid); + expect(members.members).to.have.property(uid); + done(); + }); $httpBackend.flush(); - - expect(members.selectedMember._id).to.eql(uid); - expect(members.members).to.have.property(uid); }); - it('fetches member if member data in cache is incomplete', function() { + it('fetches member if member data in cache is incomplete', function(done) { var uid = 'abc'; members.members = { abc: { _id: 'abc', items: {} } } - $httpBackend.expectGET('/api/v2/members/' + uid).respond({ _id: uid }); - members.selectMember(uid, function(){}); + var memberResponse = { + data: {_id: uid}, + } + $httpBackend.expectGET(apiV3Prefix + '/members/' + uid).respond(memberResponse); + members.selectMember(uid) + .then(function () { + expect(members.selectedMember._id).to.eql(uid); + expect(members.members).to.have.property(uid); + done(); + }); $httpBackend.flush(); - - expect(members.selectedMember._id).to.eql(uid); - expect(members.members).to.have.property(uid); }); it('gets member from cache if member has a weapons object', function() { diff --git a/website/public/js/app.js b/website/public/js/app.js index 47ed3fb970..b8beb61d4e 100644 --- a/website/public/js/app.js +++ b/website/public/js/app.js @@ -150,12 +150,20 @@ window.habitrpg = angular.module('habitrpg', url: '/:gid', templateUrl: 'partials/options.social.guilds.detail.html', title: env.t('titleGuilds'), - controller: ['$scope', 'Groups', 'Chat', '$stateParams', - function($scope, Groups, Chat, $stateParams){ + controller: ['$scope', 'Groups', 'Chat', '$stateParams', 'Members', + function($scope, Groups, Chat, $stateParams, Members){ Groups.Group.get($stateParams.gid) .then(function (response) { $scope.group = response.data.data; Chat.markChatSeen($scope.group._id); + Members.getGroupMembers($scope.group._id) + .then(function (response) { + $scope.group.members = response.data.data; + }); + Members.getGroupInvites($scope.group._id) + .then(function (response) { + $scope.group.invites = response.data.data; + }); }); }] }) diff --git a/website/public/js/controllers/groupsCtrl.js b/website/public/js/controllers/groupsCtrl.js index 224efc6fdb..f932d62cb6 100644 --- a/website/public/js/controllers/groupsCtrl.js +++ b/website/public/js/controllers/groupsCtrl.js @@ -2,7 +2,6 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '$http', '$q', 'User', 'Members', '$state', 'Notification', function($scope, $rootScope, Shared, Groups, $http, $q, User, Members, $state, Notification) { - $scope.isMemberOfPendingQuest = function (userid, group) { if (!group.quest || !group.quest.members) return false; if (group.quest.active) return false; // quest is started, not pending @@ -39,7 +38,8 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' }; $scope.Members = Members; - $scope._editing = {group:false}; + + $scope._editing = {group: false}; $scope.groupCopy = {}; $scope.editGroup = function (group) { @@ -74,7 +74,7 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' // ------ Modals ------ - $scope.clickMember = function(uid, forceShow) { + $scope.clickMember = function (uid, forceShow) { if (User.user._id == uid && !forceShow) { if ($state.is('tasks')) { $state.go('options.profile.avatar'); @@ -84,13 +84,14 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' } else { // We need the member information up top here, but then we pass it down to the modal controller // down below. Better way of handling this? - Members.selectMember(uid, function(){ - $rootScope.openModal('member', {controller:'MemberModalCtrl', windowClass:'profile-modal', size:'lg'}); - }); + Members.selectMember(uid) + .then(function () { + $rootScope.openModal('member', {controller: 'MemberModalCtrl', windowClass: 'profile-modal', size: 'lg'}); + }); } }; - $scope.removeMember = function(group, member, isMember){ + $scope.removeMember = function (group, member, isMember) { // TODO find a better way to do this (share data with remove member modal) $scope.removeMemberData = { group: group, @@ -100,7 +101,7 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' $rootScope.openModal('remove-member', {scope: $scope}); }; - $scope.confirmRemoveMember = function(confirm){ + $scope.confirmRemoveMember = function (confirm) { if (confirm) { Groups.Group.removeMember( $scope.removeMemberData.group._id, @@ -120,10 +121,11 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' } }; - $scope.openInviteModal = function(group){ + $scope.openInviteModal = function (group) { if (group.type !== 'party' && group.type !== 'guild') { return console.log('Invalid group type.') } + $rootScope.openModal('invite-' + group.type, { controller:'InviteToGroupCtrl', resolve: { @@ -134,9 +136,10 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' }); }; - $scope.quickReply = function(uid) { - Members.selectMember(uid, function(){ - $rootScope.openModal('private-message',{controller:'MemberModalCtrl'}); - }); + $scope.quickReply = function (uid) { + Members.selectMember(uid) + .then(function (response) { + $rootScope.openModal('private-message', {controller: 'MemberModalCtrl'}); + }); } }]); diff --git a/website/public/js/controllers/guildsCtrl.js b/website/public/js/controllers/guildsCtrl.js index 70493071c0..dfedbddc7c 100644 --- a/website/public/js/controllers/guildsCtrl.js +++ b/website/public/js/controllers/guildsCtrl.js @@ -17,7 +17,6 @@ habitrpg.controller("GuildsCtrl", ['$scope', 'Groups', 'User', 'Challenges', '$r $scope.groups.public = guilds; }); - $scope.type = 'guild'; $scope.text = window.env.t('guild'); diff --git a/website/public/js/controllers/memberModalCtrl.js b/website/public/js/controllers/memberModalCtrl.js index 54f0bb054a..ed501a5574 100644 --- a/website/public/js/controllers/memberModalCtrl.js +++ b/website/public/js/controllers/memberModalCtrl.js @@ -20,16 +20,17 @@ habitrpg }); $scope.sendPrivateMessage = function(uuid, message){ - // Don't do anything if the user somehow gets here without a message. if (!message) return; - $http.post('/api/v2/members/'+uuid+'/message',{message:message}).success(function(){ - Notification.text(window.env.t('messageSentAlert')); - $rootScope.User.sync(); - $scope.$close(); - }); + Members.sendPrivateMessage(message, uuid) + .then(function (response) { + Notification.text(window.env.t('messageSentAlert')); + $rootScope.User.sync(); + $scope.$close(); + }); }; + //@TODO: We don't send subscriptions so the structure has changed in the back. Update this when we update the views. $scope.gift = { type: 'gems', gems: {amount:0, fromBalance:true}, @@ -37,12 +38,13 @@ habitrpg message:'' }; - $scope.sendGift = function(uuid, gift){ - $http.post('/api/v2/members/'+uuid+'/gift', gift).success(function(){ - Notification.text('Gift sent!') - $rootScope.User.sync(); - $scope.$close(); - }) + $scope.sendGift = function (uuid, gift) { + Members.transferGems(message, uuid, $scope.gift.gems.amount) + .then(function (response) { + Notification.text('Gift sent!') + $rootScope.User.sync(); + $scope.$close(); + }); }; $scope.reportAbuse = function(reporter, message, groupId) { diff --git a/website/public/js/services/groupServices.js b/website/public/js/services/groupServices.js index e208b5bbdf..bff834582a 100644 --- a/website/public/js/services/groupServices.js +++ b/website/public/js/services/groupServices.js @@ -76,7 +76,7 @@ angular.module('habitrpg') Group.removeMember = function(gid, memberId, message) { return $http({ method: "POST", - url: groupApiURLPrefix + gid + '/removeMember/' + memberId, + url: groupApiURLPrefix + '/' + gid + '/removeMember/' + memberId, data: { message: message, }, diff --git a/website/public/js/services/memberServices.js b/website/public/js/services/memberServices.js index 4146a4ea1f..66dd4d2de5 100644 --- a/website/public/js/services/memberServices.js +++ b/website/public/js/services/memberServices.js @@ -1,49 +1,105 @@ 'use strict'; -(function(){ - angular - .module('habitrpg') - .factory('Members', membersFactory); - membersFactory.$inject = [ - '$rootScope', - 'Shared', - 'ApiUrl', - '$resource' - ]; - - function membersFactory($rootScope, Shared, ApiUrl, $resource) { +angular.module('habitrpg') +.factory('Members', [ '$rootScope', 'Shared', 'ApiUrl', '$resource', '$http', '$q', + function($rootScope, Shared, ApiUrl, $resource, $http, $q) { var members = {}; - var fetchMember = $resource(ApiUrl.get() + '/api/v2/members/:uid', { uid: '@_id' }).get; + var selectedMember = {}; + var apiV3Prefix = '/api/v3'; - function selectMember(uid, cb) { + function fetchMember (memberId) { + return $http({ + method: 'GET', + url: apiV3Prefix + '/members/' + memberId, + }); + } + //@TODO: Add paging + function getGroupMembers (groupId) { + return $http({ + method: 'GET', + url: apiV3Prefix + '/groups/' + groupId + '/members', + }); + } + + function getGroupInvites (groupId) { + return $http({ + method: 'GET', + url: apiV3Prefix + '/groups/' + groupId + '/invites', + }); + } + + function getChallengeMembers (challengeId) { + return $http({ + method: 'GET', + url: apiV3Prefix + '/challenges/' + challengeId + '/members', + }); + } + + function getChallengeMemberProgress (challengeId, memberId) { + return $http({ + method: 'GET', + url: apiV3Prefix + '/challenges/' + challengeId + '/members/' + memberId, + }); + } + + function sendPrivateMessage (message, toUserId) { + return $http({ + method: 'POST', + url: apiV3Prefix + '/members/send-private-message', + data: { + message: message, + toUserId: toUserId, + } + }); + } + + function transferGems (message, toUserId, gemAmount) { + return $http({ + method: 'POST', + url: apiV3Prefix + '/members/send-private-message', + data: { + message: message, + toUserId: toUserId, + gemAmount: gemAmount, + } + }); + } + + function selectMember (uid) { var self = this; + var deferred = $q.defer(); var memberIsReady = _checkIfMemberIsReady(members[uid]); if (memberIsReady) { - _prepareMember(self, members[uid], cb); + _prepareMember(members[uid], self); + deferred.resolve(); } else { - fetchMember({ uid: uid }, function(member) { - addToMembersList(member); // lazy load for later - _prepareMember(self, member, cb); - }); + fetchMember(uid) + .then(function (response) { + var member = response.data.data; + addToMembersList(member, self); // lazy load for later + _prepareMember(member, self); + deferred.resolve(); + }); } + + return deferred.promise; } - function addToMembersList(member){ + function addToMembersList (member, self) { if (member._id) { - members[member._id] = member; + self.members[member._id] = member; } } - function _checkIfMemberIsReady(member) { + function _checkIfMemberIsReady (member) { return member && member.items && member.items.weapon; } - function _prepareMember(self, member, cb) { + function _prepareMember(member, self) { Shared.wrap(member, false); - self.selectedMember = members[member._id]; - cb(); + self.selectedMember = self.members[member._id]; } $rootScope.$on('userUpdated', function(event, user){ @@ -54,7 +110,13 @@ members: members, addToMembersList: addToMembersList, selectedMember: undefined, - selectMember: selectMember + selectMember: selectMember, + fetchMember: fetchMember, + getGroupMembers: getGroupMembers, + getGroupInvites: getGroupInvites, + getChallengeMembers: getChallengeMembers, + getChallengeMemberProgress: getChallengeMemberProgress, + sendPrivateMessage: sendPrivateMessage, + transferGems: transferGems, } - } -}()); + }]);