Api v3 fixes continued (#7205)

* Added timzeone offset back

* Added APIToken back to settings page

* Fixed fetch recent messages for party

* Fixed returning group description

* Fixed check if user is member of challenge

* Fixed party members appearing in header

* Updated get myGroups param to include public groups. Fixed isMemberOf group

* Fixed hourglass purchase

* Fixed challenge addding tasks on first creating

* Updated tests to accomidate new changes
This commit is contained in:
Keith Holliday
2016-05-13 16:36:25 -05:00
committed by Matteo Pagliazzi
parent cc20812674
commit 1fd7df7521
12 changed files with 72 additions and 49 deletions

View File

@@ -1,7 +1,7 @@
'use strict'; 'use strict';
describe('Challenges Controller', function() { describe('Challenges Controller', function() {
var rootScope, scope, user, User, ctrl, groups, members, notification, state, challenges; var rootScope, scope, user, User, ctrl, groups, members, notification, state, challenges, tasks;
beforeEach(function() { beforeEach(function() {
module(function($provide) { module(function($provide) {
@@ -14,7 +14,7 @@ describe('Challenges Controller', function() {
$provide.value('User', User); $provide.value('User', User);
}); });
inject(function($rootScope, $controller, _$state_, _Groups_, _Members_, _Notification_, _Challenges_){ inject(function($rootScope, $controller, _$state_, _Groups_, _Members_, _Notification_, _Challenges_, _Tasks_){
scope = $rootScope.$new(); scope = $rootScope.$new();
rootScope = $rootScope; rootScope = $rootScope;
@@ -24,6 +24,7 @@ describe('Challenges Controller', function() {
ctrl = $controller('ChallengesCtrl', {$scope: scope, User: User}); ctrl = $controller('ChallengesCtrl', {$scope: scope, User: User});
challenges = _Challenges_; challenges = _Challenges_;
tasks = _Tasks_;
groups = _Groups_; groups = _Groups_;
members = _Members_; members = _Members_;
notification = _Notification_; notification = _Notification_;
@@ -320,13 +321,17 @@ describe('Challenges Controller', function() {
context('challenge owner interactions', function() { context('challenge owner interactions', function() {
describe("save challenge", function() { describe("save challenge", function() {
var alert, createChallengeSpy, challengeResponse; var alert, createChallengeSpy, challengeResponse, taskChallengeCreateSpy;
beforeEach(function(){ beforeEach(function(){
alert = sandbox.stub(window, "alert"); alert = sandbox.stub(window, "alert");
createChallengeSpy = sinon.stub(challenges, 'createChallenge'); createChallengeSpy = sinon.stub(challenges, 'createChallenge');
challengeResponse = {data: {data: {_id: 'new-challenge'}}}; challengeResponse = {data: {data: {_id: 'new-challenge'}}};
createChallengeSpy.returns(Promise.resolve(challengeResponse)); createChallengeSpy.returns(Promise.resolve(challengeResponse));
taskChallengeCreateSpy = sinon.stub(tasks, 'createChallengeTasks');
var taskResponse = {data: {data: []}};
taskChallengeCreateSpy.returns(Promise.resolve(taskResponse));
}); });
it("opens an alert box if challenge.group is not specified", function() { it("opens an alert box if challenge.group is not specified", function() {

View File

@@ -33,7 +33,10 @@ describe('groupServices', function() {
}); });
it('calls party endpoint', function() { it('calls party endpoint', function() {
$httpBackend.expectGET(groupApiUrlPrefix + '/party').respond({}); var groupId = '1234';
var groupResponse = {data: {_id: groupId}};
$httpBackend.expectGET(groupApiUrlPrefix + '/party').respond(groupResponse);
$httpBackend.expectGET('/api/v3/groups/' + groupId + '/members?includeAllPublicFields=true').respond({});
groups.Group.syncParty(); groups.Group.syncParty();
$httpBackend.flush(); $httpBackend.flush();
}); });
@@ -74,7 +77,10 @@ describe('groupServices', function() {
}); });
it('calls party endpoint when party is not cached', function() { it('calls party endpoint when party is not cached', function() {
$httpBackend.expectGET(groupApiUrlPrefix + '/party').respond({}); var groupId = '1234';
var groupResponse = {data: {_id: groupId}};
$httpBackend.expectGET(groupApiUrlPrefix + '/party').respond(groupResponse);
$httpBackend.expectGET('/api/v3/groups/' + groupId + '/members?includeAllPublicFields=true').respond({});
groups.party(); groups.party();
$httpBackend.flush(); $httpBackend.flush();
}); });
@@ -136,7 +142,7 @@ describe('groupServices', function() {
}); });
it('calls my guilds endpoint', function() { it('calls my guilds endpoint', function() {
$httpBackend.expectGET(groupApiUrlPrefix + '?type=privateGuilds').respond([]); $httpBackend.expectGET(groupApiUrlPrefix + '?type=guilds').respond([]);
groups.myGuilds(); groups.myGuilds();
$httpBackend.flush(); $httpBackend.flush();
}); });

View File

@@ -348,6 +348,7 @@ describe('Quests Service', function() {
fakeBackend.when('GET', 'partials/main.html').respond({}); fakeBackend.when('GET', 'partials/main.html').respond({});
fakeBackend.when('GET', 'partials/main.html').respond({}); fakeBackend.when('GET', 'partials/main.html').respond({});
fakeBackend.when('GET', '/api/v3/groups/party').respond(partyResponse); fakeBackend.when('GET', '/api/v3/groups/party').respond(partyResponse);
fakeBackend.when('GET', '/api/v3/groups/party-id/members?includeAllPublicFields=true').respond({});
fakeBackend.when('POST', '/api/v3/groups/party-id/quests/invite/' + key).respond({quest: { key: 'whale' } }); fakeBackend.when('POST', '/api/v3/groups/party-id/quests/invite/' + key).respond({quest: { key: 'whale' } });
fakeBackend.flush(); fakeBackend.flush();
})); }));

View File

@@ -30,6 +30,10 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User',
}); });
}; };
$scope.isUserMemberOf = function (challenge) {
return User.user.challenges.indexOf(challenge._id) !== -1;
}
$scope.editTask = Tasks.editTask; $scope.editTask = Tasks.editTask;
/** /**
@@ -124,21 +128,25 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User',
} }
if (isNew) { if (isNew) {
var _challenge;
Challenges.createChallenge(challenge) Challenges.createChallenge(challenge)
.then(function (response) { .then(function (response) {
var _challenge = response.data.data; _challenge = response.data.data;
Notification.text(window.env.t('challengeCreated')); Notification.text(window.env.t('challengeCreated'));
User.sync(); User.sync();
var challengeTasks = [];
challengeTasks = challengeTasks.concat(challenge.todos);
challengeTasks = challengeTasks.concat(challenge.habits);
challengeTasks = challengeTasks.concat(challenge.dailys);
challengeTasks = challengeTasks.concat(challenge.rewards);
return Tasks.createChallengeTasks(_challenge._id, challengeTasks);
})
.then(function (response) {
$state.transitionTo('options.social.challenges.detail', { cid: _challenge._id }, { $state.transitionTo('options.social.challenges.detail', { cid: _challenge._id }, {
reload: true, inherit: false, notify: true reload: true, inherit: false, notify: true
}); });
var challengeTasks = [];
challengeTasks.concat(challenge.todos);
challengeTasks.concat(challenge.habits);
challengeTasks.concat(challenge.dailys);
challengeTasks.concat(challenge.reqards);
Tasks.createChallengeTasks(_challenge._id, challengeTasks);
}); });
} else { } else {
Challenges.updateChallenge(challenge._id, challenge) Challenges.updateChallenge(challenge._id, challenge)
@@ -169,6 +177,7 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User',
challenge.winner = undefined; challenge.winner = undefined;
}; };
//@TODO: change to $scope.remove
$scope["delete"] = function(challenge) { $scope["delete"] = function(challenge) {
var warningMsg; var warningMsg;
@@ -232,7 +241,8 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User',
//------------------------------------------------------------ //------------------------------------------------------------
$scope.addTask = function(addTo, listDef, challenge) { $scope.addTask = function(addTo, listDef, challenge) {
var task = Shared.taskDefaults({text: listDef.newTask, type: listDef.type}); var task = Shared.taskDefaults({text: listDef.newTask, type: listDef.type});
Tasks.createChallengeTasks(challenge._id, task); //If the challenge has not been created, we bulk add tasks on save
if (challenge._id) Tasks.createChallengeTasks(challenge._id, task);
if (!challenge[task.type + 's']) challenge[task.type + 's'] = []; if (!challenge[task.type + 's']) challenge[task.type + 's'] = [];
challenge[task.type + 's'].unshift(task); challenge[task.type + 's'].unshift(task);
delete listDef.newTask; delete listDef.newTask;

View File

@@ -63,7 +63,7 @@ habitrpg.controller('ChatCtrl', ['$scope', 'Groups', 'Chat', 'User', '$http', 'A
} }
} }
$scope.likeChatMessage = function(group,message) { $scope.likeChatMessage = function(group, message) {
if (message.uuid == User.user._id) if (message.uuid == User.user._id)
return Notification.text(window.env.t('foreverAlone')); return Notification.text(window.env.t('foreverAlone'));
@@ -114,14 +114,13 @@ habitrpg.controller('ChatCtrl', ['$scope', 'Groups', 'Chat', 'User', '$http', 'A
}); });
}; };
$scope.sync = function(group){ $scope.sync = function(group) {
if(group.type == 'party') { //@TODO: We need to use chat service here
group.$syncParty(); // Syncs the whole party, not just 15 members Groups.Group.get(group._id)
} else { .then(function (response) {
group.$get(); $scope.group = response.data.data;
} })
// When the user clicks fetch recent messages we need to update
// that the user has seen the new messages
Chat.markChatSeen(group._id); Chat.markChatSeen(group._id);
} }

View File

@@ -1,8 +1,8 @@
'use strict'; 'use strict';
angular.module('habitrpg') angular.module('habitrpg')
.factory('Groups', [ '$location', '$rootScope', '$http', 'Analytics', 'ApiUrl', 'Challenges', '$q', 'User', .factory('Groups', [ '$location', '$rootScope', '$http', 'Analytics', 'ApiUrl', 'Challenges', '$q', 'User', 'Members',
function($location, $rootScope, $http, Analytics, ApiUrl, Challenges, $q, User) { function($location, $rootScope, $http, Analytics, ApiUrl, Challenges, $q, User, Members) {
var data = {party: undefined, myGuilds: undefined, publicGuilds: undefined, tavern: undefined }; var data = {party: undefined, myGuilds: undefined, publicGuilds: undefined, tavern: undefined };
var groupApiURLPrefix = "/api/v3/groups"; var groupApiURLPrefix = "/api/v3/groups";
@@ -117,7 +117,11 @@ angular.module('habitrpg')
Group.get('party') Group.get('party')
.then(function (response) { .then(function (response) {
data.party = response.data.data; data.party = response.data.data;
Members.getGroupMembers(data.party._id, true)
.then(function (response) {
data.party.members = response.data.data;
_cachedPartyPromise.resolve(data.party); _cachedPartyPromise.resolve(data.party);
});
}, function (response) { }, function (response) {
data.party = { type: 'party' }; data.party = { type: 'party' };
_cachedPartyPromise.reject(data.party); _cachedPartyPromise.reject(data.party);
@@ -154,7 +158,7 @@ angular.module('habitrpg')
var deferred = $q.defer(); var deferred = $q.defer();
if (!data.myGuilds) { if (!data.myGuilds) {
Group.getGroups('privateGuilds') Group.getGroups('guilds')
.then(function (response) { .then(function (response) {
data.myGuilds = response.data.data; data.myGuilds = response.data.data;
deferred.resolve(data.myGuilds); deferred.resolve(data.myGuilds);

View File

@@ -15,10 +15,16 @@ angular.module('habitrpg')
} }
//@TODO: Add paging //@TODO: Add paging
function getGroupMembers (groupId) { function getGroupMembers (groupId, includeAllPublicFields) {
var url = apiV3Prefix + '/groups/' + groupId + '/members';
if (includeAllPublicFields) {
url += '?includeAllPublicFields=true';
}
return $http({ return $http({
method: 'GET', method: 'GET',
url: apiV3Prefix + '/groups/' + groupId + '/members', url: url,
}); });
} }

View File

@@ -322,7 +322,7 @@ angular.module('habitrpg')
hourglassPurchase: function (data) { hourglassPurchase: function (data) {
var type = data.params.type; var type = data.params.type;
var key = data.params.key; var key = data.params.key;
callOpsFunctionAndRequest('hourglassPurchase', 'purchase-hourglass', "POST", type + '/' + key, data); callOpsFunctionAndRequest('purchaseHourglass', 'purchase-hourglass', "POST", type + '/' + key, data);
}, },
unlock: function (data) { unlock: function (data) {
@@ -403,17 +403,10 @@ angular.module('habitrpg')
settings.online = true; settings.online = true;
save(); save();
sync().then(function () { sync().then(function () {
if (cb) { if (user.preferences.timezoneOffset !== offset)
cb(); userServices.set({'preferences.timezoneOffset': offset});
} if (cb) cb();
}); });
//@TODO: Do we need the timezone set?
// userServices.log({}, function(){
// // If they don't have timezone, set it
// if (user.preferences.timezoneOffset !== offset)
// userServices.set({'preferences.timezoneOffset': offset});
// cb && cb();
// });
} else { } else {
alert('Please enter your ID and Token in settings.') alert('Please enter your ID and Token in settings.')
} }

View File

@@ -96,7 +96,7 @@ api.getGroups = {
if (validationErrors) throw validationErrors; if (validationErrors) throw validationErrors;
let types = req.query.type.split(','); let types = req.query.type.split(',');
let groupFields = basicGroupFields.concat('description memberCount balance'); let groupFields = basicGroupFields.concat(' description memberCount balance');
let sort = '-memberCount'; let sort = '-memberCount';
let results = await Group.getGroups({user, types, groupFields, sort}); let results = await Group.getGroups({user, types, groupFields, sort});

View File

@@ -229,7 +229,7 @@ script(type='text/ng-template', id='partials/options.settings.api.html')
h6=env.t('userId') h6=env.t('userId')
pre.prettyprint {{user.id}} pre.prettyprint {{user.id}}
h6=env.t('APIToken') h6=env.t('APIToken')
pre.prettyprint {{user.apiToken}} pre.prettyprint {{User.settings.auth.apiToken}}
h6=env.t('qrCode') h6=env.t('qrCode')
img.img-rendering-auto(src='https://chart.googleapis.com/chart?cht=qr&chs=200x200&chl=%7B%22address%22%3A%22https%3A%2F%2Fhabitrpg.com%22%2C%22user%22%3A%22{{user.id}}%22%2C%22key%22%3A%22{{user.apiToken}}%22%7D&choe=UTF-8&chld=L', alt='qrcode') img.img-rendering-auto(src='https://chart.googleapis.com/chart?cht=qr&chs=200x200&chl=%7B%22address%22%3A%22https%3A%2F%2Fhabitrpg.com%22%2C%22user%22%3A%22{{user.id}}%22%2C%22key%22%3A%22{{user.apiToken}}%22%7D&choe=UTF-8&chld=L', alt='qrcode')
br br
@@ -405,4 +405,3 @@ script(id='partials/options.settings.subscription.html',type='text/ng-template')
.col-xs-4 .col-xs-4
a.purchase(ng-click="Payments.amazonPayments.init({type: 'subscription', subscription:_subscription.key, coupon:_subscription.coupon})") a.purchase(ng-click="Payments.amazonPayments.init({type: 'subscription', subscription:_subscription.key, coupon:_subscription.coupon})")
img(src='https://payments.amazon.com/gp/cba/button',alt=env.t('amazonPayments')) img(src='https://payments.amazon.com/gp/cba/button',alt=env.t('amazonPayments'))

View File

@@ -199,10 +199,10 @@ script(type='text/ng-template', id='partials/options.social.challenges.html')
p!=env.t('prizeValue', {gemcount: "{{challenge.prize}}", gemicon: "<span class='inline-block Pet_Currency_Gem1x'></span>"}) p!=env.t('prizeValue', {gemcount: "{{challenge.prize}}", gemicon: "<span class='inline-block Pet_Currency_Gem1x'></span>"})
li.bg-transparent li.bg-transparent
// leave / join // leave / join
a.btn.btn-sm.btn-danger(ng-show='challenge._isMember', ng-click='clickLeave(challenge, $event)') a.btn.btn-sm.btn-danger(ng-show='::isUserMemberOf(challenge)', ng-click='clickLeave(challenge, $event)')
span.glyphicon.glyphicon-ban-circle span.glyphicon.glyphicon-ban-circle
=env.t('leave') =env.t('leave')
a.btn.btn-sm.btn-success(ng-hide='challenge._isMember', ng-click='join(challenge)') a.btn.btn-sm.btn-success(ng-hide='::isUserMemberOf(challenge)', ng-click='join(challenge)')
span.glyphicon.glyphicon-ok span.glyphicon.glyphicon-ok
=env.t('join') =env.t('join')
a.accordion-toggle(id="{{challenge._id}}" ng-click='toggle(challenge._id)') a.accordion-toggle(id="{{challenge._id}}" ng-click='toggle(challenge._id)')

View File

@@ -45,10 +45,10 @@ script(type='text/ng-template', id='partials/options.social.guilds.public.html')
li='{{::group.memberCount}} ' + env.t('members') li='{{::group.memberCount}} ' + env.t('members')
// join / leave // join / leave
li.bg-transparent li.bg-transparent
a.btn.btn-sm.btn-danger(ng-if="::group._isMember", ng-click='clickLeave(group, $event)') a.btn.btn-sm.btn-danger(ng-if="::isMemberOfGroup(User.user._id, group)", ng-click='clickLeave(group, $event)')
span.glyphicon.glyphicon-ban-circle span.glyphicon.glyphicon-ban-circle
=env.t('leave') =env.t('leave')
a.btn.btn-sm.btn-success(ng-if="::!group._isMember", ng-click='join(group)') a.btn.btn-sm.btn-success(ng-if="::!isMemberOfGroup(User.user._id, group)", ng-click='join(group)')
span.glyphicon.glyphicon-ok span.glyphicon.glyphicon-ok
=env.t('join') =env.t('join')
h4: a(href='/#/options/groups/guilds/{{::group._id}}') {{::group.name}} h4: a(href='/#/options/groups/guilds/{{::group._id}}') {{::group.name}}