Add route for leaving active quest

This commit is contained in:
Blade Barringer
2015-08-23 20:29:57 -05:00
parent 6955add15d
commit 0b7e43f156
4 changed files with 182 additions and 1 deletions

View File

@@ -129,7 +129,7 @@ describe "Party", ->
group = undefined group = undefined
participating = [] participating = []
notParticipating = [] notParticipating = []
before (done) -> beforeEach (done) ->
# Tavern boss, side-by-side # Tavern boss, side-by-side
Group.update( Group.update(
_id: "habitrpg" _id: "habitrpg"
@@ -310,6 +310,20 @@ describe "Party", ->
expect(_.size(res.body.quest.members)).to.equal 3 expect(_.size(res.body.quest.members)).to.equal 3
done() done()
it "allows quest participants to leave quest", (done) ->
leavingMember = party[1]
expect(group.quest.members[leavingMember._id]).to.eql(true)
request.post(baseURL + "/groups/" + group._id + "/questLeave")
.set("X-API-User", leavingMember._id)
.set("X-API-Key", leavingMember.apiToken)
.end (err, res) ->
expectCode res, 201
request.get(baseURL + '/groups/party')
.end (err, res) ->
expect(res.body.quest.members[leavingMember._id]).to.not.be.ok
done()
xit "Hurts the boss", (done) -> xit "Hurts the boss", (done) ->
request.post(baseURL + "/user/batch-update").end (res) -> request.post(baseURL + "/user/batch-update").end (res) ->
user = res.body user = res.body

View File

@@ -0,0 +1,133 @@
var sinon = require('sinon');
var chai = require("chai")
chai.use(require("sinon-chai"))
var expect = chai.expect
var groupsController = require('../../../website/src/controllers/groups');
describe('Groups Controller', function() {
describe('#questLeave', function() {
var res, req, group, user, saveSpy;
beforeEach(function() {
sinon.stub(process, 'nextTick').yields();
group = {
_id: 'group-id',
type: 'party',
quest: {
leader : 'another-user',
active: true,
members: {
'user-id': true,
'another-user': true
},
key : 'vice1',
progress : {
hp : 364,
collect : {}
}
},
save: sinon.stub().yields(),
markModified: sinon.spy()
};
user = {
_id: 'user-id',
party : {
quest : {
key : 'vice1',
progress : {
up : 50,
down : 0,
collect : {}
},
completed : null,
RSVPNeeded : false
}
}
};
res = {
locals: {
group: group,
user: user
},
json: sinon.stub(),
send: sinon.stub()
};
req = { };
});
afterEach(function () {
process.nextTick.restore();
});
context('error conditions', function() {
it('errors if quest is not active', function() {
group.quest.active = false;
groupsController.questLeave(req, res);
expect(res.json).to.be.calledOnce;
expect(res.json).to.be.calledWith(
404,
{ err: 'No active quest to leave' }
);
});
it('errors if user is not part of quest', function() {
delete group.quest.members[user._id];
groupsController.questLeave(req, res);
expect(res.json).to.be.calledOnce;
expect(res.json).to.be.calledWith(
403,
{ err: 'You are not part of the quest' }
);
});
it('does not allow quest leader to leave quest', function() {
group.quest.leader = 'user-id';
groupsController.questLeave(req, res);
expect(res.json).to.be.calledOnce;
expect(res.json).to.be.calledWith(
403,
{ err: 'Quest leader cannot leave quest' }
);
});
it('sends 500 if group cannot save', function() {
group.save = sinon.stub().yields('save error');
var nextSpy = sinon.spy();
groupsController.questLeave(req, res, nextSpy);
expect(nextSpy).to.be.calledOnce;
expect(nextSpy).to.be.calledWith('save error');
});
});
context('success', function() {
it('removes user from quest', function() {
expect(group.quest.members[user._id]).to.exist;
groupsController.questLeave(req, res);
expect(group.quest.members[user._id]).to.not.exist;
});
it('sends back 201 on success', function() {
groupsController.questLeave(req, res);
expect(res.send).to.be.calledOnce;
expect(res.send).to.be.calledWith(201);
});
});
});
});

View File

@@ -1072,3 +1072,29 @@ api.questAbort = function(req, res, next){
group = null; group = null;
}) })
} }
api.questLeave = function(req, res, next) {
// Non-member leave quest while still in progress
var group = res.locals.group;
var user = res.locals.user;
if (!(group.quest && group.quest.active)) {
return res.json(404, { err: 'No active quest to leave' });
}
if (!(group.quest.members && group.quest.members[user._id])) {
return res.json(403, { err: 'You are not part of the quest' });
}
if (group.quest.leader === user._id) {
return res.json(403, { err: 'Quest leader cannot leave quest' });
}
delete group.quest.members[user._id];
group.markModified('quest.members');
group.save(function(err, result) {
if (err) return next(err);
res.send(201);
});
}

View File

@@ -527,6 +527,14 @@ module.exports = (swagger, v2) ->
middleware: [auth.auth, i18n.getUserLanguage, groups.attachGroup] middleware: [auth.auth, i18n.getUserLanguage, groups.attachGroup]
action: groups.questAbort action: groups.questAbort
"/groups/{gid}/questLeave":
spec:
method: 'POST'
description: 'Leave an active quest (Quest leaders cannot leave active quests. They must abort the quest to leave)'
parameters: [path('gid','Group to leave quest in','string')]
middleware: [auth.auth, i18n.getUserLanguage, groups.attachGroup]
action: groups.questLeave
#TODO PUT /groups/:gid/chat/:messageId #TODO PUT /groups/:gid/chat/:messageId
"/groups/{gid}/chat:GET": "/groups/{gid}/chat:GET":