mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-18 07:07:35 +01:00
* Fixed more tests * Added tags into user service * Added api-v3 auth urls * v3: fix package.json * v3: fix package.json * Fixed auth tests. Updated Authctrl response * v3: remove newrelic config file in favour of env variables * v3: upgrade some deps * switch from Q to Bluebird * v3 fix tests with deferred * Removed extra consoles.log. Changed data.data to res.data * v3 fix tests and use coroutines instead of regenerator * v3: fix tests * v3: do not await a non promise * v3: q -> bluebird * Changed id param for registration response * Updated party query and create * Ensured login callback happens after user sync * Add challenges to groups. Fixed isMemberOfGuild check * Updated party and group tests * Fixed cron test * return user.id and send analytics event before changing page * fix trailing spaces * disable redirects * Api v3 party tavern fixes (#7191) * Added check if user is in party before query * Cached party query. Prevented party request when user is not in party. Updated Party create with no invites * Update tavern ctrl to use new promise * v3: misc fixes * Api v3 task fixes (#7193) * Update task view to use _id * Added try catch to user service ops calls * v3 client: saving after syncing is complete * Fixed test broken by part sync change (#7195) * v3: fix todo scoring and try to fix production testing problem * revert changes to mongoose config * mongoose: increase keepAlive * test mongoose fix * fix: Only apply captureStackTrace if it exists on the error object * v3: fix reminders with no startDate * mongoose: use options * chore(): rename website/src -> website/server and website/public -> website/client (#7199) * v3 fix GET /groups: return an error only if an invalid type is supplied not when there are 0 results (#7203) * [API v3] Fix calls to user.ops and deleting tags (#7204) * v3: fixes calls to user.ops from views and deleting tags * v3: fix tests that use user._statsComputed * 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 * fix: Correct checklist on client Closes #7207 * fix: Pin eslint to 2.9 * minor improvements to cron code for clarity; fix inaccurate comments; add TODOs for rest-in-inn actions * fix: Add missing type param to equip call closes #7212 * rename and reword pubChalsMinPrize to reflect that it's only for Tavern challenges * allows players to send gems to each other; other minor related changes - fixes https://github.com/HabitRPG/habitrpg/issues/7227 * fix tests for /members/transfer-gems * fix: Set gems sent notification as translatable string * chore: Remove unusued variable * fix: Remove requirement on message paramter in transfer-gems * add a missing variable declaration * chore: clarify comments on cron code * fix: Correct client request from habitrpg -> tavern * update apidoc URL in package.json Closes #7222 * Fixed start party by invites * Updated spell casting to v3 * Fixed adding and removing tags on tasks * Fixed page reload on settings change * Fixed battle monsters with friends button * Loaded completed todos when done is clicked * chore: Reinstate floating version number for eslint babel-eslint regression fixed * Fixed reload tests * change "an user" to "a user" in comments and text (no code changes) (#7257) * fix: Alert user that drops were recieved * remove userServices.js from karma.conf - it's been moved to website/client/js/services * feat: Create debug update user route * fix: Correct set cron debug function * feat: Add make admin button to debug menu * lint: Add missing semicolons in test * fix: Temporarilly comment out udpate user debug route * v3: fix _tmp for crit and streakBonus * v3: execute all actions when leaving a solo party * v3 client: fix group not found when leaving party * v3 migration: fix challenge prize * v3 cron: only save modified tasks * v3: add CHALLENGE_TASK_NOT_FOUND to valid broken reasons * v3: fix tasks chart * v3 client: fix ability to leave challenge * v3 client: fix filtering by tag and correctly show tag tooltip * v3 common: fix tags tests * v3 client: support unlinking not found challenges tasks * v3: disable Bluebird warning for missing return, fixes #7269 * feat: Separate out update-user into set-cron and make-admin debug routes * chore: Disable make admin debug route for v3 prod testing * v3: misc fixes * v3: misc fixes * v3: fix adding multiple tasks * Fixed join/leave button updates * Queried only user groups to be available when creating challenges * Fixed bulk add tasks to challenge * Synced challenge tasks after leave and join. * Fixed default selected group * Fixed challenge member info. Fixed challenge winner selection * Fixed deleting challenge tasks * Fixed particiapting filter * v3 client: fix casting spells * v3: do not log sensitive data * v3: always save user when casting spell * v3: always save user when casting spell * v3: more fixes for spells * fix typos and missing information in apidocs - fixes https://github.com/HabitRPG/habitrpg/issues/7277 (#7282) * v3: add TODO for client side spells * feat: Add modify inventory debug menu * Fixed viewing user progress on challenge * Updated tests * fix: Fix quest progress button * fix incorrect Armoire test; remove unneeded param details from apidocs; disambiguate health potion * v3: fix stealth casting * v3: fix tasks saving and selection for rebirth reroll and reset (server-only) * v3: fix auto allocation * v3 client: misc fixes * rename buyPotion and buy-potion to buyHealthPotion and buy-health-potion; fix apidoc param error * Added delete for saved challenge task * Fixed member modal on front page * adjust text in apidocs for errors / clarity / consistency / standard terminology (no code changes) (#7298) * fix bug in Rebirth test, add new tests, adjust apidocs (#7293) * Updated task model to allow setting streak (#7306) * fix: Correct missing * in apidoc comments * Api v3 challenge fixes (#7287) * Fixed join/leave button updates * Queried only user groups to be available when creating challenges * Fixed bulk add tasks to challenge * Synced challenge tasks after leave and join. * Fixed default selected group * Fixed challenge member info. Fixed challenge winner selection * Fixed deleting challenge tasks * Fixed particiapting filter * Fixed viewing user progress on challenge * Updated tests * Added delete for saved challenge task * v3: fix sorting * [API v3] add CRON_SAFE_MODE (#7286) * add CRON_SAFE_MODE to example config file, fix some bugs, add an unrelated low-priority TODO * create CRON_SAFE_MODE to disable parts of cron for use after extended outage - fixes https://github.com/HabitRPG/habitrpg/issues/7161 * fix a bug with CRON_SAFE_MODE, remove duplicated code, remove completed TODO comment * fix check for CRON_SAFE_MODE * v3 client: fix typo * adjust debug menu Modify Inventory: hungrier pets, fewer Special items, "Hide" buttons * completed To-Dos: return the 30 most recent instead of 30 oldest (#7318) * v3 migration: fix createdAt date * adjust locales text, key names, and files for Rebirth, Reset, and Fortify / ReRoll for consistency with existing strings (#7321) * v3: fix unlinking multiple tasks * v3 fix releasing pets * v3: fix authenticating with apiUrl * v3: fix typo * v3 fix client tests for unlinking * v3 client: do not show start quest button when quest is active * v3 client: fix ability to send cards * v3 client: fix misc challenge issues * v3: fix notifications * v3 client: more user friendly errors * v3 client: only load completed todos once * v3 client: fix tests * v3: move TAVERN_ID to common code * fix: Provide default type and text for new task creation in score route * fix: Provide default history [] for habit in score route * fix: Add _legacyId prop to tasks to support non-uuid identifiers * chore: Change v3 migration to use _legacyId instead of legacyId * fix: check for _legacyId in tasks if id does not exist * refactor: Extract out finding task by id or _legacyId into a function * Api v3 party quest fixes (#7341) * Fix display of add challenge message when group challenges are empty * Fixed forced quest start to update quest without reload * Fixed needing to reload when accepting party invite * Fix group leave and join reload * Fixed leave current party and join another * Updated party tests * v3 client: remove console.log statement * v3: misc fixes * v3 client: fix predicatbale random * v3: info about API v3 * v3: update footer with links to developer resources * v3: support party invitation from email * v3 client: fix chat flagging * fix: Correct get tasks route to properly get todos (#7349) * move locales strings from api-v3.json to other locales files (#7347) * move locales strings from api-v3.json: authentication strings -> front.json * move locales strings from api-v3.json: authentication strings -> tasks.json * move locales strings from api-v3.json: authentication strings -> groups.json * move locales strings from api-v3.json: authentication strings -> challenge.json * move locales strings from api-v3.json: authentication strings -> groups.json (again) * move locales strings from api-v3.json: authentication strings -> quests.json * move locales strings from api-v3.json: authentication strings -> subscriber.json * move locales strings from api-v3.json: authentication strings -> spells.json * move locales strings from api-v3.json: authentication strings -> character.json * move locales strings from api-v3.json: authentication strings -> groups.json (PMs) * move locales strings from api-v3.json: authentication strings -> npc.json * move locales strings from api-v3.json: authentication strings -> pets.json * move locales strings from api-v3.json: authentication strings -> miscellaneous * move locales strings from api-v3.json: authentication strings -> contrib.json and settings.json * move locales strings from api-v3.json: delete unused string (invalidTasksOwner), delete api-v3.json, whitespace cleanup * v3 client: fix sticky header * v3: remove unused code * v3 client: correctly redirect after inviting * Removed v2 calls from views (#7351) * v3: fix tests for challenge export * v3: fallbackto authWithHeaders if wuthWithSession or authWithUrl fails * Added force cache update when fetching new messages (#7360) * v3: fetch whole user when booting from group tto avoid issues with pre save hook expecting all data * v3: misc fixes for payments * v3: limit fields of challenge tasks that can be updated * fix(tests): never connect to NODE_DB_URI for tests * Added new route for setting last cron and updated front end * v3: fix iap url * v3: fix build and ios IAP * Changed route to user set custom day start * v3: iap accessible under /api/v3, fixes to spells and groups invitations * v3: correctly use v3 routes in client * remove XP, GP when unticking a Daily with a completed checklist - fixes https://github.com/HabitRPG/habitrpg/issues/7246 * use natural language for error message about skills on challenge tasks (#7336), fix other gramatical error * Updated ui when user rejects a guild invite (#7368) * feat: complete custom day start route Closes #7363 * fix: Correct spelling of healAll skill fix: Correct sprite name of healAll skill * fix: Change all instances of spookDust -> spookySparkles * add dateCreated to all tasks; add empty challenge object to tasks that don't have one (#7386) * add plumilla to artists for Tangle Tree in Bailey message * Fixed quest drop modal (#7377) * Fixed quest drop modal * Fixed broken party test * [API v3] Maintenance Mode (#7367) * WIP(maintenance): maintenance * WIP(maintenance): working locale features * fix(maintenance): don't translate info page target * WIP(maintenance): start adding info page * fix(maintenance): linting * feat: Add container to maintenance info page * fix(maintenance): add config.json edits Also DRY variables for main vs info pages * fix(maintenance): linting * refactor(maintenance): further slim down variables * refactor: Remove unnecessary variables * fix: Correct string interpolation in maintenace view * feat: Dynamically add time to maintenance pages * maintenance mode: do not connect to mongodb * fix(maintenance): clean up timezones etc. * fix(maintenance): remove unneeded sprite * Tavern party challenges invites fix (#7394) * Added challenges and invitations to party * Loaded tavern challenges * Updated group and quest services tests * v3: implement automatic syncing if user is not up to date * Removed unnecessary fields when updating groups and challenges (#7395) * v3: do not saved populated user * v3: correctly return user subset * Chained party promises together (#7396) * v3: $w -> splitWhitespace * use bluebird * use babel polyfill * migration: fix items * update links for v3 * Updated shortname validation to support multiple browsers * Docs changes (#7401) * chore: Clarify transfer-gems documentation * chore: Clarify api status route documentation * chore: Mark webhooks as BETA * Added tags update route. Added sort to user service (#7381) * Added tags update route. Added sort to user service * Change update tasks route to reorder tasks * Fixed linting issue * Changed params for reorder tags route * Fixed not found tag and added test * Added password confirmation when deleteing account (#7402) * fix production logging * feat(commit): push * empty commit * feat(maintenance): post-downtime news & awards (#7406) * fix exporting avatar * second attempt at fixing exporting avatar * fix production logging * s3: convert moment to date instance * fix avatar sharing and caching (30 minutes) * fix: Correct missing parameter Closes #7433 * fix: Validate challenge shortname on server * adjust text strings - fixes https://github.com/HabitRPG/habitrpg/issues/5631 and also Short Name -> Tag Name
497 lines
12 KiB
JavaScript
497 lines
12 KiB
JavaScript
var sinon = require('sinon');
|
|
var chai = require("chai");
|
|
chai.use(require("sinon-chai"));
|
|
var expect = chai.expect;
|
|
|
|
var Bluebird = require('bluebird');
|
|
var Group = require('../../../website/server/models/group').model;
|
|
var groupsController = require('../../../website/server/controllers/api-v2/groups');
|
|
|
|
describe('Groups Controller', function() {
|
|
var utils = require('../../../website/server/libs/api-v2/utils');
|
|
|
|
describe('#invite', function() {
|
|
var res, req, user, group;
|
|
|
|
beforeEach(function() {
|
|
group = {
|
|
_id: 'group-id',
|
|
name: 'group-name',
|
|
type: 'party',
|
|
members: [
|
|
'user-id',
|
|
'another-user'
|
|
],
|
|
save: sinon.stub().yields(),
|
|
markModified: sinon.spy()
|
|
};
|
|
|
|
user = {
|
|
_id: 'user-id',
|
|
name: 'inviter',
|
|
email: 'inviter@example.com',
|
|
save: sinon.stub().yields(),
|
|
markModified: sinon.spy()
|
|
};
|
|
|
|
res = {
|
|
locals: {
|
|
group: group,
|
|
user: user
|
|
},
|
|
json: sinon.stub(),
|
|
sendStatus: sinon.stub()
|
|
};
|
|
|
|
req = {
|
|
body: {}
|
|
};
|
|
});
|
|
|
|
context('uuids', function() {
|
|
beforeEach(function() {
|
|
req.body.uuids = ['invited-user'];
|
|
});
|
|
|
|
it('returns 400 if user not found');
|
|
|
|
it('returns a 400 if user is already in the group');
|
|
|
|
it('retuns 400 if user was already invited to that group');
|
|
|
|
it('returns 400 if user is already pending an invitation');
|
|
|
|
it('returns 400 is user is already in another party');
|
|
|
|
it('emails invited user');
|
|
|
|
it('does not email invited user if email preference is set to false');
|
|
});
|
|
|
|
context('emails', function() {
|
|
var EmailUnsubscription = require('../../../website/server/models/emailUnsubscription').model;
|
|
var execStub, selectStub;
|
|
|
|
beforeEach(function() {
|
|
sinon.stub(utils, 'encrypt').returns('http://link.com');
|
|
sinon.stub(utils, 'getUserInfo').returns({
|
|
name: user.name,
|
|
email: user.email
|
|
});
|
|
execStub = sinon.stub();
|
|
selectStub = sinon.stub().returns({
|
|
exec: execStub
|
|
});
|
|
sinon.stub(User, 'findOne').returns({
|
|
select: selectStub
|
|
});
|
|
sinon.stub(EmailUnsubscription, 'findOne');
|
|
sinon.stub(utils, 'txnEmail');
|
|
|
|
req.body.emails = [{email: 'user@example.com', name: 'user'}];
|
|
});
|
|
|
|
afterEach(function() {
|
|
User.findOne.restore();
|
|
EmailUnsubscription.findOne.restore();
|
|
utils.encrypt.restore();
|
|
utils.getUserInfo.restore();
|
|
utils.txnEmail.restore();
|
|
});
|
|
|
|
it('emails user with invite', function() {
|
|
execStub.yields(null, null);
|
|
EmailUnsubscription.findOne.yields(null, null);
|
|
|
|
groupsController.invite(req, res);
|
|
|
|
expect(utils.txnEmail).to.be.calledOnce;
|
|
expect(utils.txnEmail).to.be.calledWith(
|
|
{ email: 'user@example.com', name: 'user' },
|
|
'invite-friend',
|
|
[
|
|
{ name: 'LINK', content: '?partyInvite=http://link.com' },
|
|
{ name: 'INVITER', content: 'inviter' }
|
|
]
|
|
);
|
|
});
|
|
|
|
it('does not email user if user is on unsubscribe list', function() {
|
|
EmailUnsubscription.findOne.yields(null, {_id: 'on-list'});
|
|
|
|
expect(utils.txnEmail).to.not.be.called;
|
|
});
|
|
|
|
it('checks if a user with provided email already exists');
|
|
});
|
|
|
|
context('others', function() {
|
|
it ('returns a 400 error', function() {
|
|
groupsController.invite(req, res);
|
|
|
|
expect(res.json).to.be.calledOnce;
|
|
expect(res.json).to.be.calledWith(
|
|
400,
|
|
{ err: 'Can invite only by email or uuid' }
|
|
);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('#leave', function() {
|
|
var res, req, user, group;
|
|
|
|
beforeEach(function() {
|
|
group = {
|
|
_id: 'group-id',
|
|
type: 'party',
|
|
members: [
|
|
'user-id',
|
|
'another-user'
|
|
],
|
|
save: sinon.stub().yields(),
|
|
leave: sinon.stub().yields(),
|
|
markModified: sinon.spy()
|
|
};
|
|
|
|
user = {
|
|
_id: 'user-id',
|
|
save: sinon.stub().yields(),
|
|
markModified: sinon.spy()
|
|
};
|
|
|
|
res = {
|
|
locals: {
|
|
group: group,
|
|
user: user
|
|
},
|
|
json: sinon.stub(),
|
|
sendStatus: sinon.stub()
|
|
};
|
|
|
|
req = {
|
|
query: { keep: 'keep' }
|
|
};
|
|
});
|
|
|
|
context('party', function() {
|
|
beforeEach(function() {
|
|
group.type = 'party';
|
|
});
|
|
|
|
it('prevents user from leaving party if quest is active and part of the active members list', function() {
|
|
group.quest = {
|
|
active: true,
|
|
members: {
|
|
another_user: true,
|
|
yet_another_user: null,
|
|
'user-id': true
|
|
}
|
|
};
|
|
|
|
groupsController.leave(req, res);
|
|
|
|
expect(group.leave).to.not.be.called;
|
|
expect(res.json).to.be.calledOnce;
|
|
expect(res.json).to.be.calledWith(403, 'You cannot leave party during an active quest. Please leave the quest first.');
|
|
});
|
|
|
|
it('prevents quest leader from leaving a party if they have started a quest', function() {
|
|
group.quest = {
|
|
active: false,
|
|
leader: 'user-id'
|
|
};
|
|
|
|
groupsController.leave(req, res);
|
|
|
|
expect(group.leave).to.not.be.called;
|
|
expect(res.json).to.be.calledOnce;
|
|
expect(res.json).to.be.calledWith(403, 'You cannot leave your party when you have started a quest. Abort the quest first.');
|
|
});
|
|
|
|
it('leaves party if quest is not active', function() {
|
|
group.quest = {
|
|
active: false,
|
|
members: {
|
|
another_user: true,
|
|
yet_another_user: null,
|
|
'user-id': null
|
|
}
|
|
};
|
|
|
|
groupsController.leave(req, res);
|
|
|
|
expect(group.leave).to.be.calledOnce;
|
|
expect(res.json).to.not.be.called;
|
|
});
|
|
|
|
it('leaves party if quest is active, but user is not part of quest', function() {
|
|
group.quest = {
|
|
active: true,
|
|
members: {
|
|
another_user: true,
|
|
yet_another_user: null,
|
|
'user-id': null
|
|
}
|
|
};
|
|
|
|
groupsController.leave(req, res);
|
|
|
|
expect(group.leave).to.be.calledOnce;
|
|
expect(res.json).to.not.be.called;
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('#questLeave', function() {
|
|
var res, req, group, user, saveSpy;
|
|
|
|
beforeEach(function() {
|
|
sinon.stub(Q, 'all').returns({
|
|
done: sinon.stub().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
|
|
}
|
|
},
|
|
save: sinon.stub().yields(),
|
|
markModified: sinon.spy()
|
|
};
|
|
|
|
res = {
|
|
locals: {
|
|
group: group,
|
|
user: user
|
|
},
|
|
json: sinon.stub(),
|
|
sendStatus: sinon.stub()
|
|
};
|
|
|
|
req = { };
|
|
});
|
|
|
|
afterEach(function() {
|
|
Promise.all.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() {
|
|
Promise.all.returns({
|
|
done: sinon.stub().callsArgWith(1, {err: 'save error'})
|
|
});
|
|
var nextSpy = sinon.spy();
|
|
|
|
groupsController.questLeave(req, res, nextSpy);
|
|
|
|
expect(res.json).to.not.be.called;
|
|
expect(nextSpy).to.be.calledOnce;
|
|
expect(nextSpy).to.be.calledWith({err: '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('scrubs quest data from user', function() {
|
|
user.party.quest.progress = {
|
|
up: 100,
|
|
down: 32,
|
|
collect: {
|
|
foo: 12,
|
|
bar: 4
|
|
}
|
|
};
|
|
|
|
groupsController.questLeave(req, res);
|
|
|
|
expect(user.party.quest.key).to.not.exist;
|
|
expect(user.party.quest.progress).to.eql({
|
|
up: 0,
|
|
down: 0,
|
|
collect: {}
|
|
});
|
|
});
|
|
|
|
it('sends back 204 on success', function() {
|
|
groupsController.questLeave(req, res);
|
|
|
|
expect(res.sendStatus).to.be.calledOnce;
|
|
expect(res.sendStatus).to.be.calledWith(204);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('#removeMember', function() {
|
|
var req, res, group, user;
|
|
|
|
beforeEach(function() {
|
|
user = { _id: 'user-id' };
|
|
group = {
|
|
_id: 'group-id',
|
|
leader: 'user-id',
|
|
members: ['user-id', 'member-to-boot', 'another-user']
|
|
}
|
|
res = {
|
|
locals: {
|
|
user: user,
|
|
group: group
|
|
},
|
|
sendStatus: sinon.stub()
|
|
};
|
|
req = {
|
|
query: {
|
|
uuid: 'member-to-boot'
|
|
}
|
|
};
|
|
|
|
sinon.stub(Group, 'update');
|
|
sinon.stub(User, 'update');
|
|
sinon.stub(User, 'findById');
|
|
});
|
|
|
|
afterEach(function() {
|
|
Group.update.restore();
|
|
User.update.restore();
|
|
User.findById.restore();
|
|
});
|
|
|
|
context('quest behavior', function() {
|
|
it('removes quest from party if booted member was quest leader', function() {
|
|
group.quest = {
|
|
leader: 'member-to-boot',
|
|
active: true,
|
|
members: {
|
|
'user-id': true,
|
|
'leader-id': true,
|
|
'member-to-boot': true
|
|
},
|
|
key: 'whale'
|
|
}
|
|
|
|
groupsController.removeMember(req, res);
|
|
|
|
expect(Group.update).to.be.calledOnce;
|
|
expect(Group.update).to.be.calledWith(
|
|
{ _id: 'group-id'},
|
|
{
|
|
'$inc': { memberCount: -1 },
|
|
'$pull': { members: 'member-to-boot' },
|
|
'$set': { quest: {key: null, leader: null} }
|
|
}
|
|
);
|
|
});
|
|
|
|
it('returns quest scroll to booted member if booted member was leader of quest', function() {
|
|
Group.update.yields();
|
|
var bootedMember = {
|
|
_id: 'member-to-boot',
|
|
apiToken: 'api',
|
|
preferences: {
|
|
emailNotifications: {
|
|
kickedGroup: false
|
|
}
|
|
}
|
|
};
|
|
User.findById.yields(null, bootedMember);
|
|
User.update.returns({
|
|
exec: sinon.stub()
|
|
});
|
|
|
|
group.quest = {
|
|
leader: 'member-to-boot',
|
|
active: true,
|
|
members: {
|
|
'user-id': true,
|
|
'leader-id': true,
|
|
'member-to-boot': true
|
|
},
|
|
key: 'whale'
|
|
}
|
|
|
|
groupsController.removeMember(req, res);
|
|
|
|
expect(User.update).to.be.calledOnce;
|
|
expect(User.update).to.be.calledWith(
|
|
{ _id: 'member-to-boot', apiToken: 'api' },
|
|
{
|
|
'$unset': { 'newMessages.group-id': ''},
|
|
'$inc': { 'items.quests.whale': 1 }
|
|
}
|
|
);
|
|
});
|
|
});
|
|
});
|
|
});
|