mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-16 06:07:21 +01:00
* move groups/sidebar to groupSidebar.vue * lint files * extract group/party sidebar to rightSidebar.vue * wip stories with example data * update stories - wip sidebar re-styling * message party / group leader + move items to the menu * update paddings /place for quest section * invite to party / guild * update labels (* Party / Guild ) * guild-background to group-background * correct menu order + missing a label based on the group type * no quest - styles / layout applied * quest owner / not started - styles applied + extracted questActions from questDetailsModal.vue to a mixin * no challenge style * hover with underlines * quest-pending area layout / margins * "Collection Quest/Quest Owner Participating" Styling Done * group sidebar menu with icons / background * remove most participate button styles * fix quest-invite panel * move "Start Quest" + add "Leave Quest" * Not Participating + Boss + Rage Quests restyling * party quest changes - invitedToQuest + button styles + no-items style + view details * fix icons + rage value + colors * fix duplicate key * hide items label if 0 items found + hide pending damage if there is none + sidebar section margin + fix percent calculation 0 => 0% * combine quest abandon / cancel to one call + hide begin if quest has already started + close modal if quest was canceled * remove unused translate string * allow leaving an accepted but inactive quest + disable leave when user is quest leader * update "are you sure" questions - remove "doubleSureAbort" - add "sureLeaveInactive" * sidebar margins + menu icon color * refactored css rules * improve some styles * fix button spacing * fix dropmenu with icon hover * hide leave quest for leaders + fix quest buttons spacing * add pending items label * remove "X items found" label * first round of fixes * last v-once * Update Quest Dialogs (#13112) * new quest rewards panel + extract questPopover and itemWithLabel * WIP: questInfo still not applying the row-height.. * split up start-quest-modal into select and detail modal - also rename the current quest-details to be the group-quest-details modal * remove start-quest-modal from modal-scss * update package-lock * WIP before using the quest sidebar branch as a base * move quest detail actions to the "new" details dialog * quest details layout for owner / participant * fix quest rewards - open details modal from sidebar * apply quest-details dialog styles to the buyQuestModal one * fix quest reward icons / popover / texts * WIP back to quest selection * fix lint * merge selectQuestModal.vue with questDetailModal.vue + UI for the select quest * fix margins / layout / labels * fix quest detail + wip invitationListModal.vue / participantListModal.vue * fix questmodal user label centered * fix centered reward items + grouping items and adding a count-badge * sort quests by AZ or quantity * invitations modal * remove console.info * complete participantListModal.vue + extracted getClassName * missed a file for getClassName extraction * fix invitations * select the actual quest on details * fix margins on invite to party / start quest buttons * replace buyQuestModal close button and title * fix recursion due to the same name * missing import * sort quantity by highest first * fix "Can't find a Quest to start" styles * fix "your balance" padding * fix quest collections / drop items * fix member details in participants list * fix quest info * remove nullable because the build doesn't like it (on this file..) * add questCompleted to the stories + fix getDropName * replace quest-rewards in questCompleted.vue * fix questCompleted.vue style * delete obsolete components * add missing spritesheets to storebook * requested pr changes * refactored fetchMember * revert optional chaining * fix merge conflicts * fix rightSidebar hover colors - $scss var to css var * overflow auto instead of scroll * prevent wrapping of quest collections * rollback to multi line quest items * use min-width for the quest popover
136 lines
4.3 KiB
JavaScript
136 lines
4.3 KiB
JavaScript
import { v4 as generateUUID } from 'uuid';
|
|
import {
|
|
createAndPopulateGroup,
|
|
translate as t,
|
|
generateUser,
|
|
} from '../../../../helpers/api-integration/v3';
|
|
|
|
describe('POST /groups/:groupId/quests/leave', () => {
|
|
let questingGroup;
|
|
let partyMembers;
|
|
let user;
|
|
let leader;
|
|
|
|
const PET_QUEST = 'whale';
|
|
|
|
beforeEach(async () => {
|
|
const { 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/leave`))
|
|
.to.eventually.be.rejected.and.eql({
|
|
code: 404,
|
|
error: 'NotFound',
|
|
message: t('groupNotFound'),
|
|
});
|
|
});
|
|
|
|
it('returns an error for a group in which user is not a member', async () => {
|
|
await expect(user.post(`/groups/${questingGroup._id}/quests/leave`))
|
|
.to.eventually.be.rejected.and.eql({
|
|
code: 404,
|
|
error: 'NotFound',
|
|
message: t('groupNotFound'),
|
|
});
|
|
});
|
|
|
|
it('returns an error when group is a guild', async () => {
|
|
const { group: guild, groupLeader: guildLeader } = await createAndPopulateGroup({
|
|
groupDetails: { type: 'guild', privacy: 'private' },
|
|
});
|
|
|
|
await expect(guildLeader.post(`/groups/${guild._id}/quests/leave`))
|
|
.to.eventually.be.rejected.and.eql({
|
|
code: 401,
|
|
error: 'NotAuthorized',
|
|
message: t('guildQuestsNotSupported'),
|
|
});
|
|
});
|
|
|
|
it('returns an error when quest leader attempts to leave', 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/accept`);
|
|
|
|
await expect(leader.post(`/groups/${questingGroup._id}/quests/leave`))
|
|
.to.eventually.be.rejected.and.eql({
|
|
code: 401,
|
|
error: 'NotAuthorized',
|
|
message: t('questLeaderCannotLeaveQuest'),
|
|
});
|
|
});
|
|
|
|
it('returns an error when non quest member attempts to leave', 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 expect(partyMembers[1].post(`/groups/${questingGroup._id}/quests/leave`))
|
|
.to.eventually.be.rejected.and.eql({
|
|
code: 401,
|
|
error: 'NotAuthorized',
|
|
message: t('notPartOfQuest'),
|
|
});
|
|
});
|
|
});
|
|
|
|
async function letPartyMemberLeaveAndCheckChanges (partyMember) {
|
|
const leaveResult = await partyMember.post(`/groups/${questingGroup._id}/quests/leave`);
|
|
await Promise.all([
|
|
partyMember.sync(),
|
|
questingGroup.sync(),
|
|
]);
|
|
|
|
expect(partyMember.party.quest).to.eql({
|
|
key: null,
|
|
progress: {
|
|
up: 0,
|
|
down: 0,
|
|
collect: {},
|
|
collectedItems: 0,
|
|
},
|
|
completed: null,
|
|
RSVPNeeded: false,
|
|
});
|
|
expect(questingGroup.quest).to.deep.equal(leaveResult);
|
|
expect(questingGroup.quest.members[partyMember._id]).to.be.false;
|
|
}
|
|
|
|
it('leaves an active quest', 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/accept`);
|
|
|
|
await questingGroup.sync();
|
|
|
|
expect(questingGroup.quest.active).to.eql(true);
|
|
|
|
await letPartyMemberLeaveAndCheckChanges(partyMembers[0]);
|
|
});
|
|
|
|
it('leaves an inactive quest ', async () => {
|
|
await leader.post(`/groups/${questingGroup._id}/quests/invite/${PET_QUEST}`);
|
|
await partyMembers[0].post(`/groups/${questingGroup._id}/quests/accept`);
|
|
|
|
await questingGroup.sync();
|
|
|
|
expect(questingGroup.quest.active).to.eql(false);
|
|
|
|
await letPartyMemberLeaveAndCheckChanges(partyMembers[0]);
|
|
});
|
|
});
|