Add front end button to leave quest

This commit is contained in:
Blade Barringer
2015-08-23 22:38:55 -05:00
parent 0b7e43f156
commit bc24fa8130
9 changed files with 77 additions and 12 deletions

View File

@@ -37,6 +37,8 @@
"bossColl1": "To collect items, do your positive tasks. Quest items drop just like normal items; however, you won't see the drops until the next day, then everything you've found will be tallied up and contributed to the pile.", "bossColl1": "To collect items, do your positive tasks. Quest items drop just like normal items; however, you won't see the drops until the next day, then everything you've found will be tallied up and contributed to the pile.",
"bossColl2": "Only participants can collect items and share in the quest loot.", "bossColl2": "Only participants can collect items and share in the quest loot.",
"abort": "Abort", "abort": "Abort",
"leaveQuest": "Leave Quest",
"sureLeave": "Are you sure you want to leave the active quest? All your quest progress will be lost.",
"questOwner": "Quest Owner", "questOwner": "Quest Owner",
"questOwnerNotInPendingQuest": "The quest owner has left the quest and can no longer begin it. It is recommended that you cancel it now. The quest owner will retain possession of the quest scroll.", "questOwnerNotInPendingQuest": "The quest owner has left the quest and can no longer begin it. It is recommended that you cancel it now. The quest owner will retain possession of the quest scroll.",
"questOwnerNotInRunningQuest": "The quest owner has left the quest. You can abort the quest if you need to. You can also allow it to keep running and all remaining participants will receive the quest rewards when the quest finishes.", "questOwnerNotInRunningQuest": "The quest owner has left the quest. You can abort the quest if you need to. You can also allow it to keep running and all remaining participants will receive the quest rewards when the quest finishes.",

View File

@@ -54,8 +54,7 @@ describe('Groups Controller', function() {
group: group, group: group,
user: user user: user
}, },
json: sinon.stub(), json: sinon.stub()
send: sinon.stub()
}; };
req = { }; req = { };
@@ -125,8 +124,8 @@ describe('Groups Controller', function() {
it('sends back 201 on success', function() { it('sends back 201 on success', function() {
groupsController.questLeave(req, res); groupsController.questLeave(req, res);
expect(res.send).to.be.calledOnce; expect(res.json).to.be.calledOnce;
expect(res.send).to.be.calledWith(201); expect(res.json).to.be.calledWith(201);
}); });
}); });
}); });

View File

@@ -71,7 +71,7 @@ describe("Party Controller", function() {
cancelSpy.should.have.been.calledOnce; cancelSpy.should.have.been.calledOnce;
}); });
it('does not call Groups.questCancel when alert box is confirmed', function() { it('does not call Groups.questCancel when alert box is not confirmed', function() {
windowSpy = sandbox.stub(window, "confirm", function(){return false}); windowSpy = sandbox.stub(window, "confirm", function(){return false});
scope.questCancel(party); scope.questCancel(party);
@@ -128,6 +128,35 @@ describe("Party Controller", function() {
}); });
}); });
describe('#questLeave', function() {
var party, leaveSpy, windowSpy;
beforeEach(function() {
party = {};
sandbox.stub(rootScope, 'hardRedirect');
leaveSpy = sandbox.stub(groups, 'questLeave').returns({
then: sandbox.stub().yields()
});
});
it('calls Groups.questLeave when alert box is confirmed', function() {
windowSpy = sandbox.stub(window, "confirm").returns(true);
scope.questLeave(party);
windowSpy.should.have.been.calledOnce;
windowSpy.should.have.been.calledWith(window.env.t('sureLeave'));
leaveSpy.should.have.been.calledOnce;
});
it('does not call Groups.questLeave when alert box is not confirmed', function() {
windowSpy = sandbox.stub(window, "confirm").returns(false);
scope.questLeave(party);
windowSpy.should.have.been.calledOnce;
leaveSpy.should.not.have.been.calledOnce;
});
});
describe('clickStartQuest', function() { describe('clickStartQuest', function() {
beforeEach(function() { beforeEach(function() {
sandbox.stub(rootScope, 'openModal'); sandbox.stub(rootScope, 'openModal');

View File

@@ -53,7 +53,8 @@ describe('groupServices', function() {
$questAccept: successPromise, $questAccept: successPromise,
$questReject: successPromise, $questReject: successPromise,
$questCancel: successPromise, $questCancel: successPromise,
$questAbort: successPromise $questAbort: successPromise,
$questLeave: successPromise
} }
var failPromise = function() { var failPromise = function() {
@@ -68,7 +69,8 @@ describe('groupServices', function() {
$questAccept: failPromise, $questAccept: failPromise,
$questReject: failPromise, $questReject: failPromise,
$questCancel: failPromise, $questCancel: failPromise,
$questAbort: failPromise $questAbort: failPromise,
$questLeave: failPromise
} }
beforeEach(function() { beforeEach(function() {
@@ -135,5 +137,19 @@ describe('groupServices', function() {
console.log.should.have.been.calledWith('fail'); console.log.should.have.been.calledWith('fail');
}); });
}); });
describe('questLeave', function() {
it('syncs user if $questLeave succeeds', function() {
groups.questLeave(successParty);
user.sync.should.have.been.calledOnce;
console.log.should.not.have.been.called;
});
it('does not sync user if $questLeave fails', function() {
groups.questLeave(failParty);
user.sync.should.not.have.been.calledOnce;
console.log.should.have.been.calledWith('fail');
});
});
}); });
}); });

View File

@@ -114,6 +114,15 @@ habitrpg.controller("PartyCtrl", ['$rootScope','$scope','Groups','Chat','User','
Groups.questAbort(party); Groups.questAbort(party);
} }
$scope.questLeave = function(party){
if (!confirm(window.env.t('sureLeave'))) return;
Groups.questLeave(party)
.then(function() {
$rootScope.hardRedirect('/#/options/groups/party');
});
}
$scope.questAccept = function(party){ $scope.questAccept = function(party){
Groups.questAccept(party); Groups.questAccept(party);
}; };

View File

@@ -42,7 +42,8 @@
questAccept: {method: "POST", url: ApiUrl.get() + '/api/v2/groups/:gid/questAccept'}, questAccept: {method: "POST", url: ApiUrl.get() + '/api/v2/groups/:gid/questAccept'},
questReject: {method: "POST", url: ApiUrl.get() + '/api/v2/groups/:gid/questReject'}, questReject: {method: "POST", url: ApiUrl.get() + '/api/v2/groups/:gid/questReject'},
questCancel: {method: "POST", url: ApiUrl.get() + '/api/v2/groups/:gid/questCancel'}, questCancel: {method: "POST", url: ApiUrl.get() + '/api/v2/groups/:gid/questCancel'},
questAbort: {method: "POST", url: ApiUrl.get() + '/api/v2/groups/:gid/questAbort'} questAbort: {method: "POST", url: ApiUrl.get() + '/api/v2/groups/:gid/questAbort'},
questLeave: {method: "POST", url: ApiUrl.get() + '/api/v2/groups/:gid/questLeave'}
}); });
function _syncUser() { function _syncUser() {
@@ -98,6 +99,12 @@
.then(_syncUser, _logError); .then(_syncUser, _logError);
} }
function questLeave(party) {
Analytics.updateUser({'partyID':party.id,'partySize':party.memberCount});
return party.$questLeave()
.then(_syncUser, _logError);
}
function inviteOrStartParty(group) { function inviteOrStartParty(group) {
if (group.type === "party" || $location.$$path === "/options/groups/party") { if (group.type === "party" || $location.$$path === "/options/groups/party") {
group.type = 'party'; group.type = 'party';
@@ -121,6 +128,7 @@
questAccept: questAccept, questAccept: questAccept,
questReject: questReject, questReject: questReject,
questAbort: questAbort, questAbort: questAbort,
questLeave: questLeave,
questCancel: questCancel, questCancel: questCancel,
inviteOrStartParty: inviteOrStartParty, inviteOrStartParty: inviteOrStartParty,

View File

@@ -1095,6 +1095,6 @@ api.questLeave = function(req, res, next) {
group.save(function(err, result) { group.save(function(err, result) {
if (err) return next(err); if (err) return next(err);
res.send(201); return res.json(201, group);
}); });
} }

View File

@@ -71,8 +71,8 @@ a.pull-right.gem-wallet(ng-if='group.type!="party"', popover-trigger='mouseenter
button.pull-right.btn.btn-primary(ng-click="openInviteModal(group)")=env.t("inviteFriends") button.pull-right.btn.btn-primary(ng-click="openInviteModal(group)")=env.t("inviteFriends")
.panel-body.modal-fixed-height .panel-body.modal-fixed-height
h4(ng-show='group.memberCount === 1 && group.type === "party"')=env.t('partyEmpty') h4(ng-show='::group.memberCount === 1 && group.type === "party"')=env.t('partyEmpty')
table.table.table-striped(ng-show='group.memberCount > 1 || group.type !== "party"' bindonce='group') table.table.table-striped(ng-show='::group.memberCount > 1 || group.type !== "party"' bindonce='group')
tr(ng-repeat='member in group.members track by member._id') tr(ng-repeat='member in group.members track by member._id')
td.media td.media
// allow leaders to ban members // allow leaders to ban members

View File

@@ -20,5 +20,7 @@ div(ng-if='group.quest.active==true')
include ./ianQuestInfo include ./ianQuestInfo
unless tavern unless tavern
button.btn.btn-sm.btn-warning(ng-if=':: (group.quest.leader && group.quest.leader==user._id && isMemberOfGroup(group.quest.leader,group) && isMemberOfRunningQuest(group.quest.leader,group))', button.btn.btn-sm.btn-warning(ng-if=':: (group.quest.leader && group.quest.leader==user._id && isMemberOfRunningQuest(group.quest.leader,group))',
ng-click='questAbort(party)')=env.t('abort') ng-click='questAbort(party)')=env.t('abort')
button.btn.btn-sm.btn-warning(ng-if=':: (group.quest.leader && group.quest.leader!=user._id && isMemberOfRunningQuest(user._id,group))',
ng-click='questLeave(party)')=env.t('leaveQuest')