From ffbd4696e32b6ba813e11f54cd7108457462a0a8 Mon Sep 17 00:00:00 2001 From: Keith Holliday Date: Mon, 11 Jan 2016 12:35:46 -0600 Subject: [PATCH 1/4] Converted posts tests to async/await syntax and updated tests --- common/locales/en/api-v3.json | 3 +- .../v3/integration/groups/POST-groups.test.js | 167 ++++++++++-------- website/src/controllers/api-v3/groups.js | 1 + 3 files changed, 101 insertions(+), 70 deletions(-) diff --git a/common/locales/en/api-v3.json b/common/locales/en/api-v3.json index 2ace1f7773..1f77e456aa 100644 --- a/common/locales/en/api-v3.json +++ b/common/locales/en/api-v3.json @@ -46,5 +46,6 @@ "winnerIdRequired": "\"winnerId\" must be a valid UUID.", "challengeNotFound": "Challenge not found.", "onlyLeaderDeleteChal": "Only the challenge leader can delete it.", - "winnerNotFound": "Winner with id \"<%= userId %>\" not found or not part of the challenge." + "winnerNotFound": "Winner with id \"<%= userId %>\" not found or not part of the challenge.", + "partyMustbePrivate": "Parties must be private" } diff --git a/test/api/v3/integration/groups/POST-groups.test.js b/test/api/v3/integration/groups/POST-groups.test.js index 0d3a622581..f0ac8b9aba 100644 --- a/test/api/v3/integration/groups/POST-groups.test.js +++ b/test/api/v3/integration/groups/POST-groups.test.js @@ -6,21 +6,34 @@ import { describe('POST /group', () => { let user; - beforeEach(() => { - return generateUser().then((generatedUser) => { - user = generatedUser; + beforeEach(async () => { + user = await generateUser(); + }); + + context('All Groups', () => { + it('it returns validation error when type is not provided', async () => { + let userToCreateGroup = await generateUser({balance: 1}); + await expect(userToCreateGroup.post('/groups', { name: 'Test Group Without Type' })) + .to.eventually.be.rejected.and.eql({ + code: 400, + error: 'BadRequest', + message: 'Group validation failed', + }); }); }); context('Guilds', () => { - it('returns an error when a user with insufficient funds attempts to create a guild', () => { - let groupName = 'Test Public Guild'; - let groupType = 'guild'; + let userToCreateGuild; - return expect( + beforeEach(async () => { + userToCreateGuild = await generateUser({balance: 1}); + }); + + it('returns an error when a user with insufficient funds attempts to create a guild', async () => { + await expect( user.post('/groups', { - name: groupName, - type: groupType, + name: 'Test Public Guild', + type: 'guild', }) ) .to.eventually.be.rejected.and.eql({ @@ -31,84 +44,100 @@ describe('POST /group', () => { }); context('public guild', () => { - it('creates a group', () => { + it('creates a group', async () => { let groupName = 'Test Public Guild'; let groupType = 'guild'; - - return generateUser({balance: 1}).then((generatedUser) => { - return generatedUser.post('/groups', { - name: groupName, - type: groupType, - }); - }) - .then((result) => { - expect(result._id).to.exist; - expect(result.name).to.equal(groupName); - expect(result.type).to.equal(groupType); - expect(result.memberCount).to.equal(1); + let groupPrivacy = 'public'; + let publicGuild = await userToCreateGuild.post('/groups', { + name: groupName, + type: groupType, + privacy: groupPrivacy, }); + + expect(publicGuild._id).to.exist; + expect(publicGuild.name).to.equal(groupName); + expect(publicGuild.type).to.equal(groupType); + expect(publicGuild.memberCount).to.equal(1); + expect(publicGuild.privacy).to.equal(groupPrivacy); }); }); context('private guild', () => { - it('creates a group', () => { - let groupName = 'Test Private Guild'; - let groupType = 'guild'; - let groupPrivacy = 'private'; + let groupName = 'Test Private Guild'; + let groupType = 'guild'; + let groupPrivacy = 'private'; - return generateUser({balance: 1}).then((generatedUser) => { - return generatedUser.post('/groups', { - name: groupName, - type: groupType, - privacy: groupPrivacy, - }); - }) - .then((result) => { - expect(result._id).to.exist; - expect(result.name).to.equal(groupName); - expect(result.type).to.equal(groupType); - expect(result.memberCount).to.equal(1); - expect(result.privacy).to.equal(groupPrivacy); + it('creates a group', async () => { + let privateGuild = await userToCreateGuild.post('/groups', { + name: groupName, + type: groupType, + privacy: groupPrivacy, }); + + expect(privateGuild._id).to.exist; + expect(privateGuild.name).to.equal(groupName); + expect(privateGuild.type).to.equal(groupType); + expect(privateGuild.memberCount).to.equal(1); + expect(privateGuild.privacy).to.equal(groupPrivacy); + }); + + it('deducts gems from user and adds them to guild bank', async () => { + let privateGuild = await userToCreateGuild.post('/groups', { + name: groupName, + type: groupType, + privacy: groupPrivacy, + }); + + expect(privateGuild.balance).to.eql(1); + + let updatedUser = await userToCreateGuild.get('/user'); + + expect(updatedUser.balance).to.eql(0); }); }); }); context('Parties', () => { - it('creates a party', () => { - let groupName = 'Test Party'; - let groupType = 'party'; + let partyName = 'Test Party'; + let partyType = 'party'; - return user.post('/groups', { - name: groupName, - type: groupType, - }) - .then((result) => { - expect(result._id).to.exist; - expect(result.name).to.equal(groupName); - expect(result.type).to.equal(groupType); - expect(result.memberCount).to.equal(1); + it('creates a party', async () => { + let party = await user.post('/groups', { + name: partyName, + type: partyType, + }); + + expect(party._id).to.exist; + expect(party.name).to.equal(partyName); + expect(party.type).to.equal(partyType); + expect(party.memberCount).to.equal(1); + }); + + it('prevents user in a party from creating another party', async () => { + let userToCreateTwoParties = await generateUser(); + + await userToCreateTwoParties.post('/groups', { + name: partyName, + type: partyType, + }); + + await expect(userToCreateTwoParties.post('/groups')) + .to.eventually.be.rejected.and.eql({ + code: 401, + error: 'NotAuthorized', + message: t('messageGroupAlreadyInParty'), }); }); - it('prevents user in a party from creating another party', () => { - let tmpUser; - let groupName = 'Test Party'; - let groupType = 'party'; - - return generateUser().then((generatedUser) => { - tmpUser = generatedUser; - return tmpUser.post('/groups', { - name: groupName, - type: groupType, - }); - }) - .then(() => { - return expect(tmpUser.post('/groups')).to.eventually.be.rejected.and.eql({ - code: 401, - error: 'NotAuthorized', - message: t('messageGroupAlreadyInParty'), - }); + it('prevents creating a public party', async () => { + await expect(user.post('/groups', { + name: partyName, + type: partyType, + privacy: 'public', + })).to.eventually.be.rejected.and.eql({ + code: 401, + error: 'NotAuthorized', + message: t('partyMustbePrivate'), }); }); }); diff --git a/website/src/controllers/api-v3/groups.js b/website/src/controllers/api-v3/groups.js index 80b2972217..8604337648 100644 --- a/website/src/controllers/api-v3/groups.js +++ b/website/src/controllers/api-v3/groups.js @@ -43,6 +43,7 @@ api.createGroup = { user.balance--; user.guilds.push(group._id); } else { + if (group.privacy === 'public') throw new NotAuthorized(res.t('partyMustbePrivate')); if (user.party._id) throw new NotAuthorized(res.t('messageGroupAlreadyInParty')); user.party._id = group._id; From fffa95ca09748a7b6a8dde86e9a9267e1ee87068 Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Tue, 12 Jan 2016 08:11:19 -0600 Subject: [PATCH 2/4] refactor: Test against party not being private, instead of public --- website/src/controllers/api-v3/groups.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/src/controllers/api-v3/groups.js b/website/src/controllers/api-v3/groups.js index 8604337648..13ddf76d64 100644 --- a/website/src/controllers/api-v3/groups.js +++ b/website/src/controllers/api-v3/groups.js @@ -31,7 +31,6 @@ api.createGroup = { middlewares: [authWithHeaders(), cron], async handler (req, res) { let user = res.locals.user; - let group = new Group(Group.sanitize(req.body)); // TODO validate empty req.body group.leader = user._id; @@ -43,7 +42,7 @@ api.createGroup = { user.balance--; user.guilds.push(group._id); } else { - if (group.privacy === 'public') throw new NotAuthorized(res.t('partyMustbePrivate')); + if (group.privacy !== 'private') throw new NotAuthorized(res.t('partyMustbePrivate')); if (user.party._id) throw new NotAuthorized(res.t('messageGroupAlreadyInParty')); user.party._id = group._id; @@ -54,6 +53,7 @@ api.createGroup = { firebase.updateGroupData(savedGroup); firebase.addUserToGroup(savedGroup._id, user._id); + return res.respond(201, savedGroup); // TODO populate }, }; From 88755e69ae4f85f88b68973bb51231808e70a44b Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Tue, 12 Jan 2016 08:14:12 -0600 Subject: [PATCH 3/4] tests(api): Simplify tests --- .../v3/integration/groups/POST-groups.test.js | 38 ++++++++----------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/test/api/v3/integration/groups/POST-groups.test.js b/test/api/v3/integration/groups/POST-groups.test.js index f0ac8b9aba..99b263353f 100644 --- a/test/api/v3/integration/groups/POST-groups.test.js +++ b/test/api/v3/integration/groups/POST-groups.test.js @@ -7,36 +7,30 @@ describe('POST /group', () => { let user; beforeEach(async () => { - user = await generateUser(); + user = await generateUser({ balance: 10 }); }); context('All Groups', () => { it('it returns validation error when type is not provided', async () => { - let userToCreateGroup = await generateUser({balance: 1}); - await expect(userToCreateGroup.post('/groups', { name: 'Test Group Without Type' })) - .to.eventually.be.rejected.and.eql({ + await expect( + user.post('/groups', { name: 'Test Group Without Type' }) + ).to.eventually.be.rejected.and.eql({ code: 400, error: 'BadRequest', message: 'Group validation failed', }); }); - }); context('Guilds', () => { - let userToCreateGuild; - - beforeEach(async () => { - userToCreateGuild = await generateUser({balance: 1}); - }); - it('returns an error when a user with insufficient funds attempts to create a guild', async () => { + await user.update({ balance: 0 }); + await expect( user.post('/groups', { name: 'Test Public Guild', type: 'guild', }) - ) - .to.eventually.be.rejected.and.eql({ + ).to.eventually.be.rejected.and.eql({ code: 401, error: 'NotAuthorized', message: t('messageInsufficientGems'), @@ -48,7 +42,8 @@ describe('POST /group', () => { let groupName = 'Test Public Guild'; let groupType = 'guild'; let groupPrivacy = 'public'; - let publicGuild = await userToCreateGuild.post('/groups', { + + let publicGuild = await user.post('/groups', { name: groupName, type: groupType, privacy: groupPrivacy, @@ -68,7 +63,7 @@ describe('POST /group', () => { let groupPrivacy = 'private'; it('creates a group', async () => { - let privateGuild = await userToCreateGuild.post('/groups', { + let privateGuild = await user.post('/groups', { name: groupName, type: groupType, privacy: groupPrivacy, @@ -82,7 +77,7 @@ describe('POST /group', () => { }); it('deducts gems from user and adds them to guild bank', async () => { - let privateGuild = await userToCreateGuild.post('/groups', { + let privateGuild = await user.post('/groups', { name: groupName, type: groupType, privacy: groupPrivacy, @@ -90,9 +85,9 @@ describe('POST /group', () => { expect(privateGuild.balance).to.eql(1); - let updatedUser = await userToCreateGuild.get('/user'); + let updatedUser = await user.get('/user'); - expect(updatedUser.balance).to.eql(0); + expect(updatedUser.balance).to.eql(user.balance - 1); }); }); }); @@ -114,15 +109,12 @@ describe('POST /group', () => { }); it('prevents user in a party from creating another party', async () => { - let userToCreateTwoParties = await generateUser(); - - await userToCreateTwoParties.post('/groups', { + await user.post('/groups', { name: partyName, type: partyType, }); - await expect(userToCreateTwoParties.post('/groups')) - .to.eventually.be.rejected.and.eql({ + await expect(user.post('/groups')).to.eventually.be.rejected.and.eql({ code: 401, error: 'NotAuthorized', message: t('messageGroupAlreadyInParty'), From 36cd9e94306e35339c06be07e433e24a77dabf5d Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Tue, 12 Jan 2016 08:14:50 -0600 Subject: [PATCH 4/4] tests(api): Increase test coverage for group post tests --- .../v3/integration/groups/POST-groups.test.js | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/test/api/v3/integration/groups/POST-groups.test.js b/test/api/v3/integration/groups/POST-groups.test.js index 99b263353f..3515f07cec 100644 --- a/test/api/v3/integration/groups/POST-groups.test.js +++ b/test/api/v3/integration/groups/POST-groups.test.js @@ -21,6 +21,26 @@ describe('POST /group', () => { }); }); + it('it returns validation error when type is not supported', async () => { + await expect( + user.post('/groups', { name: 'Group with unsupported type', type: 'foo' }) + ).to.eventually.be.rejected.and.eql({ + code: 400, + error: 'BadRequest', + message: 'Group validation failed', + }); + }); + + it('sets the group leader to the user who created the group', async () => { + await expect( + user.post('/groups', { + name: 'Test Public Guild', + type: 'guild', + }) + ).to.eventually.have.property('leader', user._id); + }); + }); + context('Guilds', () => { it('returns an error when a user with insufficient funds attempts to create a guild', async () => { await user.update({ balance: 0 }); @@ -37,6 +57,18 @@ describe('POST /group', () => { }); }); + it('adds guild to user\'s list of guilds', async () => { + let guild = await user.post('/groups', { + name: 'some guild', + type: 'guild', + privacy: 'public', + }); + + let updatedUser = await user.get('/user'); + + expect(updatedUser.guilds).to.include(guild._id); + }); + context('public guild', () => { it('creates a group', async () => { let groupName = 'Test Public Guild'; @@ -108,6 +140,32 @@ describe('POST /group', () => { expect(party.memberCount).to.equal(1); }); + it('does not require gems to create a party', async () => { + await user.update({ balance: 0 }); + + let party = await user.post('/groups', { + name: partyName, + type: partyType, + }); + + expect(party._id).to.exist; + + let updatedUser = await user.get('/user'); + + expect(updatedUser.balance).to.eql(user.balance); + }); + + it('sets party id on user object', async () => { + let party = await user.post('/groups', { + name: partyName, + type: partyType, + }); + + let updatedUser = await user.get('/user'); + + expect(updatedUser.party._id).to.eql(party._id); + }); + it('prevents user in a party from creating another party', async () => { await user.post('/groups', { name: partyName,