mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-18 15:17:25 +01:00
Add route for leaving active quest
This commit is contained in:
@@ -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
|
||||||
|
|||||||
133
test/server_side/controllers/groups.test.js
Normal file
133
test/server_side/controllers/groups.test.js
Normal 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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -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":
|
||||||
|
|||||||
Reference in New Issue
Block a user