From c9a56e8f3e3114bae915275ad8f2e0ca8a35868d Mon Sep 17 00:00:00 2001 From: negue Date: Mon, 15 Jul 2019 11:25:22 +0200 Subject: [PATCH] Performance/inbox paging (#11258) * merge all changes to one commit of PR #11157 / #11226 * rename the new paged messages route * rename event, move map-method to the Inbox schema, fix lint * move `mapMessage`-call to `getUserInbox` * revert schema.method back to a normal one --- .../inbox/GET-inbox_messages.test.js | 2 +- .../DELETE-inbox_messages_messageId.test.js | 6 +- .../v4/inbox/GET-inbox-conversations.test.js | 49 +++- .../members/POST-flag_private_message.test.js | 8 +- website/client/components/chat/chatCard.vue | 3 + .../client/components/chat/chatMessages.vue | 82 ++++++- website/client/components/userMenu/inbox.vue | 210 ++++++++++++------ website/common/locales/en/generic.json | 3 +- website/server/controllers/api-v3/members.js | 23 +- website/server/controllers/api-v4/inbox.js | 30 ++- website/server/libs/inbox/index.js | 72 ++++-- website/server/models/message.js | 25 ++- 12 files changed, 387 insertions(+), 126 deletions(-) diff --git a/test/api/v3/integration/inbox/GET-inbox_messages.test.js b/test/api/v3/integration/inbox/GET-inbox_messages.test.js index c0c86a8a00..491b444cab 100644 --- a/test/api/v3/integration/inbox/GET-inbox_messages.test.js +++ b/test/api/v3/integration/inbox/GET-inbox_messages.test.js @@ -6,7 +6,7 @@ describe('GET /inbox/messages', () => { let user; let otherUser; - before(async () => { + beforeEach(async () => { [user, otherUser] = await Promise.all([generateUser(), generateUser()]); await otherUser.post('/members/send-private-message', { diff --git a/test/api/v4/inbox/DELETE-inbox_messages_messageId.test.js b/test/api/v4/inbox/DELETE-inbox_messages_messageId.test.js index 5f4e502147..99365daf8f 100644 --- a/test/api/v4/inbox/DELETE-inbox_messages_messageId.test.js +++ b/test/api/v4/inbox/DELETE-inbox_messages_messageId.test.js @@ -44,7 +44,7 @@ describe('DELETE /inbox/messages/:messageId', () => { }); it('deletes one message', async () => { - const messages = await user.get('/inbox/messages'); + const messages = await user.get('/inbox/paged-messages'); expect(messages.length).to.equal(3); @@ -53,10 +53,10 @@ describe('DELETE /inbox/messages/:messageId', () => { expect(messages[2].text).to.equal('first'); await user.del(`/inbox/messages/${messages[1]._id}`); - const updatedMessages = await user.get('/inbox/messages'); + const updatedMessages = await user.get('/inbox/paged-messages'); expect(updatedMessages.length).to.equal(2); expect(updatedMessages[0].text).to.equal('third'); expect(updatedMessages[1].text).to.equal('first'); }); -}); \ No newline at end of file +}); diff --git a/test/api/v4/inbox/GET-inbox-conversations.test.js b/test/api/v4/inbox/GET-inbox-conversations.test.js index 33131b871a..749755721b 100644 --- a/test/api/v4/inbox/GET-inbox-conversations.test.js +++ b/test/api/v4/inbox/GET-inbox-conversations.test.js @@ -7,7 +7,7 @@ describe('GET /inbox/conversations', () => { let otherUser; let thirdUser; - before(async () => { + beforeEach(async () => { [user, otherUser, thirdUser] = await Promise.all([generateUser(), generateUser(), generateUser()]); await otherUser.post('/members/send-private-message', { @@ -41,4 +41,51 @@ describe('GET /inbox/conversations', () => { expect(result[0].user).to.be.equal(user.profile.name); expect(result[0].username).to.be.equal(user.auth.local.username); }); + + it('returns the user inbox messages as an array of ordered messages (from most to least recent)', async () => { + const messages = await user.get('/inbox/paged-messages'); + + expect(messages.length).to.equal(5); + + // message to yourself + expect(messages[0].text).to.equal('fifth'); + expect(messages[0].sent).to.equal(false); + expect(messages[0].uuid).to.equal(user._id); + + expect(messages[1].text).to.equal('fourth'); + expect(messages[2].text).to.equal('third'); + expect(messages[3].text).to.equal('second'); + expect(messages[4].text).to.equal('first'); + }); + + it('returns four messages when using page-query ', async () => { + const promises = []; + + for (let i = 0; i < 10; i++) { + promises.push(user.post('/members/send-private-message', { + toUserId: user.id, + message: 'fourth', + })); + } + + await Promise.all(promises); + + const messages = await user.get('/inbox/paged-messages?page=1'); + + expect(messages.length).to.equal(5); + }); + + it('returns only the messages of one conversation', async () => { + const messages = await user.get(`/inbox/paged-messages?conversation=${otherUser.id}`); + + expect(messages.length).to.equal(3); + }); + + it('returns the correct message format', async () => { + const messages = await otherUser.get(`/inbox/paged-messages?conversation=${user.id}`); + + expect(messages[0].toUUID).to.equal(user.id); // from user + expect(messages[1].toUUID).to.not.exist; // only filled if its from the chat partner + expect(messages[2].toUUID).to.equal(user.id); // from user + }); }); diff --git a/test/api/v4/members/POST-flag_private_message.test.js b/test/api/v4/members/POST-flag_private_message.test.js index dbeb9b5e18..de9a75b9da 100644 --- a/test/api/v4/members/POST-flag_private_message.test.js +++ b/test/api/v4/members/POST-flag_private_message.test.js @@ -19,10 +19,10 @@ describe('POST /members/flag-private-message/:messageId', () => { toUserId: receiver._id, }); - let senderMessages = await userToSendMessage.get('/inbox/messages'); + let senderMessages = await userToSendMessage.get('/inbox/paged-messages'); let sendersMessageInSendersInbox = _.find(senderMessages, (message) => { - return message.uuid === receiver._id && message.text === messageToSend; + return message.toUUID === receiver._id && message.text === messageToSend; }); expect(sendersMessageInSendersInbox).to.exist; @@ -37,7 +37,7 @@ describe('POST /members/flag-private-message/:messageId', () => { toUserId: receiver._id, }); - let receiversMessages = await receiver.get('/inbox/messages'); + let receiversMessages = await receiver.get('/inbox/paged-messages'); let sendersMessageInReceiversInbox = _.find(receiversMessages, (message) => { return message.uuid === userToSendMessage._id && message.text === messageToSend; @@ -55,7 +55,7 @@ describe('POST /members/flag-private-message/:messageId', () => { toUserId: receiver._id, }); - let receiversMessages = await receiver.get('/inbox/messages'); + let receiversMessages = await receiver.get('/inbox/paged-messages'); let sendersMessageInReceiversInbox = _.find(receiversMessages, (message) => { return message.uuid === userToSendMessage._id && message.text === messageToSend; diff --git a/website/client/components/chat/chatCard.vue b/website/client/components/chat/chatCard.vue index fac207d5c0..7b3c476e71 100644 --- a/website/client/components/chat/chatCard.vue +++ b/website/client/components/chat/chatCard.vue @@ -273,5 +273,8 @@ export default { return habiticaMarkdown.render(String(text)); }, }, + mounted () { + this.$emit('chat-card-mounted', this.msg.id); + }, }; diff --git a/website/client/components/chat/chatMessages.vue b/website/client/components/chat/chatMessages.vue index 6ee84b98d8..d4c3438b19 100644 --- a/website/client/components/chat/chatMessages.vue +++ b/website/client/components/chat/chatMessages.vue @@ -1,8 +1,14 @@