mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-13 20:57:24 +01:00
* shared model for chat and inbox * disable inbox schema * inbox: use separate model * remove old code that used group.chat * add back chat field (not used) and remove old tests * remove inbox exclusions when loading user * add GET /api/v3/inbox/messages * add comment * implement DELETE /inbox/messages/:messageid in v4 * implement GET /inbox/messages in v4 and update tests * implement DELETE /api/v4/inbox/clear * fix url * fix doc * update /export/inbox.html * update other data exports * add back messages in user schema * add user.toJSONWithInbox * add compativility until migration is done * more compatibility * fix tojson called twice * add compatibility methods * fix common tests * fix v4 integration tests * v3 get user -> with inbox * start to fix tests * fix v3 integration tests * wip * wip, client use new route * update tests for members/send-private-message * tests for get user in v4 * add tests for DELETE /inbox/messages/:messageId * add tests for DELETE /inbox/clear in v4 * update docs * fix tests * initial migration * fix migration * fix migration * migration fixes * migrate api.enterCouponCode * migrate api.castSpell * migrate reset, reroll, rebirth * add routes to v4 version * fix tests * fixes * api.updateUser * remove .only * get user -> userLib * refactor inbox.vue to work with new data model * fix return message when messaging yourself * wip fix bug with new conversation * wip * fix remaining ui issues * move api.registerLocal, fixes * keep only v3 version of GET /inbox/messages
201 lines
7.1 KiB
JavaScript
201 lines
7.1 KiB
JavaScript
import {
|
|
createAndPopulateGroup,
|
|
translate as t,
|
|
generateUser,
|
|
sleep,
|
|
} from '../../../../helpers/api-integration/v3';
|
|
import { v4 as generateUUID } from 'uuid';
|
|
import { chatModel as Chat } from '../../../../../website/server/models/message';
|
|
|
|
describe('POST /groups/:groupId/quests/reject', () => {
|
|
let questingGroup;
|
|
let partyMembers;
|
|
let user;
|
|
let leader;
|
|
|
|
const PET_QUEST = 'whale';
|
|
|
|
beforeEach(async () => {
|
|
let { group, groupLeader, members } = await createAndPopulateGroup({
|
|
groupDetails: { type: 'party', privacy: 'private' },
|
|
members: 2,
|
|
});
|
|
|
|
questingGroup = group;
|
|
leader = groupLeader;
|
|
partyMembers = members;
|
|
|
|
await leader.update({
|
|
[`items.quests.${PET_QUEST}`]: 1,
|
|
});
|
|
user = await generateUser();
|
|
});
|
|
|
|
context('failure conditions', () => {
|
|
it('returns an error when group is not found', async () => {
|
|
await expect(partyMembers[0].post(`/groups/${generateUUID()}/quests/reject`))
|
|
.to.eventually.be.rejected.and.eql({
|
|
code: 404,
|
|
error: 'NotFound',
|
|
message: t('groupNotFound'),
|
|
});
|
|
});
|
|
|
|
it('does not accept quest for a group in which user is not a member', async () => {
|
|
await expect(user.post(`/groups/${questingGroup._id}/quests/accept`))
|
|
.to.eventually.be.rejected.and.eql({
|
|
code: 404,
|
|
error: 'NotFound',
|
|
message: t('groupNotFound'),
|
|
});
|
|
});
|
|
|
|
it('returns an error when group is a guild', async () => {
|
|
let { group: guild, groupLeader: guildLeader } = await createAndPopulateGroup({
|
|
groupDetails: { type: 'guild', privacy: 'private' },
|
|
});
|
|
|
|
await expect(guildLeader.post(`/groups/${guild._id}/quests/reject`))
|
|
.to.eventually.be.rejected.and.eql({
|
|
code: 401,
|
|
error: 'NotAuthorized',
|
|
message: t('guildQuestsNotSupported'),
|
|
});
|
|
});
|
|
|
|
it('returns an error when group is not on a quest', async () => {
|
|
await expect(partyMembers[0].post(`/groups/${questingGroup._id}/quests/reject`))
|
|
.to.eventually.be.rejected.and.eql({
|
|
code: 404,
|
|
error: 'NotFound',
|
|
message: t('questInvitationDoesNotExist'),
|
|
});
|
|
});
|
|
|
|
it('return an error when a user rejects an invite twice', async () => {
|
|
await leader.post(`/groups/${questingGroup._id}/quests/invite/${PET_QUEST}`);
|
|
await partyMembers[0].post(`/groups/${questingGroup._id}/quests/reject`);
|
|
|
|
await expect(partyMembers[0].post(`/groups/${questingGroup._id}/quests/reject`))
|
|
.to.eventually.be.rejected.and.eql({
|
|
code: 400,
|
|
error: 'BadRequest',
|
|
message: t('questAlreadyRejected'),
|
|
});
|
|
});
|
|
|
|
it('clears the user rsvp needed if the request fails because the request is invalid', async () => {
|
|
await leader.post(`/groups/${questingGroup._id}/quests/invite/${PET_QUEST}`);
|
|
await partyMembers[0].post(`/groups/${questingGroup._id}/quests/reject`);
|
|
|
|
await expect(partyMembers[0].post(`/groups/${questingGroup._id}/quests/reject`))
|
|
.to.eventually.be.rejected.and.eql({
|
|
code: 400,
|
|
error: 'BadRequest',
|
|
message: t('questAlreadyRejected'),
|
|
});
|
|
|
|
await partyMembers[0].sync();
|
|
expect(partyMembers[0].party.quest.RSVPNeeded).to.be.false;
|
|
});
|
|
|
|
it('return an error when a user rejects an invite already accepted', async () => {
|
|
await leader.post(`/groups/${questingGroup._id}/quests/invite/${PET_QUEST}`);
|
|
await partyMembers[0].post(`/groups/${questingGroup._id}/quests/accept`);
|
|
|
|
await expect(partyMembers[0].post(`/groups/${questingGroup._id}/quests/reject`))
|
|
.to.eventually.be.rejected.and.eql({
|
|
code: 400,
|
|
error: 'BadRequest',
|
|
message: t('questAlreadyAccepted'),
|
|
});
|
|
});
|
|
|
|
it('does not reject invite for a quest already underway', async () => {
|
|
await leader.post(`/groups/${questingGroup._id}/quests/invite/${PET_QUEST}`);
|
|
await partyMembers[0].post(`/groups/${questingGroup._id}/quests/accept`);
|
|
// quest will start after everyone has accepted
|
|
await partyMembers[1].post(`/groups/${questingGroup._id}/quests/accept`);
|
|
|
|
await expect(partyMembers[0].post(`/groups/${questingGroup._id}/quests/reject`))
|
|
.to.eventually.be.rejected.and.eql({
|
|
code: 401,
|
|
error: 'NotAuthorized',
|
|
message: t('questAlreadyUnderway'),
|
|
});
|
|
});
|
|
});
|
|
|
|
context('successfully quest rejection', () => {
|
|
let cleanUserQuestObj = {
|
|
key: null,
|
|
progress: {
|
|
up: 0,
|
|
down: 0,
|
|
collect: {},
|
|
collectedItems: 0,
|
|
},
|
|
completed: null,
|
|
RSVPNeeded: false,
|
|
};
|
|
|
|
it('rejects a quest invitation', async () => {
|
|
await leader.post(`/groups/${questingGroup._id}/quests/invite/${PET_QUEST}`);
|
|
|
|
let res = await partyMembers[0].post(`/groups/${questingGroup._id}/quests/reject`);
|
|
await partyMembers[0].sync();
|
|
await questingGroup.sync();
|
|
|
|
expect(partyMembers[0].party.quest).to.eql(cleanUserQuestObj);
|
|
expect(questingGroup.quest.members[partyMembers[0]._id]).to.be.false;
|
|
expect(questingGroup.quest.active).to.be.false;
|
|
expect(res).to.eql(questingGroup.quest);
|
|
});
|
|
|
|
it('starts the quest when the last user reject', async () => {
|
|
await leader.post(`/groups/${questingGroup._id}/quests/invite/${PET_QUEST}`);
|
|
await partyMembers[0].post(`/groups/${questingGroup._id}/quests/accept`);
|
|
await partyMembers[1].post(`/groups/${questingGroup._id}/quests/reject`);
|
|
await questingGroup.sync();
|
|
|
|
expect(questingGroup.quest.active).to.be.true;
|
|
});
|
|
|
|
it('cleans up user quest data for non-quest members when last member rejects', async () => {
|
|
let rejectingMember = partyMembers[1];
|
|
|
|
await leader.post(`/groups/${questingGroup._id}/quests/invite/${PET_QUEST}`);
|
|
await partyMembers[0].post(`/groups/${questingGroup._id}/quests/accept`);
|
|
// quest will start after everyone has accepted or rejected
|
|
await rejectingMember.post(`/groups/${questingGroup._id}/quests/reject`);
|
|
|
|
await sleep(0.5);
|
|
|
|
await questingGroup.sync();
|
|
|
|
expect(questingGroup.quest.active).to.be.true;
|
|
|
|
await rejectingMember.sync();
|
|
|
|
expect(rejectingMember.party.quest.RSVPNeeded).to.eql(false);
|
|
expect(rejectingMember.party.quest.key).to.not.exist;
|
|
expect(rejectingMember.party.quest.completed).to.not.exist;
|
|
});
|
|
|
|
it('starts the quest when the last user reject and verifies chat', async () => {
|
|
await leader.post(`/groups/${questingGroup._id}/quests/invite/${PET_QUEST}`);
|
|
await partyMembers[0].post(`/groups/${questingGroup._id}/quests/accept`);
|
|
await partyMembers[1].post(`/groups/${questingGroup._id}/quests/reject`);
|
|
|
|
const groupChat = await Chat.find({ groupId: questingGroup._id }).exec();
|
|
|
|
expect(groupChat[0].text).to.exist;
|
|
expect(groupChat[0]._meta).to.exist;
|
|
expect(groupChat[0]._meta).to.have.all.keys(['participatingMembers']);
|
|
|
|
let returnedGroup = await leader.get(`/groups/${questingGroup._id}`);
|
|
expect(returnedGroup.chat[0]._meta).to.be.undefined;
|
|
});
|
|
});
|
|
});
|