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
This commit is contained in:
Keith Holliday
2016-04-30 02:54:25 -06:00
committed by Matteo Pagliazzi
parent 570d5c7fd9
commit 415418f30c
7 changed files with 196 additions and 70 deletions

View File

@@ -2,6 +2,7 @@
describe('memberServices', function() { describe('memberServices', function() {
var $httpBackend, members; var $httpBackend, members;
var apiV3Prefix = '/api/v3';
beforeEach(inject(function (_$httpBackend_, Members) { beforeEach(inject(function (_$httpBackend_, Members) {
$httpBackend = _$httpBackend_; $httpBackend = _$httpBackend_;
@@ -20,10 +21,51 @@ describe('memberServices', function() {
expect(members.selectedMember).to.be.undefined; 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() { describe('addToMembersList', function() {
it('adds member to members object', function() { it('adds member to members object', function() {
var member = { _id: 'user_id' }; var member = { _id: 'user_id' };
members.addToMembersList(member); members.addToMembersList(member, members);
expect(members.members).to.eql({ expect(members.members).to.eql({
user_id: { _id: 'user_id' } user_id: { _id: 'user_id' }
}); });
@@ -31,27 +73,37 @@ describe('memberServices', function() {
}); });
describe('selectMember', 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'; var uid = 'abc';
$httpBackend.expectGET('/api/v2/members/' + uid).respond({ _id: uid }); var memberResponse = {
members.selectMember(uid, function(){}); data: {_id: uid},
$httpBackend.flush(); }
$httpBackend.expectGET(apiV3Prefix + '/members/' + uid).respond(memberResponse);
members.selectMember(uid)
.then(function () {
expect(members.selectedMember._id).to.eql(uid); expect(members.selectedMember._id).to.eql(uid);
expect(members.members).to.have.property(uid); expect(members.members).to.have.property(uid);
done();
});
$httpBackend.flush();
}); });
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'; var uid = 'abc';
members.members = { members.members = {
abc: { _id: 'abc', items: {} } abc: { _id: 'abc', items: {} }
} }
$httpBackend.expectGET('/api/v2/members/' + uid).respond({ _id: uid }); var memberResponse = {
members.selectMember(uid, function(){}); data: {_id: uid},
$httpBackend.flush(); }
$httpBackend.expectGET(apiV3Prefix + '/members/' + uid).respond(memberResponse);
members.selectMember(uid)
.then(function () {
expect(members.selectedMember._id).to.eql(uid); expect(members.selectedMember._id).to.eql(uid);
expect(members.members).to.have.property(uid); expect(members.members).to.have.property(uid);
done();
});
$httpBackend.flush();
}); });
it('gets member from cache if member has a weapons object', function() { it('gets member from cache if member has a weapons object', function() {

View File

@@ -150,12 +150,20 @@ window.habitrpg = angular.module('habitrpg',
url: '/:gid', url: '/:gid',
templateUrl: 'partials/options.social.guilds.detail.html', templateUrl: 'partials/options.social.guilds.detail.html',
title: env.t('titleGuilds'), title: env.t('titleGuilds'),
controller: ['$scope', 'Groups', 'Chat', '$stateParams', controller: ['$scope', 'Groups', 'Chat', '$stateParams', 'Members',
function($scope, Groups, Chat, $stateParams){ function($scope, Groups, Chat, $stateParams, Members){
Groups.Group.get($stateParams.gid) Groups.Group.get($stateParams.gid)
.then(function (response) { .then(function (response) {
$scope.group = response.data.data; $scope.group = response.data.data;
Chat.markChatSeen($scope.group._id); 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;
});
}); });
}] }]
}) })

View File

@@ -2,7 +2,6 @@
habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '$http', '$q', 'User', 'Members', '$state', 'Notification', habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '$http', '$q', 'User', 'Members', '$state', 'Notification',
function($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) { $scope.isMemberOfPendingQuest = function (userid, group) {
if (!group.quest || !group.quest.members) return false; if (!group.quest || !group.quest.members) return false;
if (group.quest.active) return false; // quest is started, not pending 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.Members = Members;
$scope._editing = {group:false};
$scope._editing = {group: false};
$scope.groupCopy = {}; $scope.groupCopy = {};
$scope.editGroup = function (group) { $scope.editGroup = function (group) {
@@ -74,7 +74,7 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '
// ------ Modals ------ // ------ Modals ------
$scope.clickMember = function(uid, forceShow) { $scope.clickMember = function (uid, forceShow) {
if (User.user._id == uid && !forceShow) { if (User.user._id == uid && !forceShow) {
if ($state.is('tasks')) { if ($state.is('tasks')) {
$state.go('options.profile.avatar'); $state.go('options.profile.avatar');
@@ -84,13 +84,14 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '
} else { } else {
// We need the member information up top here, but then we pass it down to the modal controller // 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? // down below. Better way of handling this?
Members.selectMember(uid, function(){ Members.selectMember(uid)
$rootScope.openModal('member', {controller:'MemberModalCtrl', windowClass:'profile-modal', size:'lg'}); .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) // TODO find a better way to do this (share data with remove member modal)
$scope.removeMemberData = { $scope.removeMemberData = {
group: group, group: group,
@@ -100,7 +101,7 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '
$rootScope.openModal('remove-member', {scope: $scope}); $rootScope.openModal('remove-member', {scope: $scope});
}; };
$scope.confirmRemoveMember = function(confirm){ $scope.confirmRemoveMember = function (confirm) {
if (confirm) { if (confirm) {
Groups.Group.removeMember( Groups.Group.removeMember(
$scope.removeMemberData.group._id, $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') { if (group.type !== 'party' && group.type !== 'guild') {
return console.log('Invalid group type.') return console.log('Invalid group type.')
} }
$rootScope.openModal('invite-' + group.type, { $rootScope.openModal('invite-' + group.type, {
controller:'InviteToGroupCtrl', controller:'InviteToGroupCtrl',
resolve: { resolve: {
@@ -134,9 +136,10 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '
}); });
}; };
$scope.quickReply = function(uid) { $scope.quickReply = function (uid) {
Members.selectMember(uid, function(){ Members.selectMember(uid)
$rootScope.openModal('private-message',{controller:'MemberModalCtrl'}); .then(function (response) {
$rootScope.openModal('private-message', {controller: 'MemberModalCtrl'});
}); });
} }
}]); }]);

View File

@@ -17,7 +17,6 @@ habitrpg.controller("GuildsCtrl", ['$scope', 'Groups', 'User', 'Challenges', '$r
$scope.groups.public = guilds; $scope.groups.public = guilds;
}); });
$scope.type = 'guild'; $scope.type = 'guild';
$scope.text = window.env.t('guild'); $scope.text = window.env.t('guild');

View File

@@ -20,16 +20,17 @@ habitrpg
}); });
$scope.sendPrivateMessage = function(uuid, message){ $scope.sendPrivateMessage = function(uuid, message){
// Don't do anything if the user somehow gets here without a message.
if (!message) return; if (!message) return;
$http.post('/api/v2/members/'+uuid+'/message',{message:message}).success(function(){ Members.sendPrivateMessage(message, uuid)
.then(function (response) {
Notification.text(window.env.t('messageSentAlert')); Notification.text(window.env.t('messageSentAlert'));
$rootScope.User.sync(); $rootScope.User.sync();
$scope.$close(); $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 = { $scope.gift = {
type: 'gems', type: 'gems',
gems: {amount:0, fromBalance:true}, gems: {amount:0, fromBalance:true},
@@ -37,12 +38,13 @@ habitrpg
message:'' message:''
}; };
$scope.sendGift = function(uuid, gift){ $scope.sendGift = function (uuid, gift) {
$http.post('/api/v2/members/'+uuid+'/gift', gift).success(function(){ Members.transferGems(message, uuid, $scope.gift.gems.amount)
.then(function (response) {
Notification.text('Gift sent!') Notification.text('Gift sent!')
$rootScope.User.sync(); $rootScope.User.sync();
$scope.$close(); $scope.$close();
}) });
}; };
$scope.reportAbuse = function(reporter, message, groupId) { $scope.reportAbuse = function(reporter, message, groupId) {

View File

@@ -76,7 +76,7 @@ angular.module('habitrpg')
Group.removeMember = function(gid, memberId, message) { Group.removeMember = function(gid, memberId, message) {
return $http({ return $http({
method: "POST", method: "POST",
url: groupApiURLPrefix + gid + '/removeMember/' + memberId, url: groupApiURLPrefix + '/' + gid + '/removeMember/' + memberId,
data: { data: {
message: message, message: message,
}, },

View File

@@ -1,49 +1,105 @@
'use strict'; 'use strict';
(function(){
angular
.module('habitrpg')
.factory('Members', membersFactory);
membersFactory.$inject = [ angular.module('habitrpg')
'$rootScope', .factory('Members', [ '$rootScope', 'Shared', 'ApiUrl', '$resource', '$http', '$q',
'Shared', function($rootScope, Shared, ApiUrl, $resource, $http, $q) {
'ApiUrl',
'$resource'
];
function membersFactory($rootScope, Shared, ApiUrl, $resource) {
var members = {}; 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 self = this;
var deferred = $q.defer();
var memberIsReady = _checkIfMemberIsReady(members[uid]); var memberIsReady = _checkIfMemberIsReady(members[uid]);
if (memberIsReady) { if (memberIsReady) {
_prepareMember(self, members[uid], cb); _prepareMember(members[uid], self);
deferred.resolve();
} else { } else {
fetchMember({ uid: uid }, function(member) { fetchMember(uid)
addToMembersList(member); // lazy load for later .then(function (response) {
_prepareMember(self, member, cb); 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) { 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; return member && member.items && member.items.weapon;
} }
function _prepareMember(self, member, cb) { function _prepareMember(member, self) {
Shared.wrap(member, false); Shared.wrap(member, false);
self.selectedMember = members[member._id]; self.selectedMember = self.members[member._id];
cb();
} }
$rootScope.$on('userUpdated', function(event, user){ $rootScope.$on('userUpdated', function(event, user){
@@ -54,7 +110,13 @@
members: members, members: members,
addToMembersList: addToMembersList, addToMembersList: addToMembersList,
selectedMember: undefined, selectedMember: undefined,
selectMember: selectMember selectMember: selectMember,
fetchMember: fetchMember,
getGroupMembers: getGroupMembers,
getGroupInvites: getGroupInvites,
getChallengeMembers: getChallengeMembers,
getChallengeMemberProgress: getChallengeMemberProgress,
sendPrivateMessage: sendPrivateMessage,
transferGems: transferGems,
} }
} }]);
}());