Merge branch 'develop' into api-v3

This commit is contained in:
Blade Barringer
2016-01-02 22:29:03 -06:00
33 changed files with 710 additions and 874 deletions

View File

@@ -1,6 +1,8 @@
{
"parser": "babel-eslint",
"plugins": ["babel"],
"rules": {
"indent": [2, 2],
"indent": [2, 2, {"SwitchCase": 1}],
"quotes": [2, "single"],
"linebreak-style": [2, "unix"],
"semi": [2, "always"],
@@ -43,7 +45,7 @@
"no-self-compare": 2,
"no-return-assign": 2,
"no-redeclare": 2,
"strict": [2, "global"],
"strict": [0, "global"],
"no-delete-var": 2,
"no-label-var": 2,
"no-shadow-restricted-names": 2,
@@ -64,7 +66,7 @@
"no-dupe-class-members": 2,
"no-this-before-super": 2,
"no-var": 2,
"object-shorthand": 2,
"object-shorthand": 0,
"prefer-const": 0,
"prefer-spread": 2,
"prefer-template": 2,
@@ -75,13 +77,13 @@
"comma-style": [2, "last"],
"comma-dangle": [2, "always-multiline"],
"computed-property-spacing": [2, "never"],
"consistent-this": [2, "self"],
"consistent-this": [0, "self"],
"func-names": 2,
"func-style": [2, "declaration", { "allowArrowFunctions": true }],
"block-spacing": [2, "always"],
"key-spacing": [2, {"beforeColon": false, "afterColon": true}],
"max-nested-callbacks": [2, 3],
"new-cap": 2,
"new-cap": 0,
"new-parens": 2,
"newline-after-var": 0,
"no-array-constructor": 2,
@@ -106,7 +108,11 @@
"space-unary-ops": 2,
"spaced-comment": [2, "always", { "exceptions": ["-"]}],
"padded-blocks": [2, "never"],
"no-multiple-empty-lines": [2, {"max": 2}]
"no-multiple-empty-lines": [2, {"max": 2}],
"generator-star-spacing": 0,
"babel/new-cap": 2,
"babel/object-shorthand": 2,
"babel/no-await-in-loop": 2
},
"env": {
"es6": true,

View File

@@ -445,7 +445,7 @@ let head = {
canOwn: ownsItem('head_special_fireCoralCirclet'),
},
nye: {
event: EVENTS.winter,
event: EVENTS.winter2016,
text: t('headSpecialNyeText'),
notes: t('headSpecialNyeNotes'),
value: 0,

View File

@@ -100,17 +100,18 @@
"coverage": "COVERAGE=true mocha --require register-handlers.js --reporter html-cov > coverage.html; open coverage.html"
},
"devDependencies": {
"babel-eslint": "^4.1.6",
"chai": "^3.4.0",
"chai-as-promised": "^5.1.0",
"coveralls": "^2.11.2",
"csv": "~0.3.6",
"deep-diff": "~0.1.4",
"eslint": "^1.9.0",
"eslint-plugin-babel": "^3.0.0",
"eslint-plugin-mocha": "^1.1.0",
"event-stream": "^3.2.2",
"expect.js": "~0.2.0",
"istanbul": "^0.3.14",
"phantomjs": "^1.9",
"karma": "~0.13.15",
"karma-babel-preprocessor": "^5.0.0",
"karma-chai-plugins": "~0.6.0",
@@ -123,7 +124,7 @@
"mongodb": "^2.0.46",
"mongoskin": "~0.6.1",
"nock": "^2.17.0",
"phantomjs": "^1.9.18",
"phantomjs": "^1.9",
"protractor": "~2.5.1",
"rewire": "^2.3.3",
"rimraf": "^2.4.3",

View File

@@ -20,7 +20,6 @@ const TEST_FILES = [
'./test/**/*.js',
// @TODO remove these negations as the test files are cleaned up.
'!./test/api-legacy/**/*',
'!./test/api/**/*',
'!./test/common/simulations/**/*',
'!./test/content/**/*',
'!./test/e2e/**/*',

View File

@@ -10,81 +10,60 @@ describe('GET /groups', () => {
let user;
before(() => {
let leader, createdGroup;
before(async () => {
// Set up a world with a mixture of public and private guilds
// Invite user to a few of them
return resetHabiticaDB().then(() => {
return generateUser();
}).then((_user) => {
user = _user;
await resetHabiticaDB();
return generateUser({
balance: 10,
});
}).then((_user) => {
leader = _user;
user = await generateUser();
let leader = await generateUser({ balance: 10 });
let publicGuildWithUserAsMember = generateGroup(leader, {
name: 'public guild - is member',
type: 'guild',
privacy: 'public',
members: [leader._id, user._id],
});
await generateGroup(leader, {
name: 'public guild - is member',
type: 'guild',
privacy: 'public',
members: [leader._id, user._id],
});
let publicGuildWithoutUserAsMember = generateGroup(leader, {
name: 'public guild - is not member',
type: 'guild',
privacy: 'public',
});
await generateGroup(leader, {
name: 'public guild - is not member',
type: 'guild',
privacy: 'public',
});
let privateGuildWithUserAsMember = generateGroup(leader, {
name: 'private guild - is member',
type: 'guild',
privacy: 'private',
members: [leader._id, user._id],
});
await generateGroup(leader, {
name: 'private guild - is member',
type: 'guild',
privacy: 'private',
members: [leader._id, user._id],
});
let privateGuildWithoutUserAsMember = generateGroup(leader, {
name: 'private guild - is not member',
type: 'guild',
privacy: 'private',
});
await generateGroup(leader, {
name: 'private guild - is not member',
type: 'guild',
privacy: 'private',
});
let partyWithoutUserAsMember = generateGroup(leader, {
name: 'party name',
type: 'party',
privacy: 'private',
});
await generateGroup(leader, {
name: 'party - is not member',
type: 'party',
privacy: 'private',
});
let promises = [
publicGuildWithUserAsMember,
publicGuildWithoutUserAsMember,
privateGuildWithUserAsMember,
privateGuildWithoutUserAsMember,
partyWithoutUserAsMember,
];
return Promise.all(promises);
}).then((groups) => {
return user.post('/groups', {
type: 'party',
name: 'user\'s party',
privacy: 'private',
});
await user.post('/groups', {
name: 'party - is member',
type: 'party',
privacy: 'private',
});
});
context('no query passed in', () => {
xit('lists all public guilds, the tavern, user\'s party, and any private guilds that user is a part of - TODO query includes duplicates - IE, tavern is included as tavern and part of public guilds. Refactor so this is not the case');
});
context('tavern passed in as query', () => {
it('returns only the tavern', () => {
return expect(user.get('/groups', null, {type: 'tavern'}))
it('returns only the tavern', async () => {
await expect(user.get('/groups', null, {type: 'tavern'}))
.to.eventually.have.a.lengthOf(1)
.and.to.have.deep.property('[0]')
.and.to.have.property('_id', 'habitrpg');
@@ -92,9 +71,8 @@ describe('GET /groups', () => {
});
context('party passed in as query', () => {
it('returns only the user\'s party', () => {
return expect(user.get('/groups', null, {type: 'party'}))
it('returns only the user\'s party', async () => {
await expect(user.get('/groups', null, {type: 'party'}))
.to.eventually.have.a.lengthOf(1)
.and.to.have.deep.property('[0]')
.and.to.have.property('leader', user._id);
@@ -102,17 +80,15 @@ describe('GET /groups', () => {
});
context('public passed in as query', () => {
it('returns all public guilds', () => {
return expect(user.get('/groups', null, {type: 'public'}))
it('returns all public guilds', async () => {
await expect(user.get('/groups', null, {type: 'public'}))
.to.eventually.have.a.lengthOf(NUMBER_OF_PUBLIC_GUILDS);
});
});
context('guilds passed in as query', () => {
it('returns all guilds user is a part of ', () => {
return expect(user.get('/groups', null, {type: 'guilds'}))
it('returns all guilds user is a part of ', async () => {
await expect(user.get('/groups', null, {type: 'guilds'}))
.to.eventually.have.a.lengthOf(NUMBER_OF_USERS_GUILDS);
});
});

View File

@@ -5,74 +5,66 @@ import {
} from '../../../helpers/api-integration.helper';
import {
find,
each
each,
} from 'lodash';
describe('GET /groups/:id', () => {
let typesOfGroups = {};
typesOfGroups['public guild'] = { type: 'guild', privacy: 'public' };
typesOfGroups['private guild'] = { type: 'guild', privacy: 'private' };
typesOfGroups['party'] = { type: 'party', privacy: 'private' };
typesOfGroups.party = { type: 'party', privacy: 'private' };
each(typesOfGroups, (groupData, groupType) => {
each(typesOfGroups, (groupDetails, groupType) => {
context(`Member of a ${groupType}`, () => {
let leader, member, createdGroup;
before(() => {
return createAndPopulateGroup({
before(async () => {
let groupData = await createAndPopulateGroup({
members: 30,
groupDetails: {
name: 'test guild',
type: 'guild',
privacy: 'public',
},
}).then((res) => {
leader = res.leader;
member = res.members[0];
createdGroup = res.group;
groupDetails,
});
leader = groupData.leader;
member = groupData.members[0];
createdGroup = groupData.group;
});
it('returns the group object', () => {
return member.get(`/groups/${createdGroup._id}`).then((group) => {
expect(group._id).to.eql(createdGroup._id);
expect(group.name).to.eql(createdGroup.name);
expect(group.type).to.eql(createdGroup.type);
expect(group.privacy).to.eql(createdGroup.privacy);
});
it('returns the group object', async () => {
let group = await member.get(`/groups/${createdGroup._id}`);
expect(group._id).to.eql(createdGroup._id);
expect(group.name).to.eql(createdGroup.name);
expect(group.type).to.eql(createdGroup.type);
expect(group.privacy).to.eql(createdGroup.privacy);
});
it('transforms members array to an array of user objects', () => {
return member.get(`/groups/${createdGroup._id}`).then((group) => {
let member = group.members[0];
expect(member._id).to.exist;
expect(member.profile.name).to.exist;
expect(member.contributor).to.exist;
expect(member.achievements).to.exist;
expect(member.items).to.exist;
});
it('transforms members array to an array of user objects', async () => {
let group = await member.get(`/groups/${createdGroup._id}`);
let someMember = group.members[0];
expect(someMember._id).to.exist;
expect(someMember.profile.name).to.exist;
expect(someMember.contributor).to.exist;
expect(someMember.achievements).to.exist;
expect(someMember.items).to.exist;
});
it('transforms leader id to leader object', () => {
return member.get(`/groups/${createdGroup._id}`).then((group) => {
expect(group.leader._id).to.eql(leader._id);
expect(group.leader.profile.name).to.eql(leader.profile.name);
expect(group.leader.items).to.exist;
expect(group.leader.stats).to.exist;
expect(group.leader.achievements).to.exist;
expect(group.leader.contributor).to.exist;
});
it('transforms leader id to leader object', async () => {
let group = await member.get(`/groups/${createdGroup._id}`);
expect(group.leader._id).to.eql(leader._id);
expect(group.leader.profile.name).to.eql(leader.profile.name);
expect(group.leader.items).to.exist;
expect(group.leader.stats).to.exist;
expect(group.leader.achievements).to.exist;
expect(group.leader.contributor).to.exist;
});
it('includes the user in the members list', () => {
return member.get(`/groups/${createdGroup._id}`).then((group) => {
let members = group.members;
let userInGroup = find(members, (user) => {
return member._id === user._id;
});
expect(userInGroup).to.be.ok;
});
it('includes the user in the members list', async () => {
let group = await member.get(`/groups/${createdGroup._id}`);
let userInGroup = find(group.members, '_id', member._id);
expect(userInGroup).to.exist;
});
});
});
@@ -123,8 +115,8 @@ describe('GET /groups/:id', () => {
flagCount: 3,
};
beforeEach(() => {
return createAndPopulateGroup({
beforeEach(async () => {
let groupData = await createAndPopulateGroup({
groupDetails: {
name: 'test guild',
type: 'guild',
@@ -137,134 +129,121 @@ describe('GET /groups/:id', () => {
chat5,
],
},
}).then((res) => {
group = res.group;
});
group = groupData.group;
});
context('non-admin', () => {
let nonAdmin;
beforeEach(() => {
return generateUser().then((user) => {
nonAdmin = user;
});
beforeEach(async () => {
nonAdmin = await generateUser();
});
it('does not include messages with a flag count of 2 or greater', () => {
return nonAdmin.get(`/groups/${group._id}`).then((_group) => {
expect(_group.chat).to.have.lengthOf(3);
expect(_group.chat[0].id).to.eql(chat1.id);
expect(_group.chat[1].id).to.eql(chat2.id);
expect(_group.chat[2].id).to.eql(chat3.id);
});
it('does not include messages with a flag count of 2 or greater', async () => {
let fetchedGroup = await nonAdmin.get(`/groups/${group._id}`);
expect(fetchedGroup.chat).to.have.lengthOf(3);
expect(fetchedGroup.chat[0].id).to.eql(chat1.id);
expect(fetchedGroup.chat[1].id).to.eql(chat2.id);
expect(fetchedGroup.chat[2].id).to.eql(chat3.id);
});
it('does not include user ids in flags object', () => {
return nonAdmin.get(`/groups/${group._id}`).then((_group) => {
let chatWithOneFlag = _group.chat[2];
expect(chatWithOneFlag.id).to.eql(chat3.id);
expect(chat3.flags).to.eql({ 'user-id': true });
expect(chatWithOneFlag.flags).to.eql({});
});
it('does not include user ids in flags object', async () => {
let fetchedGroup = await nonAdmin.get(`/groups/${group._id}`);
let chatWithOneFlag = fetchedGroup.chat[2];
expect(chatWithOneFlag.id).to.eql(chat3.id);
expect(chat3.flags).to.eql({ 'user-id': true });
expect(chatWithOneFlag.flags).to.eql({});
});
});
context('admin', () => {
let admin;
beforeEach(() => {
return generateUser({
beforeEach(async () => {
admin = await generateUser({
'contributor.admin': true,
}).then((user) => {
admin = user;
});
});
it('includes all messages', () => {
return admin.get(`/groups/${group._id}`).then((_group) => {
expect(_group.chat).to.have.lengthOf(5);
expect(_group.chat[0].id).to.eql(chat1.id);
expect(_group.chat[1].id).to.eql(chat2.id);
expect(_group.chat[2].id).to.eql(chat3.id);
expect(_group.chat[3].id).to.eql(chat4.id);
expect(_group.chat[4].id).to.eql(chat5.id);
});
it('includes all messages', async () => {
let fetchedGroup = await admin.get(`/groups/${group._id}`);
expect(fetchedGroup.chat).to.have.lengthOf(5);
expect(fetchedGroup.chat[0].id).to.eql(chat1.id);
expect(fetchedGroup.chat[1].id).to.eql(chat2.id);
expect(fetchedGroup.chat[2].id).to.eql(chat3.id);
expect(fetchedGroup.chat[3].id).to.eql(chat4.id);
expect(fetchedGroup.chat[4].id).to.eql(chat5.id);
});
it('includes user ids in flags object', () => {
return admin.get(`/groups/${group._id}`).then((_group) => {
let chatWithOneFlag = _group.chat[2];
expect(chatWithOneFlag.id).to.eql(chat3.id);
expect(chat3.flags).to.eql({ 'user-id': true });
expect(chatWithOneFlag.flags).to.eql(chat3.flags);
});
it('includes user ids in flags object', async () => {
let fetchedGroup = await admin.get(`/groups/${group._id}`);
let chatWithOneFlag = fetchedGroup.chat[2];
expect(chatWithOneFlag.id).to.eql(chat3.id);
expect(chat3.flags).to.eql({ 'user-id': true });
expect(chatWithOneFlag.flags).to.eql(chat3.flags);
});
});
});
context('Non-member of a public guild', () => {
let leader, nonMember, createdGroup;
let nonMember, createdGroup;
before(() => {
return createAndPopulateGroup({
before(async () => {
let groupData = await createAndPopulateGroup({
members: 1,
groupDetails: {
name: 'test guild',
type: 'guild',
privacy: 'public',
},
}).then((res) => {
leader = res.leader;
createdGroup = res.group;
return generateUser();
}).then((user) => {
nonMember = user;
});
createdGroup = groupData.group;
nonMember = await generateUser();
});
it('returns the group object for a non-member', () => {
return nonMember.get(`/groups/${createdGroup._id}`)
.then((group) => {
expect(group._id).to.eql(createdGroup._id);
expect(group.name).to.eql(createdGroup.name);
expect(group.type).to.eql(createdGroup.type);
expect(group.privacy).to.eql(createdGroup.privacy);
});
it('returns the group object for a non-member', async () => {
let group = await nonMember.get(`/groups/${createdGroup._id}`);
expect(group._id).to.eql(createdGroup._id);
expect(group.name).to.eql(createdGroup.name);
expect(group.type).to.eql(createdGroup.type);
expect(group.privacy).to.eql(createdGroup.privacy);
});
it('does not include user in members list', () => {
return nonMember.get(`/groups/${createdGroup._id}`).then((group) => {
let userInGroup = find(group.members, (user) => {
return nonMember._id === user._id;
});
expect(userInGroup).to.not.be.ok;
});
it('does not include user in members list', async () => {
let group = await nonMember.get(`/groups/${createdGroup._id}`);
let userInGroup = find(group.members, '_id', nonMember._id);
expect(userInGroup).to.not.exist;
});
});
context('Private Guilds', () => {
let leader, nonMember, createdGroup;
let nonMember, createdGroup;
before(() => {
return createAndPopulateGroup({
before(async () => {
let groupData = await createAndPopulateGroup({
members: 1,
groupDetails: {
name: 'test guild',
type: 'guild',
privacy: 'private',
},
}).then((res) => {
leader = res.leader;
createdGroup = res.group;
return generateUser();
}).then((user) => {
nonMember = user;
});
createdGroup = groupData.group;
nonMember = await generateUser();
});
it('does not return the group object for a non-member', () => {
return expect(nonMember.get(`/groups/${createdGroup._id}`))
it('does not return the group object for a non-member', async () => {
await expect(nonMember.get(`/groups/${createdGroup._id}`))
.to.eventually.be.rejected.and.eql({
code: 404,
text: t('messageGroupNotFound'),
@@ -273,27 +252,24 @@ describe('GET /groups/:id', () => {
});
context('Non-member of a party', () => {
let leader, nonMember, createdGroup;
let nonMember, createdGroup;
before(() => {
return createAndPopulateGroup({
before(async () => {
let groupData = await createAndPopulateGroup({
members: 1,
groupDetails: {
name: 'test party',
type: 'party',
privacy: 'private',
},
}).then((res) => {
leader = res.leader;
createdGroup = res.group;
return generateUser();
}).then((user) => {
nonMember = user;
});
createdGroup = groupData.group;
nonMember = await generateUser();
});
it('does not return the group object for a non-member', () => {
return expect(nonMember.get(`/groups/${createdGroup._id}`))
it('does not return the group object for a non-member', async () => {
await expect(nonMember.get(`/groups/${createdGroup._id}`))
.to.eventually.be.rejected.and.eql({
code: 404,
text: t('messageGroupNotFound'),
@@ -302,45 +278,41 @@ describe('GET /groups/:id', () => {
});
context('Member of a party', () => {
let leader, member, createdGroup;
let member, createdGroup;
before(() => {
return createAndPopulateGroup({
before(async () => {
let groupData = await createAndPopulateGroup({
members: 1,
groupDetails: {
name: 'test party',
type: 'party',
privacy: 'private',
},
}).then((res) => {
leader = res.leader;
createdGroup = res.group;
member = res.members[0];
});
createdGroup = groupData.group;
member = groupData.members[0];
});
it('returns the user\'s party if an id of "party" is passed in', () => {
return member.get('/groups/party')
.then((group) => {
expect(group._id).to.eql(createdGroup._id);
expect(group.name).to.eql(createdGroup.name);
expect(group.type).to.eql(createdGroup.type);
expect(group.privacy).to.eql(createdGroup.privacy);
});
it('returns the user\'s party if an id of "party" is passed in', async () => {
let group = await member.get('/groups/party');
expect(group._id).to.eql(createdGroup._id);
expect(group.name).to.eql(createdGroup.name);
expect(group.type).to.eql(createdGroup.type);
expect(group.privacy).to.eql(createdGroup.privacy);
});
});
context('Non-existent group', () => {
let user;
beforeEach(() => {
return generateUser().then((_user) => {
user = _user;
});
beforeEach(async () => {
user = await generateUser();
});
it('returns error if group does not exist', () => {
return expect(user.get('/groups/group-that-does-not-exist'))
it('returns error if group does not exist', async () => {
await expect(user.get('/groups/group-that-does-not-exist'))
.to.eventually.be.rejected.and.eql({
code: 404,
text: t('messageGroupNotFound'),

View File

@@ -12,7 +12,7 @@ describe('POST /groups', () => {
leader = await generateUser();
});
xit('returns defaults? (TODO: it\'s possible to create a group without a type. Should the group default to party? Should we require type to be set?', () => {
xit('returns defaults? (TODO: it\'s possible to create a group without a type. Should the group default to party? Should we require type to be set?', async () => {
return leader.post('/groups').then((group) => {
expect(group._id).to.exist;
expect(group.name).to.eql(`${leader.profile.name}'s group`);
@@ -68,7 +68,8 @@ describe('POST /groups', () => {
});
it('prevents party creation if user is already in party', async () => {
let party = await generateGroup(leader, {
await generateGroup(leader, {
name: 'first party that user attempts to create',
type: 'party',
});
@@ -78,7 +79,7 @@ describe('POST /groups', () => {
});
});
xit('prevents creating a public party. TODO: it is possible to create a public party. Should we send back an error? Automatically switch the privacy to private?', () => {
xit('prevents creating a public party. TODO: it is possible to create a public party. Should we send back an error? Automatically switch the privacy to private?', async () => {
return expect(leader.post('/groups', {
type: 'party',
privacy: 'public',
@@ -113,7 +114,7 @@ describe('POST /groups', () => {
let guild = await leader.post('/groups', {
type: 'guild',
privacy: 'public',
})
});
expect(guild.leader).to.eql(leader._id);
});

View File

@@ -5,11 +5,10 @@ import {
} from '../../../helpers/api-integration.helper';
describe('POST /groups/:id', () => {
context('user is not the leader of the group', () => {
let user, otherUser, groupUserDoesNotOwn;
beforeEach(() => {
beforeEach(async () => {
return Promise.all([
generateUser({ balance: 10 }),
generateUser({ balance: 10 }),
@@ -28,9 +27,9 @@ describe('POST /groups/:id', () => {
});
});
it('does not allow user to update group', () => {
it('does not allow user to update group', async () => {
return expect(user.post(`/groups/${groupUserDoesNotOwn._id}`, {
name: 'Change'
name: 'Change',
})).to.eventually.be.rejected.and.eql({
code: 401,
text: t('messageGroupOnlyLeaderCanUpdate'),
@@ -41,32 +40,28 @@ describe('POST /groups/:id', () => {
context('user is the leader of the group', () => {
let user, usersGroup;
beforeEach(() => {
return generateUser({
beforeEach(async () => {
user = await generateUser({
balance: 10,
}).then((_user) => {
user = _user;
});
return generateGroup(user, {
name: 'Original Group Title',
type: 'guild',
privacy: 'public',
});
}).then((group) => {
usersGroup = group;
usersGroup = await generateGroup(user, {
name: 'Original Group Title',
type: 'guild',
privacy: 'public',
});
});
it('allows user to update group', () => {
return user.post(`/groups/${usersGroup._id}`, {
it('allows user to update group', async () => {
await user.post(`/groups/${usersGroup._id}`, {
name: 'New Group Title',
description: 'New group description',
}).then((group) => {
return user.get(`/groups/${usersGroup._id}`);
}).then((group) => {
expect(group.name).to.eql('New Group Title');
expect(group.description).to.eql('New group description');
});
let group = await user.get(`/groups/${usersGroup._id}`);
expect(group.name).to.eql('New Group Title');
expect(group.description).to.eql('New group description');
});
});
});

View File

@@ -6,7 +6,6 @@ import {
import { each, find } from 'lodash';
describe('POST /groups/:id/join', () => {
context('user is already a member of the group', () => {
it('returns an error');
});
@@ -14,64 +13,48 @@ describe('POST /groups/:id/join', () => {
each({
'public guild': {type: 'guild', privacy: 'public'},
'private guild': {type: 'guild', privacy: 'private'},
'party': {type: 'party', privacy: 'private'},
}, (data, groupType) => {
party: {type: 'party', privacy: 'private'},
}, (groupDetails, groupType) => {
context(`user has invitation to a ${groupType}`, () => {
let group, invitee;
beforeEach(() => {
return createAndPopulateGroup({
groupDetails: {
type: data.type,
privacy: data.privacy,
},
beforeEach(async () => {
let groupData = await createAndPopulateGroup({
groupDetails,
invites: 1,
}).then((res) => {
group = res.group;
invitee = res.invitees[0];
});
group = groupData.group;
invitee = groupData.invitees[0];
});
it(`allows user to join a ${groupType}`, () => {
return invitee.post(`/groups/${group._id}/join`).then((res) => {
return invitee.get(`/groups/${group._id}`);
}).then((_group) => {
let members = _group.members;
let userInGroup = find(members, (user) => {
return user._id === invitee._id;
});
it(`allows user to join a ${groupType}`, async () => {
await invitee.post(`/groups/${group._id}/join`);
expect(userInGroup).to.exist;
});
let members = (await invitee.get(`/groups/${group._id}`)).members;
let userInGroup = find(members, '_id', invitee._id);
expect(userInGroup).to.exist;
});
});
});
each({
'private guild': {type: 'guild', privacy: 'private'},
'party': {type: 'party', privacy: 'private'},
}, (data, groupType) => {
party: {type: 'party', privacy: 'private'},
}, (groupDetails, groupType) => {
context(`user does not have an invitation to a ${groupType}`, () => {
let group, user;
beforeEach(() => {
return createAndPopulateGroup({
groupDetails: {
type: data.type,
privacy: data.privacy,
},
}).then((res) => {
group = res.group;
return generateUser();
}).then((generatedUser) => {
user = generatedUser;
beforeEach(async () => {
let groupData = await createAndPopulateGroup({
groupDetails,
});
group = groupData.group;
user = await generateUser();
});
it(`does not allow user to join a ${groupType}`, () => {
return expect(user.post(`/groups/${group._id}/join`).then((res) => {
return user.get(`/groups/${group._id}`);
})).to.eventually.be.rejected.and.eql({
it(`does not allow user to join a ${groupType}`, async () => {
await expect(user.post(`/groups/${group._id}/join`)).to.eventually.be.rejected.and.eql({
code: 401,
text: t('messageGroupRequiresInvite'),
});
@@ -82,58 +65,47 @@ describe('POST /groups/:id/join', () => {
context('user does not have an invitation to a public group', () => {
let group, user;
beforeEach(() => {
return createAndPopulateGroup({
beforeEach(async () => {
let groupData = await createAndPopulateGroup({
groupDetails: {
type: 'guild',
privacy: 'public',
},
}).then((res) => {
group = res.group;
return generateUser();
}).then((generatedUser) => {
user = generatedUser;
});
group = groupData.group;
user = await generateUser();
});
it('allows user to join a public guild', () => {
return user.post(`/groups/${group._id}/join`).then((res) => {
return user.get(`/groups/${group._id}`);
}).then((_group) => {
let members = _group.members;
let userInGroup = find(members, (member) => {
return user._id === user._id;
});
it('allows user to join a public guild', async () => {
await user.post(`/groups/${group._id}/join`);
expect(userInGroup).to.exist;
});
let members = (await user.get(`/groups/${group._id}`)).members;
let userInGroup = find(members, '_id', user._id);
expect(userInGroup).to.exist;
});
});
context('public guild has no leader', () => {
let user, group;
beforeEach(() => {
return createAndPopulateGroup({
beforeEach(async () => {
let groupData = await createAndPopulateGroup({
groupDetails: {
name: 'test guild',
type: 'guild',
privacy: 'public',
},
}).then((res) => {
group = res.group;
return res.leader.post(`/groups/${group._id}/leave`);
}).then((res) => {
return generateUser();
}).then((generatedUser) => {
user = generatedUser;
});
group = groupData.group;
await groupData.leader.post(`/groups/${group._id}/leave`);
user = await generateUser();
});
it('makes the joining user the leader', () => {
return expect(user.post(`/groups/${group._id}/join`).then((result) => {
return user.get(`/groups/${group._id}`);
})).to.eventually.have.deep.property('leader._id', user._id);
it('makes the joining user the leader', async () => {
await user.post(`/groups/${group._id}/join`);
await expect(user.get(`/groups/${group._id}`)).to.eventually.have.deep.property('leader._id', user._id);
});
});
});

View File

@@ -1,13 +1,10 @@
import {
checkExistence,
createAndPopulateGroup,
generateUser,
translate as t,
} from '../../../helpers/api-integration.helper';
import { find } from 'lodash';
describe('POST /groups/:id/leave', () => {
context('user is not member of the group', () => {
it('returns an error');
});
@@ -15,141 +12,127 @@ describe('POST /groups/:id/leave', () => {
context('user is a non-leader member of a guild', () => {
let user, group;
beforeEach(() => {
return createAndPopulateGroup({
beforeEach(async () => {
let groupData = await createAndPopulateGroup({
members: 3,
groupDetails: {
name: 'test guild',
type: 'guild',
privacy: 'public',
},
}).then((res) => {
user = res.members[0];
group = res.group;
});
user = groupData.members[0];
group = groupData.group;
});
it('leaves the group', () => {
return user.post(`/groups/${group._id}/leave`).then((result) => {
return user.get(`/groups/${group._id}`);
}).then((group) => {
let userInGroup = find(group.members, (member) => {
return member._id === user._id;
});
expect(userInGroup).to.not.be.ok;
});
it('leaves the group', async () => {
await user.post(`/groups/${group._id}/leave`);
let members = (await user.get(`/groups/${group._id}`)).members;
let userInGroup = find(members, '_id', user._id);
expect(userInGroup).to.not.be.ok;
});
});
context('user is the last member of a public guild', () => {
let user, group;
beforeEach(() => {
return createAndPopulateGroup({
beforeEach(async () => {
let groupData = await createAndPopulateGroup({
groupDetails: {
name: 'test guild',
type: 'guild',
privacy: 'public',
},
}).then((res) => {
user = res.leader;
group = res.group;
});
user = groupData.leader;
group = groupData.group;
});
it('leaves the group accessible', () => {
return expect(user.post(`/groups/${group._id}/leave`).then((result) => {
return user.get(`/groups/${group._id}`);
})).to.eventually.have.property('_id', group._id);
it('leaves the group accessible', async () => {
await user.post(`/groups/${group._id}/leave`);
await expect(user.get(`/groups/${group._id}`)).to.eventually.have.property('_id', group._id);
});
});
context('user is the last member of a private group', () => {
let user, group;
beforeEach(() => {
return createAndPopulateGroup({
beforeEach(async () => {
let groupData = await createAndPopulateGroup({
groupDetails: {
name: 'test guild',
type: 'guild',
privacy: 'private',
},
}).then((res) => {
user = res.leader;
group = res.group;
});
user = groupData.leader;
group = groupData.group;
});
it('group is deleted', () => {
return expect(user.post(`/groups/${group._id}/leave`).then((result) => {
return checkExistence('groups', group._id);
})).to.eventually.eql(false);
it('group is deleted', async () => {
await user.post(`/groups/${group._id}/leave`);
await expect(checkExistence('groups', group._id)).to.eventually.eql(false);
});
});
context('user is the last member of a private group with pending invites', () => {
let user, invitee1, invitee2, group;
beforeEach(() => {
return createAndPopulateGroup({
beforeEach(async () => {
let groupData = await createAndPopulateGroup({
invites: 2,
groupDetails: {
name: 'test guild',
type: 'guild',
privacy: 'private',
},
}).then((res) => {
user = res.leader;
invitee1 = res.invitees[0];
invitee2 = res.invitees[1];
group = res.group;
});
user = groupData.leader;
group = groupData.group;
invitee1 = groupData.invitees[0];
invitee2 = groupData.invitees[1];
});
it('deletes the group invitations from users', () => {
return user.post(`/groups/${group._id}/leave`).then((result) => {
return Promise.all([
expect(invitee1.get(`/user`))
.to.eventually.have.deep.property('invitations.guilds')
.and.to.be.empty,
expect(invitee2.get(`/user`))
.to.eventually.have.deep.property('invitations.guilds')
.and.to.be.empty,
]);
});
it('deletes the group invitations from users', async () => {
await user.post(`/groups/${group._id}/leave`);
await expect(invitee1.get(`/user`)).to.eventually.have.deep.property('invitations.guilds').and.to.be.empty;
await expect(invitee2.get(`/user`)).to.eventually.have.deep.property('invitations.guilds').and.to.be.empty;
});
});
context('user is the last member of a party with pending invites', () => {
let user, invitee1, invitee2, group;
beforeEach(() => {
return createAndPopulateGroup({
beforeEach(async () => {
let groupData = await createAndPopulateGroup({
invites: 2,
groupDetails: {
name: 'test party',
name: 'test guild',
type: 'party',
privacy: 'private',
},
}).then((res) => {
user = res.leader;
invitee1 = res.invitees[0];
invitee2 = res.invitees[1];
group = res.group;
});
user = groupData.leader;
group = groupData.group;
invitee1 = groupData.invitees[0];
invitee2 = groupData.invitees[1];
});
it('deletes the group invitations from users', () => {
return user.post(`/groups/${group._id}/leave`).then((result) => {
return Promise.all([
expect(invitee1.get(`/user`))
.to.eventually.have.deep.property('invitations.party')
.and.to.be.empty,
expect(invitee2.get(`/user`))
.to.eventually.have.deep.property('invitations.party')
.and.to.be.empty,
]);
});
it('deletes the group invitations from users', async () => {
await user.post(`/groups/${group._id}/leave`);
await expect(invitee1.get(`/user`)).to.eventually.have.deep.property('invitations.party').and.to.be.empty;
await expect(invitee2.get(`/user`)).to.eventually.have.deep.property('invitations.party').and.to.be.empty;
});
});
});

View File

@@ -1,12 +1,9 @@
import {
createAndPopulateGroup,
generateGroup,
generateUser,
translate as t,
} from '../../../helpers/api-integration.helper';
describe('POST /groups/:id/removeMember', () => {
context('user is not member of the group', () => {
it('returns an error');
});
@@ -18,7 +15,7 @@ describe('POST /groups/:id/removeMember', () => {
context('user is the leader of a guild', () => {
let leader, member, group;
beforeEach(() => {
beforeEach(async () => {
return createAndPopulateGroup({
members: 1,
groupDetails: {
@@ -33,7 +30,7 @@ describe('POST /groups/:id/removeMember', () => {
});
});
it('does not allow leader to remove themselves', () => {
it('does not allow leader to remove themselves', async () => {
return expect(leader.post(`/groups/${group._id}/removeMember`, null, {
uuid: leader._id,
})).to.eventually.be.rejected.and.eql({
@@ -42,10 +39,10 @@ describe('POST /groups/:id/removeMember', () => {
});
});
it('can remove other members of guild', () => {
it('can remove other members of guild', async () => {
return leader.post(`/groups/${group._id}/removeMember`, null, {
uuid: member._id,
}).then((res) => {
}).then(() => {
return leader.get(`/groups/${group._id}`);
}).then((guild) => {
expect(guild.members).to.have.a.lengthOf(1);

View File

@@ -1,13 +1,12 @@
import {
createAndPopulateGroup,
generateUser,
translate as t,
} from '../../../../helpers/api-integration.helper';
describe('DELETE /groups/:id/chat', () => {
let group, message, user;
beforeEach(() => {
beforeEach(async () => {
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
@@ -17,21 +16,21 @@ describe('DELETE /groups/:id/chat', () => {
group = res.group;
user = res.leader;
return user.post(`/groups/${group._id}/chat`, null, { message: 'Some message', });
return user.post(`/groups/${group._id}/chat`, null, { message: 'Some message' });
}).then((res) => {
message = res.message;
});
});
it('deletes a message', () => {
return user.del(`/groups/${group._id}/chat/${message.id}`).then((res) => {
it('deletes a message', async () => {
return user.del(`/groups/${group._id}/chat/${message.id}`).then(() => {
return user.get(`/groups/${group._id}/chat/`);
}).then((messages) => {
expect(messages).to.have.length(0);
});
});
it('returns an error is message does not exist', () => {
it('returns an error is message does not exist', async () => {
return expect(user.del(`/groups/${group._id}/chat/some-fake-id`)).to.eventually.be.rejected.and.eql({
code: 404,
text: t('messageGroupChatNotFound'),

View File

@@ -1,45 +1,38 @@
import {
createAndPopulateGroup,
generateUser,
translate as t,
} from '../../../../helpers/api-integration.helper';
describe('GET /groups/:id/chat', () => {
context('group with multiple messages', () => {
let group, member, message1, message2, user;
let group, member, user;
beforeEach(() => {
return createAndPopulateGroup({
beforeEach(async () => {
let groupData = await createAndPopulateGroup({
groupDetails: {
type: 'guild',
privacy: 'public',
},
members: 1,
}).then((res) => {
group = res.group;
user = res.leader;
member = res.members[0];
return member.post(`/groups/${group._id}/chat`, null, { message: 'Group member message' });
}).then((res) => {
message1 = res.message;
return user.post(`/groups/${group._id}/chat`, null, { message: 'User message' });
}).then((res) => {
message2 = res.message;
});
group = groupData.group;
user = groupData.leader;
member = groupData.members[0];
await member.post(`/groups/${group._id}/chat`, null, { message: 'Group member message' });
await user.post(`/groups/${group._id}/chat`, null, { message: 'User message' });
});
it('gets messages', () => {
return user.get(`/groups/${group._id}/chat`).then((messages) => {
expect(messages).to.have.length(2);
it('gets messages', async () => {
let messages = await user.get(`/groups/${group._id}/chat`);
let message = messages[0];
expect(message.id).to.exist;
expect(message.text).to.exist;
expect(message.uuid).to.exist;
});
expect(messages).to.have.length(2);
let message = messages[0];
expect(message.id).to.exist;
expect(message.text).to.exist;
expect(message.uuid).to.exist;
});
});
});

View File

@@ -1,14 +1,12 @@
import {
createAndPopulateGroup,
generateUser,
translate as t,
} from '../../../../helpers/api-integration.helper';
describe('POST /groups/:id/chat', () => {
let group, user;
beforeEach(() => {
beforeEach(async () => {
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
@@ -20,7 +18,7 @@ describe('POST /groups/:id/chat', () => {
});
});
it('creates a chat message', () => {
it('creates a chat message', async () => {
return user.post(`/groups/${group._id}/chat`, null, {
message: 'Test Message',
}).then((res) => {
@@ -33,7 +31,7 @@ describe('POST /groups/:id/chat', () => {
});
});
it('does not post an empty message', () => {
it('does not post an empty message', async () => {
return expect(user.post(`/groups/${group._id}/chat`, null, {
message: '',
})).to.eventually.be.rejected.and.eql({

View File

@@ -7,7 +7,7 @@ import {
describe('POST /groups/:id/chat/:id/clearflags', () => {
let group;
beforeEach(() => {
beforeEach(async () => {
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
@@ -28,13 +28,11 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
context('non admin', () => {
let nonadmin;
beforeEach(() => {
return generateUser().then((user) => {
nonadmin = user;
});
beforeEach(async () => {
nonadmin = await generateUser();
});
it('cannot clear flags', () => {
it('cannot clear flags', async () => {
return expect(nonadmin.post(`/groups/${group._id}/chat/message-to-clear/clearflags`))
.to.eventually.be.rejected.and.eql({
code: 401,
@@ -46,7 +44,7 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
context('admin', () => {
let admin;
beforeEach(() => {
beforeEach(async () => {
return generateUser({
'contributor.admin': true,
}).then((user) => {
@@ -54,23 +52,23 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
});
});
it('clears flags', () => {
return admin.post(`/groups/${group._id}/chat/message-to-clear/clearflags`).then((res) => {
it('clears flags', async () => {
return admin.post(`/groups/${group._id}/chat/message-to-clear/clearflags`).then(() => {
return admin.get(`/groups/${group._id}/chat`);
}).then((messages) => {
expect(messages[0].flagCount).to.eql(0);
});
});
it('leaves old flags on the flag object', () => {
return admin.post(`/groups/${group._id}/chat/message-to-clear/clearflags`).then((res) => {
it('leaves old flags on the flag object', async () => {
return admin.post(`/groups/${group._id}/chat/message-to-clear/clearflags`).then(() => {
return admin.get(`/groups/${group._id}/chat`);
}).then((messages) => {
expect(messages[0].flags).to.have.property('some-id', true);
});
});
it('returns error if message does not exist', () => {
it('returns error if message does not exist', async () => {
return expect(admin.post(`/groups/${group._id}/chat/non-existant-message/clearflags`))
.to.eventually.be.rejected.and.eql({
code: 404,
@@ -80,38 +78,34 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
});
context('admin user, group with multiple messages', () => {
let admin, author, group, member;
let admin, author, groupWithMessages;
beforeEach(() => {
return generateUser().then((user) => {
author = user;
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
privacy: 'public',
chat: [
{ id: 'message-to-unflag', uuid: author._id, flagCount: 1, flags: {'some-user': true} },
{ id: '1-flag-message', uuid: author._id, flagCount: 1, flags: { 'id1': true } },
{ id: '2-flag-message', uuid: author._id, flagCount: 2, flags: { 'id1': true, 'id2': true } },
{ id: 'no-flags', uuid: author._id, flagCount: 0, flags: {} },
],
},
members: 1,
});
}).then((res) => {
group = res.group;
return generateUser({
'contributor.admin': true,
});
}).then((user) => {
admin = user;
beforeEach(async () => {
author = await generateUser();
admin = await generateUser({
'contributor.admin': true,
});
let groupData = await createAndPopulateGroup({
groupDetails: {
type: 'guild',
privacy: 'public',
chat: [
{ id: 'message-to-unflag', uuid: author._id, flagCount: 1, flags: {'some-user': true} },
{ id: '1-flag-message', uuid: author._id, flagCount: 1, flags: { id1: true } },
{ id: '2-flag-message', uuid: author._id, flagCount: 2, flags: { id1: true, id2: true } },
{ id: 'no-flags', uuid: author._id, flagCount: 0, flags: {} },
],
},
members: 1,
});
groupWithMessages = groupData.group;
});
it('changes only the message that is flagged', () => {
return admin.post(`/groups/${group._id}/chat/message-to-unflag/clearflags`).then((messages) => {
return admin.get(`/groups/${group._id}/chat`);
it('changes only the message that is flagged', async () => {
return admin.post(`/groups/${groupWithMessages._id}/chat/message-to-unflag/clearflags`).then(() => {
return admin.get(`/groups/${groupWithMessages._id}/chat`);
}).then((messages) => {
expect(messages).to.have.lengthOf(4);

View File

@@ -5,11 +5,10 @@ import {
} from '../../../../helpers/api-integration.helper';
describe('POST /groups/:id/chat/:id/flag', () => {
context('another member\'s message', () => {
let group, member, message, user;
beforeEach(() => {
beforeEach(async () => {
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
@@ -21,23 +20,22 @@ describe('POST /groups/:id/chat/:id/flag', () => {
user = res.leader;
member = res.members[0];
return member.post(`/groups/${group._id}/chat`, null, { message: 'Group member message', });
return member.post(`/groups/${group._id}/chat`, null, { message: 'Group member message' });
}).then((res) => {
message = res.message;
});
});
it('flags message', () => {
return user.post(`/groups/${group._id}/chat/${message.id}/flag`).then((messages) => {
it('flags message', async () => {
return user.post(`/groups/${group._id}/chat/${message.id}/flag`).then(() => {
return user.get(`/groups/${group._id}/chat`);
}).then((messages) => {
let message = messages[0];
expect(message.flagCount).to.eql(1);
expect(messages[0].flagCount).to.eql(1);
});
});
it('cannot flag the same message twice', () => {
return expect(user.post(`/groups/${group._id}/chat/${message.id}/flag`).then((messages) => {
it('cannot flag the same message twice', async () => {
return expect(user.post(`/groups/${group._id}/chat/${message.id}/flag`).then(() => {
return user.post(`/groups/${group._id}/chat/${message.id}/flag`);
})).to.eventually.be.rejected.and.eql({
code: 401,
@@ -49,7 +47,7 @@ describe('POST /groups/:id/chat/:id/flag', () => {
context('own message', () => {
let group, message, user;
beforeEach(() => {
beforeEach(async () => {
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
@@ -60,13 +58,13 @@ describe('POST /groups/:id/chat/:id/flag', () => {
group = res.group;
user = res.leader;
return user.post(`/groups/${group._id}/chat`, null, { message: 'User\'s own message', });
return user.post(`/groups/${group._id}/chat`, null, { message: 'User\'s own message' });
}).then((res) => {
message = res.message;
});
});
it('cannot flag message', () => {
it('cannot flag message', async () => {
return expect(user.post(`/groups/${group._id}/chat/${message.id}/flag`))
.to.eventually.be.rejected.and.eql({
code: 401,
@@ -76,9 +74,9 @@ describe('POST /groups/:id/chat/:id/flag', () => {
});
context('nonexistant message', () => {
let group, message, user;
let group, user;
beforeEach(() => {
beforeEach(async () => {
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
@@ -90,7 +88,7 @@ describe('POST /groups/:id/chat/:id/flag', () => {
});
});
it('returns error', () => {
it('returns error', async () => {
return expect(user.post(`/groups/${group._id}/chat/non-existant-message/flag`))
.to.eventually.be.rejected.and.eql({
code: 404,
@@ -100,39 +98,34 @@ describe('POST /groups/:id/chat/:id/flag', () => {
});
context('group with multiple messages', () => {
let admin, author, group, member, message, user;
let admin, author, group, user;
beforeEach(() => {
return generateUser().then((user) => {
author = user;
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
privacy: 'public',
chat: [
{ id: 'message-to-be-flagged', uuid: author._id, flagCount: 0, flags: {} },
{ id: '1-flag-message', uuid: author._id, flagCount: 1, flags: { 'id1': true } },
{ id: '2-flag-message', uuid: author._id, flagCount: 2, flags: { 'id1': true, 'id2': true } },
{ id: 'no-flags', uuid: author._id, flagCount: 0, flags: {} },
],
},
members: 1,
});
}).then((res) => {
group = res.group;
user = res.leader;
member = res.members[0];
return generateUser({
'contributor.admin': true,
});
}).then((user) => {
admin = user;
beforeEach(async () => {
author = await generateUser();
admin = await generateUser({
'contributor.admin': true,
});
let groupData = await createAndPopulateGroup({
groupDetails: {
type: 'guild',
privacy: 'public',
chat: [
{ id: 'message-to-be-flagged', uuid: author._id, flagCount: 0, flags: {} },
{ id: '1-flag-message', uuid: author._id, flagCount: 1, flags: { id1: true } },
{ id: '2-flag-message', uuid: author._id, flagCount: 2, flags: { id1: true, id2: true } },
{ id: 'no-flags', uuid: author._id, flagCount: 0, flags: {} },
],
},
members: 1,
});
group = groupData.group;
user = groupData.leader;
});
it('changes only the message that is flagged', () => {
return user.post(`/groups/${group._id}/chat/message-to-be-flagged/flag`).then((messages) => {
it('changes only the message that is flagged', async () => {
return user.post(`/groups/${group._id}/chat/message-to-be-flagged/flag`).then(() => {
return admin.get(`/groups/${group._id}/chat`);
}).then((messages) => {
expect(messages).to.have.lengthOf(4);
@@ -160,7 +153,7 @@ describe('POST /groups/:id/chat/:id/flag', () => {
context('admin flagging a message', () => {
let group, member, message, user;
beforeEach(() => {
beforeEach(async () => {
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
@@ -176,18 +169,17 @@ describe('POST /groups/:id/chat/:id/flag', () => {
user = res.leader;
member = res.members[0];
return member.post(`/groups/${group._id}/chat`, null, { message: 'Group member message', });
return member.post(`/groups/${group._id}/chat`, null, { message: 'Group member message' });
}).then((res) => {
message = res.message;
});
});
it('sets flagCount to 5', () => {
return user.post(`/groups/${group._id}/chat/${message.id}/flag`).then((messages) => {
it('sets flagCount to 5', async () => {
return user.post(`/groups/${group._id}/chat/${message.id}/flag`).then(() => {
return user.get(`/groups/${group._id}/chat`);
}).then((messages) => {
let message = messages[0];
expect(message.flagCount).to.eql(5);
expect(messages[0].flagCount).to.eql(5);
});
});
});

View File

@@ -5,11 +5,10 @@ import {
} from '../../../../helpers/api-integration.helper';
describe('POST /groups/:id/chat/:id/like', () => {
context('another member\'s message', () => {
let group, member, message, user;
beforeEach(() => {
beforeEach(async () => {
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
@@ -21,25 +20,23 @@ describe('POST /groups/:id/chat/:id/like', () => {
user = res.leader;
member = res.members[0];
return member.post(`/groups/${group._id}/chat`, null, { message: 'Group member message', });
return member.post(`/groups/${group._id}/chat`, null, { message: 'Group member message' });
}).then((res) => {
message = res.message;
});
});
it('likes message', () => {
it('likes message', async () => {
return user.post(`/groups/${group._id}/chat/${message.id}/like`).then((messages) => {
let message = messages[0];
expect(message.likes[user._id]).to.eql(true);
expect(messages[0].likes[user._id]).to.eql(true);
});
});
it('returns the message object', () => {
it('returns the message object', async () => {
return user.post(`/groups/${group._id}/chat/${message.id}/like`).then((messages) => {
let message = messages[0];
expect(message.text).to.eql('Group member message');
expect(message.uuid).to.eql(member._id);
expect(message.user).to.eql(member.profile.name);
expect(messages[0].text).to.eql('Group member message');
expect(messages[0].uuid).to.eql(member._id);
expect(messages[0].user).to.eql(member.profile.name);
});
});
});
@@ -47,7 +44,7 @@ describe('POST /groups/:id/chat/:id/like', () => {
context('own message', () => {
let group, message, user;
beforeEach(() => {
beforeEach(async () => {
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
@@ -58,13 +55,13 @@ describe('POST /groups/:id/chat/:id/like', () => {
group = res.group;
user = res.leader;
return user.post(`/groups/${group._id}/chat`, null, { message: 'User\'s own message', });
return user.post(`/groups/${group._id}/chat`, null, { message: 'User\'s own message' });
}).then((res) => {
message = res.message;
});
});
it('cannot like message', () => {
it('cannot like message', async () => {
return expect(user.post(`/groups/${group._id}/chat/${message.id}/like`))
.to.eventually.be.rejected.and.eql({
code: 401,
@@ -74,39 +71,34 @@ describe('POST /groups/:id/chat/:id/like', () => {
});
context('group with multiple messages', () => {
let admin, author, group, member, message, user;
let admin, author, group, user;
beforeEach(() => {
return generateUser().then((user) => {
author = user;
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
privacy: 'public',
chat: [
{ id: 'message-to-be-liked', likes: {}, uuid: author._id, flagCount: 0, flags: {} },
{ id: '1-like-message', likes: { 'id': true }, uuid: author._id, flagCount: 1, flags: { 'id1': true } },
{ id: '2-like-message', likes: { 'id': true, 'id2': true }, uuid: author._id, flagCount: 2, flags: { 'id1': true, 'id2': true } },
{ id: 'no-likes', likes: {}, uuid: author._id, flagCount: 0, flags: {} },
],
},
members: 1,
});
}).then((res) => {
group = res.group;
user = res.leader;
member = res.members[0];
return generateUser({
'contributor.admin': true,
});
}).then((user) => {
admin = user;
beforeEach(async () => {
author = await generateUser();
admin = await generateUser({
'contributor.admin': true,
});
let groupData = await createAndPopulateGroup({
groupDetails: {
type: 'guild',
privacy: 'public',
chat: [
{ id: 'message-to-be-liked', likes: {}, uuid: author._id, flagCount: 0, flags: {} },
{ id: '1-like-message', likes: { id: true }, uuid: author._id, flagCount: 1, flags: { id1: true } },
{ id: '2-like-message', likes: { id: true, id2: true }, uuid: author._id, flagCount: 2, flags: { id1: true, id2: true } },
{ id: 'no-likes', likes: {}, uuid: author._id, flagCount: 0, flags: {} },
],
},
members: 1,
});
group = groupData.group;
user = groupData.leader;
});
it('changes only the message that is liked', () => {
return user.post(`/groups/${group._id}/chat/message-to-be-liked/like`).then((messages) => {
it('changes only the message that is liked', async () => {
return user.post(`/groups/${group._id}/chat/message-to-be-liked/like`).then(() => {
return admin.get(`/groups/${group._id}/chat`);
}).then((messages) => {
expect(messages).to.have.lengthOf(4);
@@ -132,9 +124,9 @@ describe('POST /groups/:id/chat/:id/like', () => {
});
context('nonexistant message', () => {
let group, message, user;
let group, user;
beforeEach(() => {
beforeEach(async () => {
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
@@ -146,7 +138,7 @@ describe('POST /groups/:id/chat/:id/like', () => {
});
});
it('returns error', () => {
it('returns error', async () => {
return expect(user.post(`/groups/${group._id}/chat/non-existant-message/like`))
.to.eventually.be.rejected.and.eql({
code: 404,

View File

@@ -7,18 +7,17 @@ import { v4 as generateRandomUserName } from 'uuid';
import { each } from 'lodash';
describe('POST /register', () => {
context('username and email are free', () => {
it('registers a new user', () => {
it('registers a new user', async () => {
let api = requester();
let username = generateRandomUserName();
let email = `${username}@example.com`;
let password = 'password';
return api.post('/register', {
username: username,
email: email,
password: password,
username,
email,
password,
confirmPassword: password,
}).then((user) => {
expect(user._id).to.exist;
@@ -27,7 +26,7 @@ describe('POST /register', () => {
});
});
it('requires password and confirmPassword to match', () => {
it('requires password and confirmPassword to match', async () => {
let api = requester();
let username = generateRandomUserName();
let email = `${username}@example.com`;
@@ -35,58 +34,58 @@ describe('POST /register', () => {
let confirmPassword = 'not password';
return expect(api.post('/register', {
username: username,
email: email,
password: password,
confirmPassword: confirmPassword,
username,
email,
password,
confirmPassword,
})).to.eventually.be.rejected.and.eql({
code: 401,
text: t('messageAuthPasswordMustMatch'),
});
});
it('requires a username', () => {
it('requires a username', async () => {
let api = requester();
let email = `${generateRandomUserName()}@example.com`;
let password = 'password';
let confirmPassword = 'password';
return expect(api.post('/register', {
email: email,
password: password,
confirmPassword: confirmPassword,
email,
password,
confirmPassword,
})).to.eventually.be.rejected.and.eql({
code: 401,
text: t('messageAuthCredentialsRequired'),
});
});
it('requires an email', () => {
it('requires an email', async () => {
let api = requester();
let username = generateRandomUserName();
let password = 'password';
let confirmPassword = 'password';
return expect(api.post('/register', {
username: username,
password: password,
confirmPassword: confirmPassword,
username,
password,
confirmPassword,
})).to.eventually.be.rejected.and.eql({
code: 401,
text: t('messageAuthCredentialsRequired'),
});
});
it('requires a password', () => {
it('requires a password', async () => {
let api = requester();
let username = generateRandomUserName();
let email = `${username}@example.com`;
let confirmPassword = 'password';
return expect(api.post('/register', {
username: username,
email: email,
confirmPassword: confirmPassword,
username,
email,
confirmPassword,
})).to.eventually.be.rejected.and.eql({
code: 401,
text: t('messageAuthCredentialsRequired'),
@@ -96,25 +95,25 @@ describe('POST /register', () => {
context('login is already taken', () => {
let username, email;
beforeEach(() => {
beforeEach(async () => {
username = generateRandomUserName();
email = `${username}@example.com`;
return generateUser({
'auth.local.username': username,
'auth.local.lowerCaseUsername': username,
'auth.local.email': email
'auth.local.email': email,
});
});
it('rejects if username is already taken', () => {
it('rejects if username is already taken', async () => {
let api = requester();
let uniqueEmail = `${generateRandomUserName()}@exampe.com`;
let password = 'password';
return expect(api.post('/register', {
username: username,
email: uniqueEmail,
password: password,
username,
email: uniqueEmail,
password,
confirmPassword: password,
})).to.eventually.be.rejected.and.eql({
code: 401,
@@ -122,15 +121,15 @@ describe('POST /register', () => {
});
});
it('rejects if email is already taken', () => {
it('rejects if email is already taken', async () => {
let api = requester();
let uniqueUsername = generateRandomUserName();
let password = 'password';
return expect(api.post('/register', {
username: uniqueUsername,
email: email,
password: password,
username: uniqueUsername,
email,
password,
confirmPassword: password,
})).to.eventually.be.rejected.and.eql({
code: 401,
@@ -142,33 +141,33 @@ describe('POST /register', () => {
context('successful login via api', () => {
let api, username, email, password;
beforeEach(() => {
beforeEach(async () => {
api = requester();
username = generateRandomUserName();
email = `${username}@example.com`;
password = 'password';
});
it('sets all site tour values to -2 (already seen)', () => {
it('sets all site tour values to -2 (already seen)', async () => {
return api.post('/register', {
username: username,
email: email,
password: password,
username,
email,
password,
confirmPassword: password,
}).then((user) => {
expect(user.flags.tour).to.not.be.empty;
each(user.flags.tour, (value, attribute) => {
each(user.flags.tour, (value) => {
expect(value).to.eql(-2);
});
});
});
it('populates user with default todos, not no other task types', () => {
it('populates user with default todos, not no other task types', async () => {
return api.post('/register', {
username: username,
email: email,
password: password,
username,
email,
password,
confirmPassword: password,
}).then((user) => {
expect(user.todos).to.not.be.empty;
@@ -178,11 +177,11 @@ describe('POST /register', () => {
});
});
it('populates user with default tags', () => {
it('populates user with default tags', async () => {
return api.post('/register', {
username: username,
email: email,
password: password,
username,
email,
password,
confirmPassword: password,
}).then((user) => {
expect(user.tags).to.not.be.empty;
@@ -193,33 +192,33 @@ describe('POST /register', () => {
context('successful login with habitica-web header', () => {
let api, username, email, password;
beforeEach(() => {
beforeEach(async () => {
api = requester({}, {'x-client': 'habitica-web'});
username = generateRandomUserName();
email = `${username}@example.com`;
password = 'password';
});
it('sets all common tutorial flags to true', () => {
it('sets all common tutorial flags to true', async () => {
return api.post('/register', {
username: username,
email: email,
password: password,
username,
email,
password,
confirmPassword: password,
}).then((user) => {
expect(user.flags.tour).to.not.be.empty;
each(user.flags.tutorial.common, (value, attribute) => {
each(user.flags.tutorial.common, (value) => {
expect(value).to.eql(true);
});
});
});
it('populates user with default todos, habits, and rewards', () => {
it('populates user with default todos, habits, and rewards', async () => {
return api.post('/register', {
username: username,
email: email,
password: password,
username,
email,
password,
confirmPassword: password,
}).then((user) => {
expect(user.todos).to.not.be.empty;
@@ -229,11 +228,11 @@ describe('POST /register', () => {
});
});
it('populates user with default tags', () => {
it('populates user with default tags', async () => {
return api.post('/register', {
username: username,
email: email,
password: password,
username,
email,
password,
confirmPassword: password,
}).then((user) => {
expect(user.tags).to.not.be.empty;
@@ -244,33 +243,33 @@ describe('POST /register', () => {
context('successful login with habitica-android header', () => {
let api, username, email, password;
beforeEach(() => {
beforeEach(async () => {
api = requester({}, {'x-client': 'habitica-android'});
username = generateRandomUserName();
email = `${username}@example.com`;
password = 'password';
});
it('sets all common tutorial flags to true', () => {
it('sets all common tutorial flags to true', async () => {
return api.post('/register', {
username: username,
email: email,
password: password,
username,
email,
password,
confirmPassword: password,
}).then((user) => {
expect(user.flags.tour).to.not.be.empty;
each(user.flags.tutorial.common, (value, attribute) => {
each(user.flags.tutorial.common, (value) => {
expect(value).to.eql(true);
});
});
});
it('populates user with default todos, habits, and rewards', () => {
it('populates user with default todos, habits, and rewards', async () => {
return api.post('/register', {
username: username,
email: email,
password: password,
username,
email,
password,
confirmPassword: password,
}).then((user) => {
expect(user.todos).to.not.be.empty;
@@ -280,11 +279,11 @@ describe('POST /register', () => {
});
});
it('populates user with default tags', () => {
it('populates user with default tags', async () => {
return api.post('/register', {
username: username,
email: email,
password: password,
username,
email,
password,
confirmPassword: password,
}).then((user) => {
expect(user.tags).to.not.be.empty;

View File

@@ -1,10 +1,9 @@
import {requester} from '../../../helpers/api-integration.helper';
describe('Status', () => {
it('returns a status of up when server is up', () => {
it('returns a status of up when server is up', async () => {
let api = requester();
return expect(api.get('/status'))
.to.eventually.eql({status: 'up'});
await expect(api.get('/status')).to.eventually.eql({status: 'up'});
});
});

View File

@@ -3,21 +3,18 @@ import {
createAndPopulateGroup,
generateGroup,
generateUser,
translate as t,
} from '../../../helpers/api-integration.helper';
import { find } from 'lodash';
describe('DELETE /user', () => {
let user;
beforeEach(() => {
return generateUser().then((usr) => {
user = usr;
});
beforeEach(async () => {
user = await generateUser();
});
it('deletes the user', () => {
return expect(user.del('/user').then((fetchedUser) => {
it('deletes the user', async () => {
return expect(user.del('/user').then(() => {
return checkExistence('users', user._id);
})).to.eventually.eql(false);
});
@@ -29,17 +26,17 @@ describe('DELETE /user', () => {
context('last member of a party', () => {
let party;
beforeEach(() => {
beforeEach(async () => {
return generateGroup(user, {
type: 'party',
privacy: 'private'
privacy: 'private',
}).then((group) => {
party = group;
});
});
it('deletes party when user is the only member', () => {
return expect(user.del('/user').then((result) => {
it('deletes party when user is the only member', async () => {
return expect(user.del('/user').then(() => {
return checkExistence('groups', party._id);
})).to.eventually.eql(false);
});
@@ -48,17 +45,17 @@ describe('DELETE /user', () => {
context('last member of a private guild', () => {
let guild;
beforeEach(() => {
beforeEach(async () => {
return generateGroup(user, {
type: 'guild',
privacy: 'private'
privacy: 'private',
}).then((group) => {
guild = group;
});
});
it('deletes guild when user is the only member', () => {
return expect(user.del('/user').then((result) => {
it('deletes guild when user is the only member', async () => {
return expect(user.del('/user').then(() => {
return checkExistence('groups', guild._id);
})).to.eventually.eql(false);
});
@@ -67,7 +64,7 @@ describe('DELETE /user', () => {
context('groups user is leader of', () => {
let group, oldLeader, newLeader;
beforeEach(() => {
beforeEach(async () => {
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
@@ -81,8 +78,8 @@ describe('DELETE /user', () => {
});
});
it('chooses new group leader for any group user was the leader of', () => {
return oldLeader.del('/user').then((res) => {
it('chooses new group leader for any group user was the leader of', async () => {
return oldLeader.del('/user').then(() => {
return newLeader.get(`/groups/${group._id}`);
}).then((guild) => {
expect(guild.leader).to.exist;
@@ -94,11 +91,11 @@ describe('DELETE /user', () => {
context('groups user is a part of', () => {
let group1, group2, userToDelete, otherUser;
beforeEach(() => {
beforeEach(async () => {
return generateUser({
balance: 10,
}).then((user) => {
userToDelete = user;
}).then((_user) => {
userToDelete = _user;
return generateGroup(userToDelete, {
type: 'guild',
@@ -122,8 +119,8 @@ describe('DELETE /user', () => {
});
});
it('removes user from all groups user was a part of', () => {
return userToDelete.del('/user').then((res) => {
it('removes user from all groups user was a part of', async () => {
return userToDelete.del('/user').then(() => {
return otherUser.get(`/groups/${group1._id}`);
}).then((fetchedGroup1) => {
expect(fetchedGroup1.members).to.be.empty;
@@ -139,13 +136,12 @@ describe('DELETE /user', () => {
expect(userInGroup).to.not.be.ok;
});
});
});
context('pending invitation to group', () => {
let group, userToDelete, otherUser;
beforeEach(() => {
beforeEach(async () => {
return createAndPopulateGroup({
groupDetails: {
type: 'guild',
@@ -160,8 +156,8 @@ describe('DELETE /user', () => {
});
});
it('removes invitations from groups', () => {
return userToDelete.del('/user').then((res) => {
it('removes invitations from groups', async () => {
return userToDelete.del('/user').then(() => {
return otherUser.get(`/groups/${group._id}`);
}).then((fetchedGroup) => {
expect(fetchedGroup.invites).to.have.a.lengthOf(1);

View File

@@ -10,19 +10,19 @@ describe('GET /user', () => {
user = await usr.get('/user');
});
it('gets the user object', () => {
it('gets the user object', async () => {
expect(user._id).to.eql(user._id);
expect(user.auth.local.username).to.eql(user.auth.local.username);
expect(user.todos).to.eql(user.todos);
expect(user.items).to.eql(user.items);
});
it('does not include password information', () => {
expect(user.auth.local.hashed_password).to.not.exist
expect(user.auth.local.salt).to.not.exist
it('does not include password information', async () => {
expect(user.auth.local.hashed_password).to.not.exist;
expect(user.auth.local.salt).to.not.exist;
});
it('does not include api token', () => {
expect(user.apiToken).to.not.exist
it('does not include api token', async () => {
expect(user.apiToken).to.not.exist;
});
});

View File

@@ -5,13 +5,11 @@ import {
describe('GET /user/tags', () => {
let user;
beforeEach(() => {
return generateUser().then((usr) => {
user = usr;
});
beforeEach(async () => {
user = await generateUser();
});
it('gets the user\'s tags', () => {
it('gets the user\'s tags', async () => {
return expect(user.get('/user/tags'))
.to.eventually.eql(user.tags);
});

View File

@@ -6,18 +6,16 @@ import {
describe('GET /user/tags/id', () => {
let user;
beforeEach(() => {
return generateUser().then((usr) => {
user = usr;
});
beforeEach(async () => {
user = await generateUser();
});
it('gets a user\'s tag by id', () => {
return expect(user.get('/user/tags/' + user.tags[0].id))
it('gets a user\'s tag by id', async () => {
return expect(user.get(`/user/tags/${user.tags[0].id}`))
.to.eventually.eql(user.tags[0]);
});
it('fails for non-existent tags', () => {
it('fails for non-existent tags', async () => {
return expect(user.get('/user/tags/not-an-id'))
.to.eventually.be.rejected.and.eql({
code: 404,

View File

@@ -8,44 +8,43 @@ import { each } from 'lodash';
describe('PUT /user', () => {
let user;
beforeEach(() => {
return generateUser().then((usr) => {
user = usr;
});
beforeEach(async () => {
user = await generateUser();
});
context('allowed operations', () => {
it('updates the user', () => {
return user.put('/user', {
'profile.name' : 'Frodo',
it('updates the user', async () => {
let updatedUser = await user.put('/user', {
'profile.name': 'Frodo',
'preferences.costume': true,
'stats.hp': 14,
}).then((updatedUser) => {
expect(updatedUser.profile.name).to.eql('Frodo');
expect(updatedUser.preferences.costume).to.eql(true);
expect(updatedUser.stats.hp).to.eql(14);
});
expect(updatedUser.profile.name).to.eql('Frodo');
expect(updatedUser.preferences.costume).to.eql(true);
expect(updatedUser.stats.hp).to.eql(14);
});
});
context('top level protected operations', () => {
let protectedOperations = {
'gem balance': {balance: 100},
'auth': {'auth.blocked': true, 'auth.timestamps.created': new Date()},
'contributor': {'contributor.level': 9, 'contributor.admin': true, 'contributor.text': 'some text'},
'backer': {'backer.tier': 10, 'backer.npc': 'Bilbo'},
'subscriptions': {'purchased.plan.extraMonths': 500, 'purchased.plan.consecutive.trinkets': 1000},
auth: {'auth.blocked': true, 'auth.timestamps.created': new Date()},
contributor: {'contributor.level': 9, 'contributor.admin': true, 'contributor.text': 'some text'},
backer: {'backer.tier': 10, 'backer.npc': 'Bilbo'},
subscriptions: {'purchased.plan.extraMonths': 500, 'purchased.plan.consecutive.trinkets': 1000},
'customization gem purchases': {'purchased.background.tavern': true, 'purchased.skin.bear': true},
'tasks': {todos: [], habits: [], dailys: [], rewards: []},
tasks: {todos: [], habits: [], dailys: [], rewards: []},
};
each(protectedOperations, (data, testName) => {
it(`does not allow updating ${testName}`, () => {
it(`does not allow updating ${testName}`, async () => {
let errorText = [];
each(data, (value, operation) => {
errorText.push(t('messageUserOperationProtected', { operation: operation }));
errorText.push(t('messageUserOperationProtected', { operation }));
});
return expect(user.put('/user', data)).to.eventually.be.rejected.and.eql({
await expect(user.put('/user', data)).to.eventually.be.rejected.and.eql({
code: 401,
text: errorText,
});
@@ -59,12 +58,13 @@ describe('PUT /user', () => {
};
each(protectedOperations, (data, testName) => {
it(`does not allow updating ${testName}`, () => {
it(`does not allow updating ${testName}`, async () => {
let errorText = [];
each(data, (value, operation) => {
errorText.push(t('messageUserOperationProtected', { operation: operation }));
errorText.push(t('messageUserOperationProtected', { operation }));
});
return expect(user.put('/user', data)).to.eventually.be.rejected.and.eql({
await expect(user.put('/user', data)).to.eventually.be.rejected.and.eql({
code: 401,
text: errorText,
});

View File

@@ -4,80 +4,77 @@ import {
import { each } from 'lodash';
describe('GET /user/anonymized', () => {
let user;
let user, anonymizedUser;
before(() => {
return generateUser({
'inbox.messages' : {
'the-message-id' : {
sort : 214,
user : 'Some user',
backer : {},
contributor : {
text : 'Blacksmith',
level : 2,
contributions : 'Made some contributions',
admin : false
before(async () => {
user = await generateUser({
'inbox.messages': {
'the-message-id': {
sort: 214,
user: 'Some user',
backer: {},
contributor: {
text: 'Blacksmith',
level: 2,
contributions: 'Made some contributions',
admin: false,
},
uuid : 'some-users-uuid',
flagCount : 0,
flags : {},
likes : {},
timestamp : 1444154258699.0000000000000000,
text : 'Lorem ipsum',
id : 'the-messages-id',
sent : true
}
}
}).then((usr) => {
user = usr;
return user.post('/user/tasks', {
text: 'some private text',
notes: 'some private notes',
checklist: [
{text: 'a private checklist'},
{text: 'another private checklist'},
],
type: 'daily',
});
}).then((result) => {
return user.get('/user/anonymized');
}).then((anonymizedUser) => {
user = anonymizedUser;
uuid: 'some-users-uuid',
flagCount: 0,
flags: {},
likes: {},
timestamp: 1444154258699.0000000000000000,
text: 'Lorem ipsum',
id: 'the-messages-id',
sent: true,
},
},
});
await user.post('/user/tasks', {
text: 'some private text',
notes: 'some private notes',
checklist: [
{text: 'a private checklist'},
{text: 'another private checklist'},
],
type: 'daily',
});
anonymizedUser = await user.get('/user/anonymized');
});
it('retains user id', () => {
expect(user._id).to.exist;
it('retains user id', async () => {
expect(anonymizedUser._id).to.eql(user._id);
});
it('removes credentials and financial information', () => {
expect(user.apiToken).to.not.exist;
expect(user.auth.local).to.not.exist;
expect(user.auth.facebook).to.not.exist;
expect(user.purchased.plan).to.not.exist;
it('removes credentials and financial information', async () => {
expect(anonymizedUser.apiToken).to.not.exist;
expect(anonymizedUser.auth.local).to.not.exist;
expect(anonymizedUser.auth.facebook).to.not.exist;
expect(anonymizedUser.purchased.plan).to.not.exist;
});
it('removes profile information', () => {
expect(user.profile).to.not.exist;
expect(user.contributor).to.not.exist;
expect(user.achievements.challenges).to.not.exist;
it('removes profile information', async () => {
expect(anonymizedUser.profile).to.not.exist;
expect(anonymizedUser.contributor).to.not.exist;
expect(anonymizedUser.achievements.challenges).to.not.exist;
});
it('removes social information', () => {
expect(user.newMessages).to.not.exist;
expect(user.invitations).to.not.exist;
expect(user.items.special.nyeReceived).to.not.exist;
expect(user.items.special.valentineReceived).to.not.exist;
it('removes social information', async () => {
expect(anonymizedUser.newMessages).to.not.exist;
expect(anonymizedUser.invitations).to.not.exist;
expect(anonymizedUser.items.special.nyeReceived).to.not.exist;
expect(anonymizedUser.items.special.valentineReceived).to.not.exist;
each(user.inbox.messages, (msg) => {
each(anonymizedUser.inbox.messages, (msg) => {
expect(msg.text).to.eql('inbox message text');
});
});
it('anonymizes task info', () => {
it('anonymizes task info', async () => {
each(['habits', 'todos', 'dailys', 'rewards'], (tasks) => {
each(user[tasks], (task) => {
each(anonymizedUser[tasks], (task) => {
expect(task.text).to.eql('task text');
expect(task.notes).to.eql('task notes');
@@ -88,14 +85,14 @@ describe('GET /user/anonymized', () => {
});
});
it('anonymizes tags', () => {
each(user.tags, (tag) => {
it('anonymizes tags', async () => {
each(anonymizedUser.tags, (tag) => {
expect(tag.name).to.eql('tag');
expect(tag.challenge).to.eql('challenge');
});
});
it('removes webhooks', () => {
expect(user.webhooks).to.not.exist;
it('removes webhooks', async () => {
expect(anonymizedUser.webhooks).to.not.exist;
});
});

View File

@@ -8,32 +8,26 @@ import { each } from 'lodash';
describe('POST /user/batch-update', () => {
let user;
beforeEach(() => {
return generateUser().then((usr) => {
user = usr;
});
beforeEach(async () => {
user = await generateUser();
});
context('allowed operations', () => {
it('makes batch operations', () => {
let task;
it('makes batch operations', async () => {
let task = (await user.get('/user/tasks'))[0];
return user.get('/user/tasks').then((tasks) => {
task = tasks[0];
let updatedUser = await user.post('/user/batch-update', [
{op: 'update', body: {'stats.hp': 30}},
{op: 'update', body: {'profile.name': 'Samwise'}},
{op: 'score', params: { direction: 'up', id: task.id }},
]);
return user.post('/user/batch-update', [
{op: 'update', body: {'stats.hp': 30}},
{op: 'update', body: {'profile.name': 'Samwise'}},
{op: 'score', params: { direction: 'up', id: task.id }},
]);
}).then((updatedUser) => {
expect(updatedUser.stats.hp).to.eql(30);
expect(updatedUser.profile.name).to.eql('Samwise');
expect(updatedUser.stats.hp).to.eql(30);
expect(updatedUser.profile.name).to.eql('Samwise');
return user.get(`/user/tasks/${task.id}`);
}).then((task) => {
expect(task.value).to.be.greaterThan(0);
});
let fetchedTask = await user.get(`/user/tasks/${task.id}`);
expect(fetchedTask.value).to.be.greaterThan(task.value);
});
});
@@ -44,26 +38,25 @@ describe('POST /user/batch-update', () => {
};
each(protectedOperations, (operation, description) => {
it(`it sends back a 500 error for ${description} operation`, () => {
it(`it sends back a 500 error for ${description} operation`, async () => {
return expect(user.post('/user/batch-update', [
{ op: operation },
])).to.eventually.be.rejected.and.eql({
code: 500,
text: t('messageUserOperationNotFound', { operation }),
});
code: 500,
text: t('messageUserOperationNotFound', { operation }),
});
});
});
});
context('unknown operations', () => {
it('sends back a 500 error', () => {
it('sends back a 500 error', async () => {
return expect(user.post('/user/batch-update', [
{op: 'aNotRealOperation'},
])).to.eventually.be.rejected.and.eql({
code: 500,
text: t('messageUserOperationNotFound', { operation: 'aNotRealOperation' }),
});
code: 500,
text: t('messageUserOperationNotFound', { operation: 'aNotRealOperation' }),
});
});
});
});

View File

@@ -5,13 +5,11 @@ import {
describe('POST /user/pushDevice', () => {
let user;
beforeEach(() => {
return generateUser().then((_user) => {
user = _user;
});
beforeEach(async () => {
user = await generateUser();
});
it('registers a device id', () => {
it('registers a device id', async () => {
return user.post('/user/pushDevice', {
regId: '123123',
type: 'android',

View File

@@ -6,32 +6,29 @@ import {
describe('DELETE /user/tasks/:id', () => {
let user, task;
beforeEach(() => {
return generateUser().then((_user) => {
user = _user;
task = user.todos[0];
beforeEach(async () => {
user = await generateUser();
task = user.todos[0];
});
it('deletes a task', async () => {
await user.del(`/user/tasks/${task.id}`);
await expect(user.get(`/user/tasks/${task.id}`)).to.eventually.be.rejected.and.eql({
code: 404,
text: t('messageTaskNotFound'),
});
});
it('deletes a task', () => {
return expect(user.del(`/user/tasks/${task.id}`)
.then((res) => {
return user.get(`/user/tasks/${task.id}`);
})).to.eventually.be.rejected.and.eql({
code: 404,
text: t('messageTaskNotFound'),
});
});
it('returns an error if the task does not exist', () => {
it('returns an error if the task does not exist', async () => {
return expect(user.del('/user/tasks/task-that-does-not-exist'))
.to.eventually.be.rejected.and.eql({
code: 404,
text: t('messageTaskNotFound'),
});
});
});
it('does not delete another user\'s task', () => {
it('does not delete another user\'s task', async () => {
return expect(generateUser().then((otherUser) => {
let otherUsersTask = otherUser.todos[0];
return user.del(`/user/tasks/${otherUsersTask.id}`);

View File

@@ -1,12 +1,11 @@
import {
generateUser,
translate as t,
} from '../../../../helpers/api-integration.helper';
describe('GET /user/tasks/', () => {
let user;
beforeEach(() => {
beforeEach(async () => {
return generateUser({
dailys: [
{text: 'daily', type: 'daily'},
@@ -19,7 +18,7 @@ describe('GET /user/tasks/', () => {
});
});
it('gets all tasks', () => {
it('gets all tasks', async () => {
return user.get(`/user/tasks/`).then((tasks) => {
expect(tasks).to.be.an('array');
expect(tasks.length).to.be.greaterThan(3);

View File

@@ -6,14 +6,12 @@ import {
describe('GET /user/tasks/:id', () => {
let user, task;
beforeEach(() => {
return generateUser().then((_user) => {
user = _user;
task = user.todos[0];
});
beforeEach(async () => {
user = await generateUser();
task = user.todos[0];
});
it('gets a task', () => {
it('gets a task', async () => {
return user.get(`/user/tasks/${task.id}`).then((foundTask) => {
expect(foundTask.id).to.eql(task.id);
expect(foundTask.text).to.eql(task.text);
@@ -23,15 +21,15 @@ describe('GET /user/tasks/:id', () => {
});
});
it('returns an error if the task does not exist', () => {
it('returns an error if the task does not exist', async () => {
return expect(user.get('/user/tasks/task-that-does-not-exist'))
.to.eventually.be.rejected.and.eql({
code: 404,
text: t('messageTaskNotFound'),
});
});
});
it('does not get another user\'s task', () => {
it('does not get another user\'s task', async () => {
return expect(generateUser().then((otherUser) => {
let otherUsersTask = otherUser.todos[0];

View File

@@ -4,27 +4,24 @@ import {
} from '../../../../helpers/api-integration.helper';
describe('POST /user/tasks', () => {
let user;
beforeEach(() => {
return generateUser().then((_user) => {
user = _user;
});
beforeEach(async () => {
user = await generateUser();
});
it('creates a task', () => {
it('creates a task', async () => {
return user.post('/user/tasks').then((task) => {
expect(task.id).to.exist;
});
});
it('creates a habit by default', () => {
it('creates a habit by default', async () => {
return expect(user.post('/user/tasks'))
.to.eventually.have.property('type', 'habit');
});
it('creates a task with specified values', () => {
it('creates a task with specified values', async () => {
return user.post('/user/tasks', {
type: 'daily',
text: 'My task',
@@ -38,7 +35,7 @@ describe('POST /user/tasks', () => {
});
});
it('does not create a task with an id that already exists', () => {
it('does not create a task with an id that already exists', async () => {
let todo = user.todos[0];
return expect(user.post('/user/tasks', {
@@ -49,7 +46,7 @@ describe('POST /user/tasks', () => {
});
});
xit('TODO: no error is thrown - throws a 500 validation error if invalid type is posted', () => {
xit('TODO: no error is thrown - throws a 500 validation error if invalid type is posted', async () => {
return expect(user.post('/user/tasks', {
type: 'not-valid',
})).to.eventually.be.rejected.and.eql({
@@ -58,7 +55,7 @@ describe('POST /user/tasks', () => {
});
});
xit('TODO: no error is thrown - throws a 500 validation error if invalid data is posted', () => {
xit('TODO: no error is thrown - throws a 500 validation error if invalid data is posted', async () => {
return expect(user.post('/user/tasks', {
frequency: 'not-valid',
})).to.eventually.be.rejected.and.eql({

View File

@@ -1,19 +1,16 @@
import {
generateUser,
translate as t,
} from '../../../../helpers/api-integration.helper';
describe('PUT /user/tasks/:id', () => {
let user, task;
beforeEach(() => {
return generateUser().then((_user) => {
user = _user;
task = user.todos[0];
});
beforeEach(async () => {
user = await generateUser();
task = user.todos[0];
});
it('does not update the id of the task', () => {
it('does not update the id of the task', async () => {
return user.put(`/user/tasks/${task.id}`, {
id: 'some-thing',
}).then((updatedTask) => {
@@ -22,7 +19,7 @@ describe('PUT /user/tasks/:id', () => {
});
});
it('does not update the type of the task', () => {
it('does not update the type of the task', async () => {
return user.put(`/user/tasks/${task.id}`, {
type: 'habit',
}).then((updatedTask) => {
@@ -31,23 +28,23 @@ describe('PUT /user/tasks/:id', () => {
});
});
it('updates text, attribute, priority, value and notes', () => {
it('updates text, attribute, priority, value and notes', async () => {
return user.put(`/user/tasks/${task.id}`, {
text: 'new text',
notes: 'new notes',
value: 10000,
priority: .5,
priority: 0.5,
attribute: 'str',
}).then((updatedTask) => {
expect(updatedTask.text).to.eql('new text');
expect(updatedTask.notes).to.eql('new notes');
expect(updatedTask.value).to.eql(10000);
expect(updatedTask.priority).to.eql(.5);
expect(updatedTask.priority).to.eql(0.5);
expect(updatedTask.attribute).to.eql('str');
});
});
it('returns an error if the task does not exist', () => {
it('returns an error if the task does not exist', async () => {
return expect(user.put('/user/tasks/task-id-that-does-not-exist'))
.to.eventually.be.rejected.and.eql({
code: 404,
@@ -55,7 +52,7 @@ describe('PUT /user/tasks/:id', () => {
});
});
it('does not update another user\'s task', () => {
it('does not update another user\'s task', async () => {
return expect(generateUser().then((otherUser) => {
let otherUsersTask = otherUser.todos[0];
return user.put(`/user/tasks/${otherUsersTask._id}`, {

View File

@@ -4,7 +4,7 @@ h2 12/30/2015 - NEW YEAR'S EVE CELEBRATION: PARTY HATS, NEW YEAR'S CARDS, BEEMIN
td
.npc_matt.pull-right
h3 Party Hats
p In honor of the new year, some free Party Hats are available in the Rewards store! New users get the ever-handsome Absurd Party Hat, and users who already received one last year get the Silly Party Hat or the new Ridiculous Party Hat. These hats will be available to purchase until January 31st, but once you've bought them, you'll have them forever. Enjoy!
p In honor of the new year, there's a free Party Hat available in the Rewards store! New users get the ever-handsome Absurd Party Hat, and users who already received one last year get the Silly Party Hat or the new Ridiculous Party Hat. These hats will be available to purchase until January 31st, but once you've bought them, you'll have them forever. Enjoy!
p.small.muted by Lemoness and SabreCat
tr
td