mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-18 07:07:35 +01:00
Challenge create tests
This commit is contained in:
295
test/api/v3/integration/challenges/POST-challenges.test.js
Normal file
295
test/api/v3/integration/challenges/POST-challenges.test.js
Normal file
@@ -0,0 +1,295 @@
|
||||
import {
|
||||
generateUser,
|
||||
createAndPopulateGroup,
|
||||
translate as t,
|
||||
} from '../../../../helpers/api-v3-integration.helper';
|
||||
import { v4 as generateUUID } from 'uuid';
|
||||
|
||||
describe('POST /challenges', () => {
|
||||
it('returns error when groupId is empty', async () => {
|
||||
let user = await generateUser();
|
||||
|
||||
await expect(user.post('/challenges')).to.eventually.be.rejected.and.eql({
|
||||
code: 400,
|
||||
error: 'BadRequest',
|
||||
message: t('invalidReqParams'),
|
||||
});
|
||||
});
|
||||
|
||||
it('returns error when groupId is not for a valid group', async () => {
|
||||
let user = await generateUser();
|
||||
|
||||
await expect(user.post(`/challenges`, {
|
||||
groupId: generateUUID(),
|
||||
})).to.eventually.be.rejected.and.eql({
|
||||
code: 404,
|
||||
error: 'NotFound',
|
||||
message: t('groupNotFound'),
|
||||
});
|
||||
});
|
||||
|
||||
it('returns error when creating a challenge in the tavern with no prize', async () => {
|
||||
let user = await generateUser();
|
||||
|
||||
await expect(user.post(`/challenges`, {
|
||||
groupId: 'habitrpg',
|
||||
prize: 0,
|
||||
})).to.eventually.be.rejected.and.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
message: t('pubChalsMinPrize'),
|
||||
});
|
||||
});
|
||||
|
||||
it('returns error when creating a challenge in a public guild and you are not a member of it', async () => {
|
||||
let user = await generateUser();
|
||||
let { group } = await createAndPopulateGroup({
|
||||
groupDetails: {
|
||||
type: 'guild',
|
||||
privacy: 'public',
|
||||
},
|
||||
});
|
||||
|
||||
await expect(user.post(`/challenges`, {
|
||||
groupId: group._id,
|
||||
prize: 4,
|
||||
})).to.eventually.be.rejected.and.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
message: t('mustBeGroupMember'),
|
||||
});
|
||||
});
|
||||
|
||||
context('Creating a challenge for a valid group', () => {
|
||||
let groupLeader;
|
||||
let group;
|
||||
let groupMember;
|
||||
|
||||
beforeEach(async () => {
|
||||
let populatedGroup = await createAndPopulateGroup({
|
||||
members: 1,
|
||||
leaderDetails: {
|
||||
balance: 3,
|
||||
},
|
||||
groupDetails: {
|
||||
type: 'guild',
|
||||
leaderOnly: {
|
||||
challenges: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
groupLeader = await populatedGroup.groupLeader.sync();
|
||||
group = populatedGroup.group;
|
||||
groupMember = populatedGroup.members[0];
|
||||
});
|
||||
|
||||
it('returns an error when non-leader member creates a challenge in leaderOnly group', async () => {
|
||||
await expect(groupMember.post(`/challenges`, {
|
||||
groupId: group._id,
|
||||
})).to.eventually.be.rejected.and.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
message: t('onlyGroupLeaderChal'),
|
||||
});
|
||||
});
|
||||
|
||||
it('returns an error when non-leader member creates a challenge in leaderOnly group', async () => {
|
||||
await expect(groupMember.post(`/challenges`, {
|
||||
groupId: group._id,
|
||||
})).to.eventually.be.rejected.and.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
message: t('onlyGroupLeaderChal'),
|
||||
});
|
||||
});
|
||||
|
||||
it('allows non-leader member to create a challenge', async () => {
|
||||
let populatedGroup = await createAndPopulateGroup({
|
||||
members: 1,
|
||||
});
|
||||
|
||||
group = populatedGroup.group;
|
||||
groupMember = populatedGroup.members[0];
|
||||
|
||||
await expect(groupMember.post(`/challenges`, {
|
||||
groupId: group._id,
|
||||
name: 'Test Challenge',
|
||||
shortName: 'TC',
|
||||
})).to.eventually.have.property('leader', groupMember._id);
|
||||
});
|
||||
|
||||
it('doesn\'t take gems from user or group when challenge has no prize', async () => {
|
||||
let oldUserBalance = groupLeader.balance;
|
||||
let oldGroupBalance = group.balance;
|
||||
|
||||
await groupLeader.post(`/challenges`, {
|
||||
groupId: group._id,
|
||||
name: 'Test Challenge',
|
||||
shortName: 'TC',
|
||||
prize: 0,
|
||||
});
|
||||
|
||||
await expect(groupLeader.sync()).to.eventually.have.property('balance', oldUserBalance);
|
||||
await expect(group.sync()).to.eventually.have.property('balance', oldGroupBalance);
|
||||
});
|
||||
|
||||
it('returns error when user and group can\'t pay prize', async () => {
|
||||
await expect(groupLeader.post(`/challenges`, {
|
||||
groupId: group._id,
|
||||
name: 'Test Challenge',
|
||||
shortName: 'TC',
|
||||
prize: 20,
|
||||
})).to.eventually.be.rejected.and.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
message: t('cantAfford'),
|
||||
});
|
||||
});
|
||||
|
||||
it('takes prize out of group if it has sufficient funds', async () => {
|
||||
let oldUserBalance = groupLeader.balance;
|
||||
let oldGroupBalance = group.balance;
|
||||
let prize = 4;
|
||||
|
||||
await groupLeader.post(`/challenges`, {
|
||||
groupId: group._id,
|
||||
name: 'Test Challenge',
|
||||
shortName: 'TC',
|
||||
prize,
|
||||
});
|
||||
|
||||
await expect(group.sync()).to.eventually.have.property('balance', oldGroupBalance - prize / 4);
|
||||
await expect(groupLeader.sync()).to.eventually.have.property('balance', oldUserBalance);
|
||||
});
|
||||
|
||||
it('takes prize out of both group and user if group doesn\'t have enough', async () => {
|
||||
let oldUserBalance = groupLeader.balance;
|
||||
let prize = 8;
|
||||
|
||||
await groupLeader.post(`/challenges`, {
|
||||
groupId: group._id,
|
||||
name: 'Test Challenge',
|
||||
shortName: 'TC',
|
||||
prize,
|
||||
});
|
||||
|
||||
await expect(group.sync()).to.eventually.have.property('balance', 0);
|
||||
await expect(groupLeader.sync()).to.eventually.have.property('balance', oldUserBalance - (prize / 4 - 1));
|
||||
});
|
||||
|
||||
it('takes prize out of user if group has no balance', async () => {
|
||||
let oldUserBalance = groupLeader.balance;
|
||||
let prize = 8;
|
||||
|
||||
await group.update({ balance: 0});
|
||||
await groupLeader.post(`/challenges`, {
|
||||
groupId: group._id,
|
||||
name: 'Test Challenge',
|
||||
shortName: 'TC',
|
||||
prize,
|
||||
});
|
||||
|
||||
await expect(group.sync()).to.eventually.have.property('balance', 0);
|
||||
await expect(groupLeader.sync()).to.eventually.have.property('balance', oldUserBalance - prize / 4);
|
||||
});
|
||||
|
||||
it('increases challenge count of group', async () => {
|
||||
let oldChallengeCount = group.challengeCount;
|
||||
|
||||
await groupLeader.post(`/challenges`, {
|
||||
groupId: group._id,
|
||||
name: 'Test Challenge',
|
||||
shortName: 'TC',
|
||||
});
|
||||
|
||||
await expect(group.sync()).to.eventually.have.property('challengeCount', oldChallengeCount + 1);
|
||||
});
|
||||
|
||||
it('sets challenge as official if created by admin and official flag is set', async () => {
|
||||
await groupLeader.update({
|
||||
contributor: {
|
||||
admin: true,
|
||||
},
|
||||
});
|
||||
|
||||
let challenge = await groupLeader.post(`/challenges`, {
|
||||
groupId: group._id,
|
||||
name: 'Test Challenge',
|
||||
shortName: 'TC',
|
||||
official: true,
|
||||
});
|
||||
|
||||
expect(challenge.official).to.eql(true);
|
||||
});
|
||||
|
||||
it('doesn\'t set challenge as official if official flag is set by non-admin', async () => {
|
||||
let challenge = await groupLeader.post(`/challenges`, {
|
||||
groupId: group._id,
|
||||
name: 'Test Challenge',
|
||||
shortName: 'TC',
|
||||
official: true,
|
||||
});
|
||||
|
||||
expect(challenge.official).to.be.undefined;
|
||||
});
|
||||
|
||||
it('returns an error when challenge validation fails; doesn\'s save user or group', async () => {
|
||||
let oldChallengeCount = group.challengeCount;
|
||||
let oldUserBalance = groupLeader.balance;
|
||||
let oldUserChallenges = groupLeader.challenges;
|
||||
let oldGroupBalance = group.balance;
|
||||
|
||||
await expect(groupLeader.post(`/challenges`, {
|
||||
groupId: group._id,
|
||||
prize: 8,
|
||||
})).to.eventually.be.rejected.and.eql({
|
||||
code: 400,
|
||||
error: 'BadRequest',
|
||||
message: 'Challenge validation failed',
|
||||
});
|
||||
|
||||
group = await group.sync();
|
||||
groupLeader = await groupLeader.sync();
|
||||
|
||||
expect(group.challengeCount).to.eql(oldChallengeCount);
|
||||
expect(group.balance).to.eql(oldGroupBalance);
|
||||
expect(groupLeader.balance).to.eql(oldUserBalance);
|
||||
expect(groupLeader.challenges).to.eql(oldUserChallenges);
|
||||
});
|
||||
|
||||
it('sets all properites of the challenge as passed', async () => {
|
||||
let name = 'Test Challenge';
|
||||
let shortName = 'TC';
|
||||
let description = 'Test Description';
|
||||
let prize = 4;
|
||||
|
||||
let challenge = await groupLeader.post(`/challenges`, {
|
||||
groupId: group._id,
|
||||
name,
|
||||
shortName,
|
||||
description,
|
||||
prize,
|
||||
});
|
||||
|
||||
expect(challenge.leader).to.eql(groupLeader._id);
|
||||
expect(challenge.name).to.eql(name);
|
||||
expect(challenge.shortName).to.eql(shortName);
|
||||
expect(challenge.description).to.eql(description);
|
||||
expect(challenge.official).to.be.undefined;
|
||||
expect(challenge.groupId).to.eql(group._id);
|
||||
expect(challenge.memberCount).to.eql(1);
|
||||
expect(challenge.prize).to.eql(prize);
|
||||
});
|
||||
|
||||
it('adds challenge to creator\'s challenges', async () => {
|
||||
let challenge = await groupLeader.post(`/challenges`, {
|
||||
groupId: group._id,
|
||||
name: 'Test Challenge',
|
||||
shortName: 'TC',
|
||||
});
|
||||
|
||||
await expect(groupLeader.sync()).to.eventually.have.property('challenges').to.include(challenge._id);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user