diff --git a/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java b/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java
index 681175abd..a5f9583e7 100644
--- a/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java
+++ b/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java
@@ -107,25 +107,6 @@ public class MessagingController implements Runnable {
*/
private static final String[] EMPTY_STRING_ARRAY = new String[0];
- /**
- * The maximum message size that we'll consider to be "small". A small message is downloaded
- * in full immediately instead of in pieces. Anything over this size will be downloaded in
- * pieces with attachments being left off completely and downloaded on demand.
- *
- *
- * 25k for a "small" message was picked by educated trial and error.
- * http://answers.google.com/answers/threadview?id=312463 claims that the
- * average size of an email is 59k, which I feel is too large for our
- * blind download. The following tests were performed on a download of
- * 25 random messages.
- *
- * 5k - 61 seconds,
- * 25k - 51 seconds,
- * 55k - 53 seconds,
- *
- * So 25k gives good performance and a reasonable data footprint. Sounds good to me.
- */
-
private static final String PENDING_COMMAND_MOVE_OR_COPY = "com.fsck.k9.MessagingController.moveOrCopy";
private static final String PENDING_COMMAND_MOVE_OR_COPY_BULK = "com.fsck.k9.MessagingController.moveOrCopyBulk";
private static final String PENDING_COMMAND_MOVE_OR_COPY_BULK_NEW = "com.fsck.k9.MessagingController.moveOrCopyBulkNew";
@@ -327,7 +308,6 @@ public class MessagingController implements Runnable {
throw new Error(e);
}
-
public void addListener(MessagingListener listener) {
mListeners.add(listener);
refreshListener(listener);
@@ -438,74 +418,80 @@ public class MessagingController implements Runnable {
put("doRefreshRemote", listener, new Runnable() {
@Override
public void run() {
- List localFolders = null;
- try {
- Store store = account.getRemoteStore();
-
- List extends Folder > remoteFolders = store.getPersonalNamespaces(false);
-
- LocalStore localStore = account.getLocalStore();
- Set remoteFolderNames = new HashSet();
- List foldersToCreate = new LinkedList();
-
- localFolders = localStore.getPersonalNamespaces(false);
- Set localFolderNames = new HashSet();
- for (Folder localFolder : localFolders) {
- localFolderNames.add(localFolder.getName());
- }
- for (Folder remoteFolder : remoteFolders) {
- if (localFolderNames.contains(remoteFolder.getName()) == false) {
- LocalFolder localFolder = localStore.getFolder(remoteFolder.getName());
- foldersToCreate.add(localFolder);
- }
- remoteFolderNames.add(remoteFolder.getName());
- }
- localStore.createFolders(foldersToCreate, account.getDisplayCount());
-
- localFolders = localStore.getPersonalNamespaces(false);
-
- /*
- * Clear out any folders that are no longer on the remote store.
- */
- for (Folder localFolder : localFolders) {
- String localFolderName = localFolder.getName();
-
- // FIXME: This is a hack used to clean up when we accidentally created the
- // special placeholder folder "-NONE-".
- if (K9.FOLDER_NONE.equals(localFolderName)) {
- localFolder.delete(false);
- }
-
- if (!account.isSpecialFolder(localFolderName) &&
- !remoteFolderNames.contains(localFolderName)) {
- localFolder.delete(false);
- }
- }
-
- localFolders = localStore.getPersonalNamespaces(false);
-
- for (MessagingListener l : getListeners(listener)) {
- l.listFolders(account, localFolders);
- }
- for (MessagingListener l : getListeners(listener)) {
- l.listFoldersFinished(account);
- }
- } catch (Exception e) {
- for (MessagingListener l : getListeners(listener)) {
- l.listFoldersFailed(account, "");
- }
- addErrorMessage(account, null, e);
- } finally {
- if (localFolders != null) {
- for (Folder localFolder : localFolders) {
- closeFolder(localFolder);
- }
- }
- }
+ refreshRemoteSynchronous(account, listener);
}
});
}
+ @VisibleForTesting
+ void refreshRemoteSynchronous(final Account account, final MessagingListener listener) {
+ List localFolders = null;
+ try {
+ Store store = account.getRemoteStore();
+
+ List extends Folder > remoteFolders = store.getPersonalNamespaces(false);
+
+ LocalStore localStore = account.getLocalStore();
+ Set remoteFolderNames = new HashSet();
+ List foldersToCreate = new LinkedList();
+
+ localFolders = localStore.getPersonalNamespaces(false);
+ Set localFolderNames = new HashSet();
+ for (Folder localFolder : localFolders) {
+ localFolderNames.add(localFolder.getName());
+ }
+
+ for (Folder remoteFolder : remoteFolders) {
+ if (localFolderNames.contains(remoteFolder.getName()) == false) {
+ LocalFolder localFolder = localStore.getFolder(remoteFolder.getName());
+ foldersToCreate.add(localFolder);
+ }
+ remoteFolderNames.add(remoteFolder.getName());
+ }
+ localStore.createFolders(foldersToCreate, account.getDisplayCount());
+
+ localFolders = localStore.getPersonalNamespaces(false);
+
+ /*
+ * Clear out any folders that are no longer on the remote store.
+ */
+ for (Folder localFolder : localFolders) {
+ String localFolderName = localFolder.getName();
+
+ // FIXME: This is a hack used to clean up when we accidentally created the
+ // special placeholder folder "-NONE-".
+ if (K9.FOLDER_NONE.equals(localFolderName)) {
+ localFolder.delete(false);
+ }
+
+ if (!account.isSpecialFolder(localFolderName) &&
+ !remoteFolderNames.contains(localFolderName)) {
+ localFolder.delete(false);
+ }
+ }
+
+ localFolders = localStore.getPersonalNamespaces(false);
+
+ for (MessagingListener l : getListeners(listener)) {
+ l.listFolders(account, localFolders);
+ }
+ for (MessagingListener l : getListeners(listener)) {
+ l.listFoldersFinished(account);
+ }
+ } catch (Exception e) {
+ for (MessagingListener l : getListeners(listener)) {
+ l.listFoldersFailed(account, "");
+ }
+ addErrorMessage(account, null, e);
+ } finally {
+ if (localFolders != null) {
+ for (Folder localFolder : localFolders) {
+ closeFolder(localFolder);
+ }
+ }
+ }
+ }
+
/**
* Find all messages in any local account which match the query 'query'
* @throws MessagingException
diff --git a/k9mail/src/test/java/com/fsck/k9/controller/MessagingControllerTest.java b/k9mail/src/test/java/com/fsck/k9/controller/MessagingControllerTest.java
index f5ee82817..1aeb522cf 100644
--- a/k9mail/src/test/java/com/fsck/k9/controller/MessagingControllerTest.java
+++ b/k9mail/src/test/java/com/fsck/k9/controller/MessagingControllerTest.java
@@ -1,15 +1,21 @@
package com.fsck.k9.controller;
-
+import java.lang.reflect.Field;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
import android.content.Context;
import com.fsck.k9.Account;
import com.fsck.k9.AccountStats;
+import com.fsck.k9.Preferences;
import com.fsck.k9.mail.FetchProfile;
+import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessageRetrievalListener;
@@ -19,12 +25,15 @@ import com.fsck.k9.mailstore.LocalFolder;
import com.fsck.k9.mailstore.LocalMessage;
import com.fsck.k9.mailstore.LocalStore;
import com.fsck.k9.notification.NotificationController;
+import com.fsck.k9.search.LocalSearch;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
+import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
@@ -37,11 +46,16 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anySet;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -62,6 +76,8 @@ public class MessagingControllerTest {
@Mock
private MessagingListener listener;
@Mock
+ private LocalSearch search;
+ @Mock
private LocalFolder localFolder;
@Mock
private Folder remoteFolder;
@@ -74,13 +90,34 @@ public class MessagingControllerTest {
@Captor
private ArgumentCaptor> messageListCaptor;
@Captor
+ private ArgumentCaptor> localFolderListCaptor;
+ @Captor
private ArgumentCaptor fetchProfileCaptor;
+ @Captor
+ private ArgumentCaptor> messageRetrievalListenerCaptor;
+
+ private Context appContext;
+ private Set reqFlags;
+ private Set forbiddenFlags;
+
+ private List remoteMessages;
+ @Mock
+ private Message remoteOldMessage;
+ @Mock
+ private Message remoteNewMessage1;
+ @Mock
+ private Message remoteNewMessage2;
+ @Mock
+ private LocalMessage localNewMessage1;
+ @Mock
+ private LocalMessage localNewMessage2;
+ private volatile boolean hasFetchedMessage = false;
@Before
public void setUp() throws MessagingException {
MockitoAnnotations.initMocks(this);
- Context appContext = ShadowApplication.getInstance().getApplicationContext();
+ appContext = ShadowApplication.getInstance().getApplicationContext();
controller = new MessagingController(appContext, notificationController);
@@ -93,6 +130,348 @@ public class MessagingControllerTest {
controller.stop();
}
+ @Test
+ public void listFoldersSynchronous_shouldNotifyTheListenerListingStarted() throws MessagingException {
+ List folders = Collections.singletonList(localFolder);
+ when(localStore.getPersonalNamespaces(false)).thenReturn(folders);
+
+ controller.listFoldersSynchronous(account, false, listener);
+
+ verify(listener).listFoldersStarted(account);
+ }
+
+ @Test
+ public void listFoldersSynchronous_shouldNotifyTheListenerOfTheListOfFolders() throws MessagingException {
+ List folders = Collections.singletonList(localFolder);
+ when(localStore.getPersonalNamespaces(false)).thenReturn(folders);
+
+ controller.listFoldersSynchronous(account, false, listener);
+
+ verify(listener).listFolders(eq(account), localFolderListCaptor.capture());
+ assertEquals(folders, localFolderListCaptor.getValue());
+ }
+
+ @Test
+ public void listFoldersSynchronous_shouldNotifyFailureOnException() throws MessagingException {
+ when(localStore.getPersonalNamespaces(false)).thenThrow(new MessagingException("Test"));
+
+ controller.listFoldersSynchronous(account, true, listener);
+
+ verify(listener).listFoldersFailed(account, "Test");
+ }
+
+ @Test
+ public void listFoldersSynchronous_shouldNotNotifyFinishedAfterFailure() throws MessagingException {
+ when(localStore.getPersonalNamespaces(false)).thenThrow(new MessagingException("Test"));
+
+ controller.listFoldersSynchronous(account, true, listener);
+
+ verify(listener, never()).listFoldersFinished(account);
+ }
+
+ @Test
+ public void listFoldersSynchronous_shouldNotifyFinishedAfterSuccess() throws MessagingException {
+ List folders = Collections.singletonList(localFolder);
+ when(localStore.getPersonalNamespaces(false)).thenReturn(folders);
+
+ controller.listFoldersSynchronous(account, false, listener);
+
+ verify(listener).listFoldersFinished(account);
+ }
+
+ @Test
+ public void refreshRemoteSynchronous_shouldCreateFoldersFromRemote() throws MessagingException {
+ configureRemoteStoreWithFolder();
+ LocalFolder newLocalFolder = mock(LocalFolder.class);
+
+ List folders = Collections.singletonList(remoteFolder);
+ when(remoteStore.getPersonalNamespaces(false)).thenAnswer(createAnswer(folders));
+ when(remoteFolder.getName()).thenReturn("NewFolder");
+ when(localStore.getFolder("NewFolder")).thenReturn(newLocalFolder);
+
+ controller.refreshRemoteSynchronous(account, listener);
+
+ verify(localStore).createFolders(eq(Collections.singletonList(newLocalFolder)), anyInt());
+ }
+
+ @Test
+ public void refreshRemoteSynchronous_shouldDeleteFoldersNotOnRemote() throws MessagingException {
+ configureRemoteStoreWithFolder();
+ LocalFolder oldLocalFolder = mock(LocalFolder.class);
+ when(oldLocalFolder.getName()).thenReturn("OldLocalFolder");
+ when(localStore.getPersonalNamespaces(false))
+ .thenReturn(Collections.singletonList(oldLocalFolder));
+ List folders = Collections.emptyList();
+ when(remoteStore.getPersonalNamespaces(false)).thenAnswer(createAnswer(folders));
+
+ controller.refreshRemoteSynchronous(account, listener);
+
+ verify(oldLocalFolder).delete(false);
+ }
+
+ @Test
+ public void refreshRemoteSynchronous_shouldNotDeleteFoldersOnRemote() throws MessagingException {
+ configureRemoteStoreWithFolder();
+ when(localStore.getPersonalNamespaces(false))
+ .thenReturn(Collections.singletonList(localFolder));
+ List folders = Collections.singletonList(remoteFolder);
+ when(remoteStore.getPersonalNamespaces(false)).thenAnswer(createAnswer(folders));
+
+ controller.refreshRemoteSynchronous(account, listener);
+
+ verify(localFolder, never()).delete(false);
+ }
+
+ @Test
+ public void refreshRemoteSynchronous_shouldNotDeleteSpecialFoldersNotOnRemote() throws MessagingException {
+ configureRemoteStoreWithFolder();
+ LocalFolder missingSpecialFolder = mock(LocalFolder.class);
+ when(account.isSpecialFolder("Outbox")).thenReturn(true);
+ when(missingSpecialFolder.getName()).thenReturn("Outbox");
+ when(localStore.getPersonalNamespaces(false))
+ .thenReturn(Collections.singletonList(missingSpecialFolder));
+ List folders = Collections.emptyList();
+ when(remoteStore.getPersonalNamespaces(false)).thenAnswer(createAnswer(folders));
+
+ controller.refreshRemoteSynchronous(account, listener);
+
+ verify(missingSpecialFolder, never()).delete(false);
+ }
+
+ public static Answer createAnswer(final T value) {
+ return new Answer() {
+ @Override
+ public T answer(InvocationOnMock invocation) throws Throwable {
+ return value;
+ }
+ };
+ }
+
+ @Test
+ public void refreshRemoteSynchronous_shouldProvideFolderList() throws MessagingException {
+ configureRemoteStoreWithFolder();
+ List folders = Collections.singletonList(localFolder);
+ when(localStore.getPersonalNamespaces(false)).thenReturn(folders);
+
+ controller.refreshRemoteSynchronous(account, listener);
+
+ verify(listener).listFolders(account, folders);
+ }
+
+ @Test
+ public void refreshRemoteSynchronous_shouldNotifyFinishedAfterSuccess() throws MessagingException {
+ configureRemoteStoreWithFolder();
+ List folders = Collections.singletonList(localFolder);
+ when(localStore.getPersonalNamespaces(false)).thenReturn(folders);
+
+ controller.refreshRemoteSynchronous(account, listener);
+
+ verify(listener).listFoldersFinished(account);
+ }
+
+ @Test
+ public void refreshRemoteSynchronous_shouldNotNotifyFinishedAfterFailure() throws MessagingException {
+ configureRemoteStoreWithFolder();
+ when(localStore.getPersonalNamespaces(false)).thenThrow(new MessagingException("Test"));
+
+ controller.refreshRemoteSynchronous(account, listener);
+
+ verify(listener, never()).listFoldersFinished(account);
+ }
+
+ @Test
+ public void searchLocalMessagesSynchronous_shouldNotifyStartedListingLocalMessages()
+ throws Exception {
+ setAccountsInPreferences(Collections.singletonMap("1", account));
+ when(search.getAccountUuids()).thenReturn(new String[]{"allAccounts"});
+
+ controller.searchLocalMessagesSynchronous(search, listener);
+
+ verify(listener).listLocalMessagesStarted(account, null);
+ }
+
+ @Test
+ public void searchLocalMessagesSynchronous_shouldCallSearchForMessagesOnLocalStore()
+ throws Exception {
+ setAccountsInPreferences(Collections.singletonMap("1", account));
+ when(search.getAccountUuids()).thenReturn(new String[]{"allAccounts"});
+
+ controller.searchLocalMessagesSynchronous(search, listener);
+
+ verify(localStore).searchForMessages(any(MessageRetrievalListener.class), eq(search));
+ }
+
+ @Test
+ public void searchLocalMessagesSynchronous_shouldNotifyFailureIfStoreThrowsException() throws Exception {
+ setAccountsInPreferences(Collections.singletonMap("1", account));
+ when(search.getAccountUuids()).thenReturn(new String[]{"allAccounts"});
+ when(localStore.searchForMessages(any(MessageRetrievalListener.class), eq(search)))
+ .thenThrow(new MessagingException("Test"));
+
+ controller.searchLocalMessagesSynchronous(search, listener);
+
+ verify(listener).listLocalMessagesFailed(account, null, "Test");
+ }
+
+ @Test
+ public void searchLocalMessagesSynchronous_shouldNotifyWhenStoreFinishesRetrievingAMessage()
+ throws Exception {
+ setAccountsInPreferences(Collections.singletonMap("1", account));
+ LocalMessage localMessage = mock(LocalMessage.class);
+ when(localMessage.getFolder()).thenReturn(localFolder);
+ when(search.getAccountUuids()).thenReturn(new String[]{"allAccounts"});
+ when(localStore.searchForMessages(any(MessageRetrievalListener.class), eq(search)))
+ .thenThrow(new MessagingException("Test"));
+
+ controller.searchLocalMessagesSynchronous(search, listener);
+
+ verify(localStore).searchForMessages(messageRetrievalListenerCaptor.capture(), eq(search));
+ messageRetrievalListenerCaptor.getValue().messageFinished(localMessage, 1, 1);
+ verify(listener).listLocalMessagesAddMessages(eq(account),
+ eq((String) null), eq(Collections.singletonList(localMessage)));
+ }
+
+ private void setupRemoteSearch() throws Exception {
+ setAccountsInPreferences(Collections.singletonMap("1", account));
+ configureRemoteStoreWithFolder();
+
+ remoteMessages = new ArrayList<>();
+ Collections.addAll(remoteMessages, remoteOldMessage, remoteNewMessage1, remoteNewMessage2);
+ List newRemoteMessages = new ArrayList<>();
+ Collections.addAll(newRemoteMessages, remoteNewMessage1, remoteNewMessage2);
+
+ when(remoteOldMessage.getUid()).thenReturn("oldMessageUid");
+ when(remoteNewMessage1.getUid()).thenReturn("newMessageUid1");
+ when(localNewMessage1.getUid()).thenReturn("newMessageUid1");
+ when(remoteNewMessage2.getUid()).thenReturn("newMessageUid2");
+ when(localNewMessage2.getUid()).thenReturn("newMessageUid2");
+ when(remoteFolder.search(anyString(), anySet(), anySet())).thenReturn(remoteMessages);
+ when(localFolder.extractNewMessages(Matchers.>any())).thenReturn(newRemoteMessages);
+ when(localFolder.getMessage("newMessageUid1")).thenReturn(localNewMessage1);
+ when(localFolder.getMessage("newMessageUid2")).thenAnswer(
+ new Answer() {
+ @Override
+ public LocalMessage answer(InvocationOnMock invocation) throws Throwable {
+ if(hasFetchedMessage) {
+ return localNewMessage2;
+ }
+ else
+ return null;
+ }
+ }
+ );
+ doAnswer(new Answer() {
+ @Override
+ public Void answer(InvocationOnMock invocation) throws Throwable {
+ hasFetchedMessage = true;
+ return null;
+ }
+ }).when(remoteFolder).fetch(
+ Matchers.>eq(Collections.singletonList(remoteNewMessage2)),
+ any(FetchProfile.class),
+ Matchers.eq(null));
+ reqFlags = Collections.singleton(Flag.ANSWERED);
+ forbiddenFlags = Collections.singleton(Flag.DELETED);
+
+ when(account.getRemoteSearchNumResults()).thenReturn(50);
+ }
+
+ @Test
+ public void searchRemoteMessagesSynchronous_shouldNotifyStartedListingRemoteMessages() throws Exception {
+ setupRemoteSearch();
+
+ controller.searchRemoteMessagesSynchronous("1", FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
+
+ verify(listener).remoteSearchStarted(FOLDER_NAME);
+ }
+
+ @Test
+ public void searchRemoteMessagesSynchronous_shouldQueryRemoteFolder() throws Exception {
+ setupRemoteSearch();
+
+ controller.searchRemoteMessagesSynchronous("1", FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
+
+ verify(remoteFolder).search("query", reqFlags, forbiddenFlags);
+ }
+
+ @Test
+ public void searchRemoteMessagesSynchronous_shouldAskLocalFolderToDetermineNewMessages() throws Exception {
+ setupRemoteSearch();
+
+ controller.searchRemoteMessagesSynchronous("1", FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
+
+ verify(localFolder).extractNewMessages(remoteMessages);
+ }
+
+ @Test
+ public void searchRemoteMessagesSynchronous_shouldTryAndGetNewMessages() throws Exception {
+ setupRemoteSearch();
+
+ controller.searchRemoteMessagesSynchronous("1", FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
+
+ verify(localFolder).getMessage("newMessageUid1");
+ }
+
+ @Test
+ public void searchRemoteMessagesSynchronous_shouldNotTryAndGetOldMessages() throws Exception {
+ setupRemoteSearch();
+
+ controller.searchRemoteMessagesSynchronous("1", FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
+
+ verify(localFolder, never()).getMessage("oldMessageUid");
+ }
+
+ @Test
+ public void searchRemoteMessagesSynchronous_shouldFetchNewMessages() throws Exception {
+ setupRemoteSearch();
+
+ controller.searchRemoteMessagesSynchronous("1", FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
+
+ verify(remoteFolder, times(2)).fetch(eq(Collections.singletonList(remoteNewMessage2)),
+ fetchProfileCaptor.capture(), Matchers.eq(null));
+ }
+
+ @Test
+ public void searchRemoteMessagesSynchronous_shouldNotFetchExistingMessages() throws Exception {
+ setupRemoteSearch();
+
+ controller.searchRemoteMessagesSynchronous("1", FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
+
+ verify(remoteFolder, never()).fetch(eq(Collections.singletonList(remoteNewMessage1)),
+ fetchProfileCaptor.capture(), Matchers.eq(null));
+ }
+
+ @Test
+ public void searchRemoteMessagesSynchronous_shouldNotifyListenerOfNewMessages() throws Exception {
+ setupRemoteSearch();
+
+ controller.searchRemoteMessagesSynchronous("1", FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
+
+ verify(listener).remoteSearchAddMessage(FOLDER_NAME, localNewMessage1, 1, 2);
+ verify(listener).remoteSearchAddMessage(FOLDER_NAME, localNewMessage2, 2, 2);
+ }
+
+ @Test
+ public void searchRemoteMessagesSynchronous_shouldNotifyOnFailure() throws Exception {
+ setupRemoteSearch();
+ when(account.getRemoteStore()).thenThrow(new MessagingException("Test"));
+
+ controller.searchRemoteMessagesSynchronous("1", FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
+
+ verify(listener).remoteSearchFailed(null, "Test");
+ }
+
+ @Test
+ public void searchRemoteMessagesSynchronous_shouldNotifyOnFinish() throws Exception {
+ setupRemoteSearch();
+ when(account.getRemoteStore()).thenThrow(new MessagingException("Test"));
+
+ controller.searchRemoteMessagesSynchronous("1", FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
+
+ verify(listener).remoteSearchFinished(FOLDER_NAME, 0, 50, Collections.emptyList());
+ }
+
+
@Test
public void synchronizeMailboxSynchronous_withOneMessageInRemoteFolder_shouldFinishWithoutError()
throws Exception {
@@ -372,6 +751,7 @@ public class MessagingControllerTest {
}
private void configureAccount() throws MessagingException {
+ when(account.isAvailable(appContext)).thenReturn(true);
when(account.getLocalStore()).thenReturn(localStore);
when(account.getStats(any(Context.class))).thenReturn(accountStats);
when(account.getMaximumAutoDownloadMessageSize()).thenReturn(MAXIMUM_SMALL_MESSAGE_SIZE);
@@ -379,10 +759,25 @@ public class MessagingControllerTest {
private void configureLocalStore() {
when(localStore.getFolder(FOLDER_NAME)).thenReturn(localFolder);
+ when(localFolder.getName()).thenReturn(FOLDER_NAME);
}
private void configureRemoteStoreWithFolder() throws MessagingException {
when(account.getRemoteStore()).thenReturn(remoteStore);
when(remoteStore.getFolder(FOLDER_NAME)).thenReturn(remoteFolder);
+ when(remoteFolder.getName()).thenReturn(FOLDER_NAME);
+ }
+
+ private void setAccountsInPreferences(Map newAccounts)
+ throws Exception {
+ Field accounts = Preferences.class.getDeclaredField("accounts");
+ accounts.setAccessible(true);
+ accounts.set(Preferences.getPreferences(appContext), newAccounts);
+
+ Field accountsInOrder = Preferences.class.getDeclaredField("accountsInOrder");
+ accountsInOrder.setAccessible(true);
+ ArrayList newAccountsInOrder = new ArrayList<>();
+ newAccountsInOrder.addAll(newAccounts.values());
+ accountsInOrder.set(Preferences.getPreferences(appContext), newAccountsInOrder);
}
}