diff options
author | Christoph Wurst <christoph@winzerhof-wurst.at> | 2020-02-20 18:12:11 +0300 |
---|---|---|
committer | Christoph Wurst <christoph@winzerhof-wurst.at> | 2020-02-24 09:12:16 +0300 |
commit | 46916ee4f396e71075fd228a87ef294e38825dea (patch) | |
tree | fbe43ebdd9862f3992ea60da7af40ea1c627a05e /src/tests/unit/store/actions.spec.js | |
parent | 5be88a693bf7e516b1159f3c0500302c0adbe514 (diff) |
Make envelope lists more versatile
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
Diffstat (limited to 'src/tests/unit/store/actions.spec.js')
-rw-r--r-- | src/tests/unit/store/actions.spec.js | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/src/tests/unit/store/actions.spec.js b/src/tests/unit/store/actions.spec.js new file mode 100644 index 000000000..893a9e536 --- /dev/null +++ b/src/tests/unit/store/actions.spec.js @@ -0,0 +1,313 @@ +/* + * @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @author 2020 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import sinon from 'sinon' +import {curry, prop, range, reverse} from 'ramda' +import orderBy from 'lodash/fp/orderBy' + +import actions from '../../../store/actions' +import * as MessageService from '../../../service/MessageService' +import {normalizedMessageId} from '../../../store/normalization' +import {UNIFIED_ACCOUNT_ID, UNIFIED_INBOX_ID} from '../../../store/constants' + +const mockEnvelope = curry((accountId, folderId, id) => ({ + accountId, + folderId, + id, + uid: normalizedMessageId(accountId, folderId, id), + dateInt: id * 10000, +})) + +describe('Vuex store actions', () => { + let context + + beforeEach(() => { + context = { + commit: sinon.stub(), + dispatch: sinon.stub(), + getters: { + accounts: [], + getFolder: sinon.stub(), + getFolders: sinon.stub(), + getEnvelopeById: sinon.stub(), + getEnvelopes: sinon.stub(), + }, + } + }) + + it('combines unified inbox even if no inboxes are present', () => { + context.getters.getFolder.returns({ + isUnified: true, + }) + + const envelopes = actions.fetchEnvelopes(context, { + accountId: UNIFIED_ACCOUNT_ID, + folderId: UNIFIED_INBOX_ID, + }) + + expect(envelopes).to.be.empty + }) + + it('creates a unified page from one mailbox', async () => { + context.getters.accounts.push({ + id: 13, + accountId: 13, + }) + context.getters.getFolder.withArgs(UNIFIED_ACCOUNT_ID, UNIFIED_INBOX_ID).returns({ + isUnified: true, + specialRole: 'inbox', + }) + context.getters.getFolders.withArgs(13).returns([ + { + id: 'INBOX', + accountId: 13, + specialRole: 'inbox', + }, + { + id: 'Drafts', + accountId: 13, + specialRole: 'draft', + }, + ]) + context.dispatch + .withArgs('fetchEnvelopes', { + accountId: 13, + folderId: 'INBOX', + query: undefined, + }) + .returns([ + { + accountId: 13, + folderId: 'INBOX', + uid: '13-INBOX-123', + subject: 'msg1', + }, + ]) + + const envelopes = await actions.fetchEnvelopes(context, { + accountId: UNIFIED_ACCOUNT_ID, + folderId: UNIFIED_INBOX_ID, + }) + + expect(envelopes).to.deep.equal([ + { + accountId: 13, + folderId: 'INBOX', + uid: '13-INBOX-123', + subject: 'msg1', + }, + ]) + expect(context.dispatch).to.have.been.calledOnce + expect(context.commit).to.have.been.calledWith('addEnvelope', { + accountId: UNIFIED_ACCOUNT_ID, + folderId: UNIFIED_INBOX_ID, + envelope: { + accountId: 13, + folderId: 'INBOX', + uid: '13-INBOX-123', + subject: 'msg1', + }, + query: undefined, + }) + }) + + it('fetches the next individual page', async () => { + context.getters.accounts.push({ + id: 13, + accountId: 13, + }) + context.getters.getFolder.withArgs(13, 'INBOX').returns({ + id: 'INBOX', + accountId: 13, + specialRole: 'inbox', + envelopeLists: { + '': reverse(range(21, 40).map(normalizedMessageId(13, 'INBOX'))), + }, + }) + context.getters.getEnvelopeById + .withArgs(normalizedMessageId(13, 'INBOX', 21)) + .returns(mockEnvelope(13, 'INBOX', 1)) + sinon.stub(MessageService, 'fetchEnvelopes').returns( + Promise.resolve( + reverse( + range(1, 21).map(n => ({ + id: n, + uid: normalizedMessageId(13, 'INBOX', n), + dateInt: n * 10000, + })) + ) + ) + ) + + const page = await actions.fetchNextEnvelopePage(context, { + accountId: 13, + folderId: 'INBOX', + }) + + expect(page).to.deep.equal( + reverse( + range(1, 21).map(n => ({ + id: n, + uid: normalizedMessageId(13, 'INBOX', n), + dateInt: n * 10000, + })) + ) + ) + expect(context.commit).to.have.callCount(20) + }) + + it('builds the next unified page with local data', async () => { + const page1 = reverse(range(25, 30)) + const page2 = reverse(range(30, 35)) + const msgs1 = reverse(range(10, 30)) + const msgs2 = reverse(range(5, 35)) + context.getters.accounts.push({ + id: 13, + accountId: 13, + }) + context.getters.accounts.push({ + id: 26, + accountId: 26, + }) + context.getters.getFolder.withArgs(UNIFIED_ACCOUNT_ID, UNIFIED_INBOX_ID).returns({ + isUnified: true, + specialRole: 'inbox', + accountId: UNIFIED_ACCOUNT_ID, + id: UNIFIED_INBOX_ID, + }) + context.getters.getFolders.withArgs(13).returns([ + { + id: 'INBOX', + accountId: 13, + specialRole: 'inbox', + }, + { + id: 'Drafts', + accountId: 13, + specialRole: 'draft', + }, + ]) + context.getters.getFolders.withArgs(26).returns([ + { + id: 'INBOX', + accountId: 26, + specialRole: 'inbox', + }, + { + id: 'Drafts', + accountId: 26, + specialRole: 'draft', + }, + ]) + context.getters.getEnvelopes + .withArgs(UNIFIED_ACCOUNT_ID, UNIFIED_INBOX_ID, undefined) + .returns( + orderBy( + prop('dateInt'), + 'desc', + page1.map(mockEnvelope(13, 'INBOX')).concat(page2.map(mockEnvelope(26, 'INBOX'))) + ) + ) + context.getters.getEnvelopes.withArgs(13, 'INBOX', undefined).returns(msgs1.map(mockEnvelope(13, 'INBOX'))) + context.getters.getEnvelopes.withArgs(26, 'INBOX', undefined).returns(msgs2.map(mockEnvelope(26, 'INBOX'))) + + const page = await actions.fetchNextEnvelopePage(context, { + accountId: UNIFIED_ACCOUNT_ID, + folderId: UNIFIED_INBOX_ID, + }) + + expect(context.dispatch).not.have.been.called + expect(page.length).to.equal(20) + }) + + it('builds the next unified page with partial fetch', async () => { + const page1 = reverse(range(25, 30)) + const page2 = reverse(range(30, 35)) + const msgs1 = reverse(range(25, 30)) + const msgs2 = reverse(range(5, 35)) + context.getters.accounts.push({ + id: 13, + accountId: 13, + }) + context.getters.accounts.push({ + id: 26, + accountId: 26, + }) + context.getters.getFolder.withArgs(UNIFIED_ACCOUNT_ID, UNIFIED_INBOX_ID).returns({ + isUnified: true, + specialRole: 'inbox', + accountId: UNIFIED_ACCOUNT_ID, + id: UNIFIED_INBOX_ID, + }) + context.getters.getFolders.withArgs(13).returns([ + { + id: 'INBOX', + accountId: 13, + specialRole: 'inbox', + }, + { + id: 'Drafts', + accountId: 13, + specialRole: 'draft', + }, + ]) + context.getters.getFolders.withArgs(26).returns([ + { + id: 'INBOX', + accountId: 26, + specialRole: 'inbox', + }, + { + id: 'Drafts', + accountId: 26, + specialRole: 'draft', + }, + ]) + context.getters.getEnvelopes + .withArgs(UNIFIED_ACCOUNT_ID, UNIFIED_INBOX_ID, undefined) + .returns( + orderBy( + prop('dateInt'), + 'desc', + page1.map(mockEnvelope(13, 'INBOX')).concat(page2.map(mockEnvelope(26, 'INBOX'))) + ) + ) + context.getters.getEnvelopes.withArgs(13, 'INBOX', undefined).returns(msgs1.map(mockEnvelope(13, 'INBOX'))) + context.getters.getEnvelopes.withArgs(26, 'INBOX', undefined).returns(msgs2.map(mockEnvelope(26, 'INBOX'))) + + await actions.fetchNextEnvelopePage(context, { + accountId: UNIFIED_ACCOUNT_ID, + folderId: UNIFIED_INBOX_ID, + }) + + expect(context.dispatch).have.been.calledTwice + expect(context.dispatch).have.been.calledWith('fetchNextEnvelopePage', { + accountId: 26, + folderId: 'INBOX', + query: undefined, + }) + expect(context.dispatch).have.been.calledWith('fetchNextEnvelopePage', { + accountId: UNIFIED_ACCOUNT_ID, + folderId: UNIFIED_INBOX_ID, + query: undefined, + }) + }) +}) |