From 6c8da9a53add54c3edc84ed63e916ba390842d05 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Sat, 27 Feb 2016 17:46:00 +0100 Subject: [PATCH] fix user schema definition and add missing schema --- .../groups/POST-groups_groupId_join.test.js | 21 ++++++++++------ website/src/controllers/api-v3/groups.js | 11 ++++---- website/src/models/user.js | 25 +++++++++---------- 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/test/api/v3/integration/groups/POST-groups_groupId_join.test.js b/test/api/v3/integration/groups/POST-groups_groupId_join.test.js index b9b759bed9..c245bee42a 100644 --- a/test/api/v3/integration/groups/POST-groups_groupId_join.test.js +++ b/test/api/v3/integration/groups/POST-groups_groupId_join.test.js @@ -7,6 +7,8 @@ import { import { v4 as generateUUID } from 'uuid'; describe('POST /group/:groupId/join', () => { + const PET_QUEST = 'whale'; + it('returns error when groupId is not for a valid group', async () => { let joiningUser = await generateUser(); @@ -135,6 +137,7 @@ describe('POST /group/:groupId/join', () => { name: 'Test Party', type: 'party', }, + members: 2, invites: 1, }); @@ -205,18 +208,20 @@ describe('POST /group/:groupId/join', () => { await expect(checkExistence('groups', oldParty._id)).to.eventually.equal(false); }); - xit('invites joining member to active quest', async () => { - // TODO start quest + it('invites joining member to active quest', async () => { + await user.update({ + [`items.quests.${PET_QUEST}`]: 1, + }); + await user.post(`/groups/${party._id}/quests/invite/${PET_QUEST}`); await invitedUser.post(`/groups/${party._id}/join`); - invitedUser = await user.get('/user'); - party = await user.get(`/groups/${party._id}`); + await invitedUser.sync(); + await party.sync(); - expect(user).to.have.deep.property('party.quest.RSVPNeeded', true); - expect(user).to.have.deep.property('party.quest.key', party.quest.key); - - expect(party.quest.members[invitedUser._id]).to.be.undefined; + expect(invitedUser).to.have.deep.property('party.quest.RSVPNeeded', true); + expect(invitedUser).to.have.deep.property('party.quest.key', party.quest.key); + expect(party.quest.members[invitedUser._id]).to.be.null; }); }); }); diff --git a/website/src/controllers/api-v3/groups.js b/website/src/controllers/api-v3/groups.js index 05925d5730..d3c77aa3a1 100644 --- a/website/src/controllers/api-v3/groups.js +++ b/website/src/controllers/api-v3/groups.js @@ -251,16 +251,16 @@ api.joinGroup = { let isUserInvited = false; - if (group.type === 'party' && group._id === (user.invitations.party && user.invitations.party.id)) { + if (group.type === 'party' && group._id === user.invitations.party.id) { inviter = user.invitations.party.inviter; - user.invitations.party = {}; // Clear invite TODO mark modified? + user.invitations.party = {}; // Clear invite + user.markModified('invitations.party'); // invite new user to pending quest if (group.quest.key && !group.quest.active) { user.party.quest.RSVPNeeded = true; user.party.quest.key = group.quest.key; - user.party.quest.progress = undefined; // Make sure to reset progress from ay previous quest - group.quest.members[user._id] = undefined; + group.quest.members[user._id] = null; group.markModified('quest.members'); } @@ -459,7 +459,6 @@ api.removeGroupMember = { }; async function _inviteByUUID (uuid, group, inviter, req, res) { - // TODO: Add Push Notifications let userToInvite = await User.findById(uuid).exec(); if (!userToInvite) { @@ -475,7 +474,7 @@ async function _inviteByUUID (uuid, group, inviter, req, res) { } userToInvite.invitations.guilds.push({id: group._id, name: group.name, inviter: inviter._id}); } else if (group.type === 'party') { - if (!_.isEmpty(userToInvite.invitations.party)) { + if (userToInvite.invitations.party.id) { throw new NotAuthorized(res.t('userAlreadyPendingInvitation')); } diff --git a/website/src/models/user.js b/website/src/models/user.js index 9f59b4c143..71138aebe6 100644 --- a/website/src/models/user.js +++ b/website/src/models/user.js @@ -136,7 +136,7 @@ export let schema = new Schema({ dateUpdated: Date, extraMonths: {type: Number, default: 0}, gemsBought: {type: Number, default: 0}, - mysteryItems: {type: Array, default: []}, + mysteryItems: {type: Array, default: () => []}, lastBillingDate: Date, // Used only for Amazon Payments to keep track of billing date consecutive: { count: {type: Number, default: 0}, @@ -348,16 +348,15 @@ export let schema = new Schema({ challenges: [{type: String, ref: 'Challenge', validate: [validator.isUUID, 'Invalid uuid.']}], invitations: { - guilds: [{ - id: {type: String, ref: 'Group', validate: [validator.isUUID, 'Invalid uuid.']}, - name: String, - inviter: {type: String, ref: 'User', validate: [validator.isUUID, 'Invalid uuid.']}, - }], - party: { - id: {type: String, ref: 'Group', validate: [validator.isUUID, 'Invalid uuid.']}, - name: String, - inviter: {type: String, ref: 'User', validate: [validator.isUUID, 'Invalid uuid.']}, - }, + // Using an array without validation because otherwise mongoose treat this as a subdocument and applies _id by default + // Schema is (id, name, inviter) + // TODO one way to fix is http://mongoosejs.com/docs/guide.html#_id + guilds: {type: Array, default: () => []}, + // Using a Mixed type because otherwise user.invitations.party = {} // to reset invitation, causes validation to fail TODO + // schema is the same as for guild invitations (id, name, inviter) + party: {type: Schema.Types.Mixed, default: () => { + return {}; + }}, }, guilds: [{type: String, ref: 'Group', validate: [validator.isUUID, 'Invalid uuid.']}], @@ -483,7 +482,7 @@ export let schema = new Schema({ inbox: { newMessages: {type: Number, default: 0}, - blocks: {type: Array, default: []}, + blocks: {type: Array, default: () => []}, messages: {type: Schema.Types.Mixed, default: () => { return {}; }}, @@ -504,7 +503,7 @@ export let schema = new Schema({ regId: {type: String}, type: {type: String}, }], - default: [], + default: () => [], }, }, { strict: true,