Loading k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapFolder.java +2 −2 Original line number Diff line number Diff line Loading @@ -524,7 +524,7 @@ public class ImapFolder extends Folder<ImapMessage> { .build(); try { UidSearchResponse searchResponse = connection.executeSelectedStateCommand(searchCommand); return getMessages(searchResponse, null); return getMessages(searchResponse, listener); } catch (IOException ioe) { throw ioExceptionHandler(connection, ioe); } Loading Loading @@ -580,7 +580,7 @@ public class ImapFolder extends Folder<ImapMessage> { .build(); try { UidSearchResponse searchResponse = connection.executeSelectedStateCommand(searchCommand); return getMessages(searchResponse, null); return getMessages(searchResponse, listener); } catch (IOException ioe) { throw ioExceptionHandler(connection, ioe); } Loading k9mail-library/src/test/java/com/fsck/k9/mail/store/imap/ImapFolderTest.java +79 −83 Original line number Diff line number Diff line package com.fsck.k9.mail.store.imap; import java.io.IOException; 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 java.util.TimeZone; import com.fsck.k9.mail.Body; import com.fsck.k9.mail.DefaultBodyFactory; import com.fsck.k9.mail.FetchProfile; Loading @@ -16,7 +26,12 @@ import com.fsck.k9.mail.Part; import com.fsck.k9.mail.internet.BinaryTempFileBody; import com.fsck.k9.mail.internet.MimeHeader; import com.fsck.k9.mail.store.StoreConfig; import com.fsck.k9.mail.store.imap.selectedstate.command.FolderSelectedStateCommand; import com.fsck.k9.mail.store.imap.selectedstate.command.UidCopyCommand; import com.fsck.k9.mail.store.imap.selectedstate.command.UidSearchCommand; import com.fsck.k9.mail.store.imap.selectedstate.response.UidCopyResponse; import com.fsck.k9.mail.store.imap.selectedstate.response.UidSearchResponse; import okio.Buffer; import org.apache.james.mime4j.util.MimeUtil; import org.junit.Before; import org.junit.Test; Loading @@ -26,18 +41,6 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.robolectric.RuntimeEnvironment; import java.io.IOException; 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 java.util.TimeZone; import okio.Buffer; import static com.fsck.k9.mail.Folder.OPEN_MODE_RO; import static com.fsck.k9.mail.Folder.OPEN_MODE_RW; import static com.fsck.k9.mail.store.imap.ImapResponseHelper.createImapResponse; Loading @@ -52,6 +55,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; Loading @@ -66,6 +70,7 @@ public class ImapFolderTest { private ImapStore imapStore; private ImapConnection imapConnection; private StoreConfig storeConfig; private ArgumentCaptor<? extends FolderSelectedStateCommand> commandCaptor; @Before public void setUp() throws Exception { Loading @@ -77,6 +82,7 @@ public class ImapFolderTest { when(imapStore.getStoreConfig()).thenReturn(storeConfig); imapConnection = mock(ImapConnection.class); commandCaptor = ArgumentCaptor.forClass(FolderSelectedStateCommand.class); } @Test Loading Loading @@ -330,10 +336,7 @@ public class ImapFolderTest { prepareImapFolderForOpen(OPEN_MODE_RW); ImapFolder destinationFolder = createFolder("Destination"); List<ImapMessage> messages = singletonList(createImapMessage("1")); List<ImapResponse> copyResponses = singletonList( createImapResponse("x OK [COPYUID 23 1 101] Success") ); when(imapConnection.executeSimpleCommand("UID COPY 1 \"Destination\"")).thenReturn(copyResponses); setupCopyResponse("x OK [COPYUID 23 1 101] Success"); sourceFolder.open(OPEN_MODE_RW); Map<String, String> uidMapping = sourceFolder.copyMessages(messages, destinationFolder); Loading @@ -348,10 +351,7 @@ public class ImapFolderTest { prepareImapFolderForOpen(OPEN_MODE_RW); ImapFolder destinationFolder = createFolder("Destination"); List<ImapMessage> messages = singletonList(createImapMessage("1")); List<ImapResponse> copyResponses = singletonList( createImapResponse("x OK [COPYUID 23 1 101] Success") ); when(imapConnection.executeSimpleCommand("UID COPY 1 \"Destination\"")).thenReturn(copyResponses); setupCopyResponse("x OK [COPYUID 23 1 101] Success"); sourceFolder.open(OPEN_MODE_RW); Map<String, String> uidMapping = sourceFolder.moveMessages(messages, destinationFolder); Loading @@ -366,15 +366,11 @@ public class ImapFolderTest { prepareImapFolderForOpen(OPEN_MODE_RW); ImapFolder destinationFolder = createFolder("Destination"); List<ImapMessage> messages = singletonList(createImapMessage("1")); List<ImapResponse> copyResponses = singletonList( createImapResponse("x OK [COPYUID 23 1 101] Success") ); when(imapConnection.executeSimpleCommand("UID COPY 1 \"Destination\"")).thenReturn(copyResponses); sourceFolder.open(OPEN_MODE_RW); sourceFolder.moveMessages(messages, destinationFolder); verify(imapConnection).executeSimpleCommand("UID STORE 1 +FLAGS.SILENT (\\Deleted)"); assertCommandIssued("UID STORE 1 +FLAGS.SILENT (\\Deleted)"); } @Test Loading Loading @@ -407,7 +403,7 @@ public class ImapFolderTest { folder.delete(messages, "Folder"); verify(imapConnection).executeSimpleCommand("UID STORE 23 +FLAGS.SILENT (\\Deleted)"); assertCommandIssued("UID STORE 23 +FLAGS.SILENT (\\Deleted)"); } @Test Loading @@ -417,15 +413,12 @@ public class ImapFolderTest { ImapFolder trashFolder = createFolder("Trash"); when(imapStore.getFolder("Trash")).thenReturn(trashFolder); List<ImapMessage> messages = singletonList(createImapMessage("2")); List<ImapResponse> copyResponses = singletonList( createImapResponse("x OK [COPYUID 23 2 102] Success") ); when(imapConnection.executeSimpleCommand("UID COPY 2 \"Trash\"")).thenReturn(copyResponses); setupCopyResponse("x OK [COPYUID 23 2 102] Success"); folder.open(OPEN_MODE_RW); folder.delete(messages, "Trash"); verify(imapConnection).executeSimpleCommand("UID STORE 2 +FLAGS.SILENT (\\Deleted)"); assertCommandIssued("UID STORE 2 +FLAGS.SILENT (\\Deleted)"); } @Test Loading Loading @@ -465,7 +458,7 @@ public class ImapFolderTest { public void getUnreadMessageCount_connectionThrowsIOException_shouldThrowMessagingException() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); when(imapConnection.executeSimpleCommand("UID SEARCH 1:* NOT SEEN NOT DELETED")).thenThrow(new IOException()); when(imapConnection.executeSelectedStateCommand(any(UidSearchCommand.class))).thenThrow(new IOException()); folder.open(OPEN_MODE_RW); try { Loading @@ -480,8 +473,7 @@ public class ImapFolderTest { public void getUnreadMessageCount() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = singletonList(createImapResponse("* SEARCH 1 2 3")); when(imapConnection.executeSimpleCommand("UID SEARCH 1:* NOT SEEN NOT DELETED")).thenReturn(imapResponses); setupSearchResponse("* SEARCH 1 2 3"); folder.open(OPEN_MODE_RW); int unreadMessageCount = folder.getUnreadMessageCount(); Loading @@ -506,11 +498,7 @@ public class ImapFolderTest { public void getFlaggedMessageCount() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = asList( createImapResponse("* SEARCH 1 2"), createImapResponse("* SEARCH 23 42") ); when(imapConnection.executeSimpleCommand("UID SEARCH 1:* FLAGGED NOT DELETED")).thenReturn(imapResponses); setupSearchResponse("* SEARCH 1 2", "* SEARCH 23 42"); folder.open(OPEN_MODE_RW); int flaggedMessageCount = folder.getFlaggedMessageCount(); Loading @@ -522,8 +510,7 @@ public class ImapFolderTest { public void getHighestUid() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = singletonList(createImapResponse("* SEARCH 42")); when(imapConnection.executeSimpleCommand("UID SEARCH *:*")).thenReturn(imapResponses); setupSearchResponse("* SEARCH 42"); folder.open(OPEN_MODE_RW); long highestUid = folder.getHighestUid(); Loading @@ -535,7 +522,8 @@ public class ImapFolderTest { public void getHighestUid_imapConnectionThrowsNegativesResponse_shouldReturnMinusOne() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); doThrow(NegativeImapResponseException.class).when(imapConnection).executeSimpleCommand("UID SEARCH *:*"); doThrow(NegativeImapResponseException.class).when(imapConnection) .executeSelectedStateCommand(any(UidSearchCommand.class)); folder.open(OPEN_MODE_RW); long highestUid = folder.getHighestUid(); Loading @@ -547,7 +535,7 @@ public class ImapFolderTest { public void getHighestUid_imapConnectionThrowsIOException_shouldThrowMessagingException() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); doThrow(IOException.class).when(imapConnection).executeSimpleCommand("UID SEARCH *:*"); doThrow(IOException.class).when(imapConnection).executeSelectedStateCommand(any(UidSearchCommand.class)); folder.open(OPEN_MODE_RW); try { Loading @@ -562,12 +550,7 @@ public class ImapFolderTest { public void getMessages_withoutDateConstraint() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = asList( createImapResponse("* SEARCH 3"), createImapResponse("* SEARCH 5"), createImapResponse("* SEARCH 6") ); when(imapConnection.executeSimpleCommand("UID SEARCH 1:10 NOT DELETED")).thenReturn(imapResponses); setupSearchResponse("* SEARCH 3", "* SEARCH 5", "* SEARCH 6"); folder.open(OPEN_MODE_RW); List<ImapMessage> messages = folder.getMessages(1, 10, null, null); Loading @@ -581,12 +564,7 @@ public class ImapFolderTest { TimeZone.setDefault(TimeZone.getTimeZone("UTC")); ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = asList( createImapResponse("* SEARCH 47"), createImapResponse("* SEARCH 18") ); when(imapConnection.executeSimpleCommand("UID SEARCH 1:10 SINCE 06-Feb-2016 NOT DELETED")) .thenReturn(imapResponses); setupSearchResponse("* SEARCH 47", "* SEARCH 18"); folder.open(OPEN_MODE_RW); List<ImapMessage> messages = folder.getMessages(1, 10, new Date(1454719826000L), null); Loading @@ -599,8 +577,7 @@ public class ImapFolderTest { public void getMessages_withListener_shouldCallListener() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = singletonList(createImapResponse("* SEARCH 99")); when(imapConnection.executeSimpleCommand("UID SEARCH 1:10 NOT DELETED")).thenReturn(imapResponses); setupSearchResponse("* SEARCH 99"); folder.open(OPEN_MODE_RW); MessageRetrievalListener<ImapMessage> listener = createMessageRetrievalListener(); Loading Loading @@ -678,13 +655,7 @@ public class ImapFolderTest { public void getMessages_sequenceNumbers() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = asList( createImapResponse("* SEARCH 17"), createImapResponse("* SEARCH 18"), createImapResponse("* SEARCH 49") ); when(imapConnection.executeSimpleCommand("UID SEARCH 5,1:2 NOT DELETED")) .thenReturn(imapResponses); setupSearchResponse("* SEARCH 17", "* SEARCH 18", "* SEARCH 49"); folder.open(OPEN_MODE_RW); List<ImapMessage> messages = folder.getMessages(newSet(1L, 2L, 5L), false, null); Loading @@ -697,8 +668,7 @@ public class ImapFolderTest { public void getMessages_sequenceNumbers_withListener_shouldCallListener() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = singletonList(createImapResponse("* SEARCH 99")); when(imapConnection.executeSimpleCommand("UID SEARCH 1")).thenReturn(imapResponses); setupSearchResponse("* SEARCH 99"); folder.open(OPEN_MODE_RW); MessageRetrievalListener<ImapMessage> listener = createMessageRetrievalListener(); Loading Loading @@ -727,12 +697,7 @@ public class ImapFolderTest { public void getMessagesFromUids() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = asList( createImapResponse("* SEARCH 11"), createImapResponse("* SEARCH 22"), createImapResponse("* SEARCH 25") ); when(imapConnection.executeSimpleCommand("UID SEARCH UID 11,22,25")).thenReturn(imapResponses); setupSearchResponse("* SEARCH 11", "* SEARCH 22", "* SEARCH 25"); folder.open(OPEN_MODE_RW); List<ImapMessage> messages = folder.getMessagesFromUids(asList("11", "22", "25")); Loading @@ -758,8 +723,7 @@ public class ImapFolderTest { public void areMoreMessagesAvailable_withAdditionalMessages_shouldReturnTrue() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = singletonList(createImapResponse("* SEARCH 42")); when(imapConnection.executeSimpleCommand("UID SEARCH 1:9 NOT DELETED")).thenReturn(imapResponses); setupSearchResponse("* SEARCH 42"); folder.open(OPEN_MODE_RW); boolean areMoreMessagesAvailable = folder.areMoreMessagesAvailable(10, null); Loading @@ -771,6 +735,7 @@ public class ImapFolderTest { public void areMoreMessagesAvailable_withoutAdditionalMessages_shouldReturnFalse() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); setupSearchResponse("1 OK SEARCH completed"); folder.open(OPEN_MODE_RW); boolean areMoreMessagesAvailable = folder.areMoreMessagesAvailable(600, null); Loading @@ -796,12 +761,13 @@ public class ImapFolderTest { throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); setupSearchResponse("1 OK SEARCH Completed"); folder.open(OPEN_MODE_RW); folder.areMoreMessagesAvailable(600, null); verify(imapConnection).executeSimpleCommand("UID SEARCH 100:599 NOT DELETED"); verify(imapConnection).executeSimpleCommand("UID SEARCH 1:99 NOT DELETED"); assertCommandIssued("UID SEARCH 100:599 NOT DELETED"); assertCommandIssued("UID SEARCH 1:99 NOT DELETED"); } @Test Loading Loading @@ -1008,10 +974,11 @@ public class ImapFolderTest { folder.open(OPEN_MODE_RW); ImapMessage message = createImapMessage("2"); when(message.getHeader("Message-ID")).thenReturn(new String[] { "<00000000.0000000@example.org>" }); setupSearchResponse("1 OK SEARCH Completed"); folder.getUidFromMessageId(message); verify(imapConnection).executeSimpleCommand("UID SEARCH HEADER MESSAGE-ID \"<00000000.0000000@example.org>\""); assertCommandIssued("UID SEARCH HEADER MESSAGE-ID \"<00000000.0000000@example.org>\""); } @Test Loading @@ -1021,8 +988,7 @@ public class ImapFolderTest { folder.open(OPEN_MODE_RW); ImapMessage message = createImapMessage("2"); when(message.getHeader("Message-ID")).thenReturn(new String[] { "<00000000.0000000@example.org>" }); when(imapConnection.executeSimpleCommand("UID SEARCH HEADER MESSAGE-ID \"<00000000.0000000@example.org>\"")) .thenReturn(singletonList(createImapResponse("* SEARCH 23"))); setupSearchResponse("* SEARCH 23"); String uid = folder.getUidFromMessageId(message); Loading @@ -1046,7 +1012,7 @@ public class ImapFolderTest { folder.setFlags(newSet(Flag.SEEN), true); verify(imapConnection).executeSimpleCommand("UID STORE 1:* +FLAGS.SILENT (\\Seen)"); assertCommandIssued("UID STORE 1:* +FLAGS.SILENT (\\Seen)"); } @Test Loading Loading @@ -1077,10 +1043,11 @@ public class ImapFolderTest { prepareImapFolderForOpen(OPEN_MODE_RO); when(storeConfig.allowRemoteSearch()).thenReturn(true); when(storeConfig.isRemoteSearchFullText()).thenReturn(true); setupSearchResponse("1 OK SEARCH completed"); folder.search("query", newSet(Flag.SEEN), Collections.<Flag>emptySet()); verify(imapConnection).executeSimpleCommand("UID SEARCH TEXT \"query\" SEEN"); assertCommandIssued("UID SEARCH TEXT \"query\" SEEN"); } @Test Loading @@ -1089,10 +1056,11 @@ public class ImapFolderTest { prepareImapFolderForOpen(OPEN_MODE_RO); when(storeConfig.allowRemoteSearch()).thenReturn(true); when(storeConfig.isRemoteSearchFullText()).thenReturn(false); setupSearchResponse("1 OK SEARCH completed"); folder.search("query", Collections.<Flag>emptySet(), Collections.<Flag>emptySet()); verify(imapConnection).executeSimpleCommand("UID SEARCH OR SUBJECT \"query\" FROM \"query\""); assertCommandIssued("UID SEARCH OR SUBJECT \"query\" FROM \"query\""); } @Test Loading Loading @@ -1243,4 +1211,32 @@ public class ImapFolderTest { private void assertCheckOpenErrorMessage(String folderName, MessagingException e) { assertEquals("Folder " + folderName + " is not open.", e.getMessage()); } @SuppressWarnings("unchecked") private void assertCommandIssued(String command) throws MessagingException, IOException { verify(imapConnection, atLeastOnce()).executeSelectedStateCommand(commandCaptor.capture()); List<? extends FolderSelectedStateCommand> issuedCommands = commandCaptor.getAllValues(); List<String> stringCommands = new ArrayList<>(issuedCommands.size()); for (FolderSelectedStateCommand issuedCommand : issuedCommands) { stringCommands.addAll(issuedCommand.optimizeAndSplit(false)); } assertEquals(stringCommands.contains(command), true); } private void setupSearchResponse(String... responses) throws MessagingException, IOException { List<ImapResponse> imapResponses = new ArrayList<>(responses.length); for (String response : responses) { imapResponses.add(createImapResponse(response)); } UidSearchResponse searchResponse = UidSearchResponse.parse(singletonList(imapResponses)); when(imapConnection.executeSelectedStateCommand(any(UidSearchCommand.class))) .thenReturn(searchResponse); } private void setupCopyResponse(String response) throws MessagingException, IOException { List<ImapResponse> imapResponse = singletonList(createImapResponse(response)); UidCopyResponse uidCopyResponse = UidCopyResponse.parse(singletonList(imapResponse)); when(imapConnection.executeSelectedStateCommand(any(UidCopyCommand.class))) .thenReturn(uidCopyResponse); } } k9mail-library/src/test/java/com/fsck/k9/mail/store/imap/selectedstate/command/FolderSelectedStateCommandTest.java +9 −12 Original line number Diff line number Diff line package com.fsck.k9.mail.store.imap.selectedstate.command; import java.util.Collections; import java.util.List; import com.fsck.k9.mail.store.imap.ImapConnection; import com.fsck.k9.mail.store.imap.ImapFolder; import com.fsck.k9.mail.store.imap.ImapResponseHelper; import org.junit.Before; import org.junit.Test; import java.util.Collections; import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.internal.util.collections.Sets.newSet; Loading Loading @@ -80,21 +77,21 @@ public class FolderSelectedStateCommandTest { } @Test public void executeInternal_withShortCommand_shouldNotSplitCommand() throws Exception { public void optimizeAndSplit_withShortCommand_shouldNotSplitCommand() throws Exception { TestCommand command = TestCommand.createWithIdSet(newSet(1L, 2L, 3L)); command.executeInternal(imapConnection, imapFolder); List<String> splitCommands = command.optimizeAndSplit(false); verify(imapFolder, times(1)).executeSimpleCommand(anyString()); assertEquals(splitCommands.size(), 1); } @Test public void executeInternal_withLongCommand_shouldSplitCommand() throws Exception { public void optimizeAndSplit_withLongCommand_shouldSplitCommand() throws Exception { TestCommand command = TestCommand.createWithIdSet(ImapResponseHelper .createNonContiguousIdSet(10000L, 10500L, 2)); command.executeInternal(imapConnection, imapFolder); List<String> splitCommands = command.optimizeAndSplit(false); verify(imapFolder, atLeast(2)).executeSimpleCommand(anyString()); assertEquals(splitCommands.size(), 2); } } k9mail-library/src/test/java/com/fsck/k9/mail/store/imap/selectedstate/command/TestCommand.java +10 −1 Original line number Diff line number Diff line package com.fsck.k9.mail.store.imap.selectedstate.command; import java.util.Collections; import java.util.List; import java.util.Set; class TestCommand extends FolderSelectedStateCommand { import com.fsck.k9.mail.store.imap.selectedstate.response.SelectedStateResponse; class TestCommand extends FolderSelectedStateCommand<SelectedStateResponse> { private TestCommand(Set<Long> ids) { super(ids); Loading @@ -14,6 +18,11 @@ class TestCommand extends FolderSelectedStateCommand { return String.format("TEST %s", createCombinedIdString()).trim(); } @Override public SelectedStateResponse parseResponses(List unparsedResponses) { return null; } static TestCommand createWithIdSetAndGroup(Set<Long> ids, Long start, Long end) { TestCommand command = new TestCommand(ids); command.addIdGroup(start, end); Loading Loading
k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapFolder.java +2 −2 Original line number Diff line number Diff line Loading @@ -524,7 +524,7 @@ public class ImapFolder extends Folder<ImapMessage> { .build(); try { UidSearchResponse searchResponse = connection.executeSelectedStateCommand(searchCommand); return getMessages(searchResponse, null); return getMessages(searchResponse, listener); } catch (IOException ioe) { throw ioExceptionHandler(connection, ioe); } Loading Loading @@ -580,7 +580,7 @@ public class ImapFolder extends Folder<ImapMessage> { .build(); try { UidSearchResponse searchResponse = connection.executeSelectedStateCommand(searchCommand); return getMessages(searchResponse, null); return getMessages(searchResponse, listener); } catch (IOException ioe) { throw ioExceptionHandler(connection, ioe); } Loading
k9mail-library/src/test/java/com/fsck/k9/mail/store/imap/ImapFolderTest.java +79 −83 Original line number Diff line number Diff line package com.fsck.k9.mail.store.imap; import java.io.IOException; 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 java.util.TimeZone; import com.fsck.k9.mail.Body; import com.fsck.k9.mail.DefaultBodyFactory; import com.fsck.k9.mail.FetchProfile; Loading @@ -16,7 +26,12 @@ import com.fsck.k9.mail.Part; import com.fsck.k9.mail.internet.BinaryTempFileBody; import com.fsck.k9.mail.internet.MimeHeader; import com.fsck.k9.mail.store.StoreConfig; import com.fsck.k9.mail.store.imap.selectedstate.command.FolderSelectedStateCommand; import com.fsck.k9.mail.store.imap.selectedstate.command.UidCopyCommand; import com.fsck.k9.mail.store.imap.selectedstate.command.UidSearchCommand; import com.fsck.k9.mail.store.imap.selectedstate.response.UidCopyResponse; import com.fsck.k9.mail.store.imap.selectedstate.response.UidSearchResponse; import okio.Buffer; import org.apache.james.mime4j.util.MimeUtil; import org.junit.Before; import org.junit.Test; Loading @@ -26,18 +41,6 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.robolectric.RuntimeEnvironment; import java.io.IOException; 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 java.util.TimeZone; import okio.Buffer; import static com.fsck.k9.mail.Folder.OPEN_MODE_RO; import static com.fsck.k9.mail.Folder.OPEN_MODE_RW; import static com.fsck.k9.mail.store.imap.ImapResponseHelper.createImapResponse; Loading @@ -52,6 +55,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; Loading @@ -66,6 +70,7 @@ public class ImapFolderTest { private ImapStore imapStore; private ImapConnection imapConnection; private StoreConfig storeConfig; private ArgumentCaptor<? extends FolderSelectedStateCommand> commandCaptor; @Before public void setUp() throws Exception { Loading @@ -77,6 +82,7 @@ public class ImapFolderTest { when(imapStore.getStoreConfig()).thenReturn(storeConfig); imapConnection = mock(ImapConnection.class); commandCaptor = ArgumentCaptor.forClass(FolderSelectedStateCommand.class); } @Test Loading Loading @@ -330,10 +336,7 @@ public class ImapFolderTest { prepareImapFolderForOpen(OPEN_MODE_RW); ImapFolder destinationFolder = createFolder("Destination"); List<ImapMessage> messages = singletonList(createImapMessage("1")); List<ImapResponse> copyResponses = singletonList( createImapResponse("x OK [COPYUID 23 1 101] Success") ); when(imapConnection.executeSimpleCommand("UID COPY 1 \"Destination\"")).thenReturn(copyResponses); setupCopyResponse("x OK [COPYUID 23 1 101] Success"); sourceFolder.open(OPEN_MODE_RW); Map<String, String> uidMapping = sourceFolder.copyMessages(messages, destinationFolder); Loading @@ -348,10 +351,7 @@ public class ImapFolderTest { prepareImapFolderForOpen(OPEN_MODE_RW); ImapFolder destinationFolder = createFolder("Destination"); List<ImapMessage> messages = singletonList(createImapMessage("1")); List<ImapResponse> copyResponses = singletonList( createImapResponse("x OK [COPYUID 23 1 101] Success") ); when(imapConnection.executeSimpleCommand("UID COPY 1 \"Destination\"")).thenReturn(copyResponses); setupCopyResponse("x OK [COPYUID 23 1 101] Success"); sourceFolder.open(OPEN_MODE_RW); Map<String, String> uidMapping = sourceFolder.moveMessages(messages, destinationFolder); Loading @@ -366,15 +366,11 @@ public class ImapFolderTest { prepareImapFolderForOpen(OPEN_MODE_RW); ImapFolder destinationFolder = createFolder("Destination"); List<ImapMessage> messages = singletonList(createImapMessage("1")); List<ImapResponse> copyResponses = singletonList( createImapResponse("x OK [COPYUID 23 1 101] Success") ); when(imapConnection.executeSimpleCommand("UID COPY 1 \"Destination\"")).thenReturn(copyResponses); sourceFolder.open(OPEN_MODE_RW); sourceFolder.moveMessages(messages, destinationFolder); verify(imapConnection).executeSimpleCommand("UID STORE 1 +FLAGS.SILENT (\\Deleted)"); assertCommandIssued("UID STORE 1 +FLAGS.SILENT (\\Deleted)"); } @Test Loading Loading @@ -407,7 +403,7 @@ public class ImapFolderTest { folder.delete(messages, "Folder"); verify(imapConnection).executeSimpleCommand("UID STORE 23 +FLAGS.SILENT (\\Deleted)"); assertCommandIssued("UID STORE 23 +FLAGS.SILENT (\\Deleted)"); } @Test Loading @@ -417,15 +413,12 @@ public class ImapFolderTest { ImapFolder trashFolder = createFolder("Trash"); when(imapStore.getFolder("Trash")).thenReturn(trashFolder); List<ImapMessage> messages = singletonList(createImapMessage("2")); List<ImapResponse> copyResponses = singletonList( createImapResponse("x OK [COPYUID 23 2 102] Success") ); when(imapConnection.executeSimpleCommand("UID COPY 2 \"Trash\"")).thenReturn(copyResponses); setupCopyResponse("x OK [COPYUID 23 2 102] Success"); folder.open(OPEN_MODE_RW); folder.delete(messages, "Trash"); verify(imapConnection).executeSimpleCommand("UID STORE 2 +FLAGS.SILENT (\\Deleted)"); assertCommandIssued("UID STORE 2 +FLAGS.SILENT (\\Deleted)"); } @Test Loading Loading @@ -465,7 +458,7 @@ public class ImapFolderTest { public void getUnreadMessageCount_connectionThrowsIOException_shouldThrowMessagingException() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); when(imapConnection.executeSimpleCommand("UID SEARCH 1:* NOT SEEN NOT DELETED")).thenThrow(new IOException()); when(imapConnection.executeSelectedStateCommand(any(UidSearchCommand.class))).thenThrow(new IOException()); folder.open(OPEN_MODE_RW); try { Loading @@ -480,8 +473,7 @@ public class ImapFolderTest { public void getUnreadMessageCount() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = singletonList(createImapResponse("* SEARCH 1 2 3")); when(imapConnection.executeSimpleCommand("UID SEARCH 1:* NOT SEEN NOT DELETED")).thenReturn(imapResponses); setupSearchResponse("* SEARCH 1 2 3"); folder.open(OPEN_MODE_RW); int unreadMessageCount = folder.getUnreadMessageCount(); Loading @@ -506,11 +498,7 @@ public class ImapFolderTest { public void getFlaggedMessageCount() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = asList( createImapResponse("* SEARCH 1 2"), createImapResponse("* SEARCH 23 42") ); when(imapConnection.executeSimpleCommand("UID SEARCH 1:* FLAGGED NOT DELETED")).thenReturn(imapResponses); setupSearchResponse("* SEARCH 1 2", "* SEARCH 23 42"); folder.open(OPEN_MODE_RW); int flaggedMessageCount = folder.getFlaggedMessageCount(); Loading @@ -522,8 +510,7 @@ public class ImapFolderTest { public void getHighestUid() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = singletonList(createImapResponse("* SEARCH 42")); when(imapConnection.executeSimpleCommand("UID SEARCH *:*")).thenReturn(imapResponses); setupSearchResponse("* SEARCH 42"); folder.open(OPEN_MODE_RW); long highestUid = folder.getHighestUid(); Loading @@ -535,7 +522,8 @@ public class ImapFolderTest { public void getHighestUid_imapConnectionThrowsNegativesResponse_shouldReturnMinusOne() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); doThrow(NegativeImapResponseException.class).when(imapConnection).executeSimpleCommand("UID SEARCH *:*"); doThrow(NegativeImapResponseException.class).when(imapConnection) .executeSelectedStateCommand(any(UidSearchCommand.class)); folder.open(OPEN_MODE_RW); long highestUid = folder.getHighestUid(); Loading @@ -547,7 +535,7 @@ public class ImapFolderTest { public void getHighestUid_imapConnectionThrowsIOException_shouldThrowMessagingException() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); doThrow(IOException.class).when(imapConnection).executeSimpleCommand("UID SEARCH *:*"); doThrow(IOException.class).when(imapConnection).executeSelectedStateCommand(any(UidSearchCommand.class)); folder.open(OPEN_MODE_RW); try { Loading @@ -562,12 +550,7 @@ public class ImapFolderTest { public void getMessages_withoutDateConstraint() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = asList( createImapResponse("* SEARCH 3"), createImapResponse("* SEARCH 5"), createImapResponse("* SEARCH 6") ); when(imapConnection.executeSimpleCommand("UID SEARCH 1:10 NOT DELETED")).thenReturn(imapResponses); setupSearchResponse("* SEARCH 3", "* SEARCH 5", "* SEARCH 6"); folder.open(OPEN_MODE_RW); List<ImapMessage> messages = folder.getMessages(1, 10, null, null); Loading @@ -581,12 +564,7 @@ public class ImapFolderTest { TimeZone.setDefault(TimeZone.getTimeZone("UTC")); ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = asList( createImapResponse("* SEARCH 47"), createImapResponse("* SEARCH 18") ); when(imapConnection.executeSimpleCommand("UID SEARCH 1:10 SINCE 06-Feb-2016 NOT DELETED")) .thenReturn(imapResponses); setupSearchResponse("* SEARCH 47", "* SEARCH 18"); folder.open(OPEN_MODE_RW); List<ImapMessage> messages = folder.getMessages(1, 10, new Date(1454719826000L), null); Loading @@ -599,8 +577,7 @@ public class ImapFolderTest { public void getMessages_withListener_shouldCallListener() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = singletonList(createImapResponse("* SEARCH 99")); when(imapConnection.executeSimpleCommand("UID SEARCH 1:10 NOT DELETED")).thenReturn(imapResponses); setupSearchResponse("* SEARCH 99"); folder.open(OPEN_MODE_RW); MessageRetrievalListener<ImapMessage> listener = createMessageRetrievalListener(); Loading Loading @@ -678,13 +655,7 @@ public class ImapFolderTest { public void getMessages_sequenceNumbers() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = asList( createImapResponse("* SEARCH 17"), createImapResponse("* SEARCH 18"), createImapResponse("* SEARCH 49") ); when(imapConnection.executeSimpleCommand("UID SEARCH 5,1:2 NOT DELETED")) .thenReturn(imapResponses); setupSearchResponse("* SEARCH 17", "* SEARCH 18", "* SEARCH 49"); folder.open(OPEN_MODE_RW); List<ImapMessage> messages = folder.getMessages(newSet(1L, 2L, 5L), false, null); Loading @@ -697,8 +668,7 @@ public class ImapFolderTest { public void getMessages_sequenceNumbers_withListener_shouldCallListener() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = singletonList(createImapResponse("* SEARCH 99")); when(imapConnection.executeSimpleCommand("UID SEARCH 1")).thenReturn(imapResponses); setupSearchResponse("* SEARCH 99"); folder.open(OPEN_MODE_RW); MessageRetrievalListener<ImapMessage> listener = createMessageRetrievalListener(); Loading Loading @@ -727,12 +697,7 @@ public class ImapFolderTest { public void getMessagesFromUids() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = asList( createImapResponse("* SEARCH 11"), createImapResponse("* SEARCH 22"), createImapResponse("* SEARCH 25") ); when(imapConnection.executeSimpleCommand("UID SEARCH UID 11,22,25")).thenReturn(imapResponses); setupSearchResponse("* SEARCH 11", "* SEARCH 22", "* SEARCH 25"); folder.open(OPEN_MODE_RW); List<ImapMessage> messages = folder.getMessagesFromUids(asList("11", "22", "25")); Loading @@ -758,8 +723,7 @@ public class ImapFolderTest { public void areMoreMessagesAvailable_withAdditionalMessages_shouldReturnTrue() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); List<ImapResponse> imapResponses = singletonList(createImapResponse("* SEARCH 42")); when(imapConnection.executeSimpleCommand("UID SEARCH 1:9 NOT DELETED")).thenReturn(imapResponses); setupSearchResponse("* SEARCH 42"); folder.open(OPEN_MODE_RW); boolean areMoreMessagesAvailable = folder.areMoreMessagesAvailable(10, null); Loading @@ -771,6 +735,7 @@ public class ImapFolderTest { public void areMoreMessagesAvailable_withoutAdditionalMessages_shouldReturnFalse() throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); setupSearchResponse("1 OK SEARCH completed"); folder.open(OPEN_MODE_RW); boolean areMoreMessagesAvailable = folder.areMoreMessagesAvailable(600, null); Loading @@ -796,12 +761,13 @@ public class ImapFolderTest { throws Exception { ImapFolder folder = createFolder("Folder"); prepareImapFolderForOpen(OPEN_MODE_RW); setupSearchResponse("1 OK SEARCH Completed"); folder.open(OPEN_MODE_RW); folder.areMoreMessagesAvailable(600, null); verify(imapConnection).executeSimpleCommand("UID SEARCH 100:599 NOT DELETED"); verify(imapConnection).executeSimpleCommand("UID SEARCH 1:99 NOT DELETED"); assertCommandIssued("UID SEARCH 100:599 NOT DELETED"); assertCommandIssued("UID SEARCH 1:99 NOT DELETED"); } @Test Loading Loading @@ -1008,10 +974,11 @@ public class ImapFolderTest { folder.open(OPEN_MODE_RW); ImapMessage message = createImapMessage("2"); when(message.getHeader("Message-ID")).thenReturn(new String[] { "<00000000.0000000@example.org>" }); setupSearchResponse("1 OK SEARCH Completed"); folder.getUidFromMessageId(message); verify(imapConnection).executeSimpleCommand("UID SEARCH HEADER MESSAGE-ID \"<00000000.0000000@example.org>\""); assertCommandIssued("UID SEARCH HEADER MESSAGE-ID \"<00000000.0000000@example.org>\""); } @Test Loading @@ -1021,8 +988,7 @@ public class ImapFolderTest { folder.open(OPEN_MODE_RW); ImapMessage message = createImapMessage("2"); when(message.getHeader("Message-ID")).thenReturn(new String[] { "<00000000.0000000@example.org>" }); when(imapConnection.executeSimpleCommand("UID SEARCH HEADER MESSAGE-ID \"<00000000.0000000@example.org>\"")) .thenReturn(singletonList(createImapResponse("* SEARCH 23"))); setupSearchResponse("* SEARCH 23"); String uid = folder.getUidFromMessageId(message); Loading @@ -1046,7 +1012,7 @@ public class ImapFolderTest { folder.setFlags(newSet(Flag.SEEN), true); verify(imapConnection).executeSimpleCommand("UID STORE 1:* +FLAGS.SILENT (\\Seen)"); assertCommandIssued("UID STORE 1:* +FLAGS.SILENT (\\Seen)"); } @Test Loading Loading @@ -1077,10 +1043,11 @@ public class ImapFolderTest { prepareImapFolderForOpen(OPEN_MODE_RO); when(storeConfig.allowRemoteSearch()).thenReturn(true); when(storeConfig.isRemoteSearchFullText()).thenReturn(true); setupSearchResponse("1 OK SEARCH completed"); folder.search("query", newSet(Flag.SEEN), Collections.<Flag>emptySet()); verify(imapConnection).executeSimpleCommand("UID SEARCH TEXT \"query\" SEEN"); assertCommandIssued("UID SEARCH TEXT \"query\" SEEN"); } @Test Loading @@ -1089,10 +1056,11 @@ public class ImapFolderTest { prepareImapFolderForOpen(OPEN_MODE_RO); when(storeConfig.allowRemoteSearch()).thenReturn(true); when(storeConfig.isRemoteSearchFullText()).thenReturn(false); setupSearchResponse("1 OK SEARCH completed"); folder.search("query", Collections.<Flag>emptySet(), Collections.<Flag>emptySet()); verify(imapConnection).executeSimpleCommand("UID SEARCH OR SUBJECT \"query\" FROM \"query\""); assertCommandIssued("UID SEARCH OR SUBJECT \"query\" FROM \"query\""); } @Test Loading Loading @@ -1243,4 +1211,32 @@ public class ImapFolderTest { private void assertCheckOpenErrorMessage(String folderName, MessagingException e) { assertEquals("Folder " + folderName + " is not open.", e.getMessage()); } @SuppressWarnings("unchecked") private void assertCommandIssued(String command) throws MessagingException, IOException { verify(imapConnection, atLeastOnce()).executeSelectedStateCommand(commandCaptor.capture()); List<? extends FolderSelectedStateCommand> issuedCommands = commandCaptor.getAllValues(); List<String> stringCommands = new ArrayList<>(issuedCommands.size()); for (FolderSelectedStateCommand issuedCommand : issuedCommands) { stringCommands.addAll(issuedCommand.optimizeAndSplit(false)); } assertEquals(stringCommands.contains(command), true); } private void setupSearchResponse(String... responses) throws MessagingException, IOException { List<ImapResponse> imapResponses = new ArrayList<>(responses.length); for (String response : responses) { imapResponses.add(createImapResponse(response)); } UidSearchResponse searchResponse = UidSearchResponse.parse(singletonList(imapResponses)); when(imapConnection.executeSelectedStateCommand(any(UidSearchCommand.class))) .thenReturn(searchResponse); } private void setupCopyResponse(String response) throws MessagingException, IOException { List<ImapResponse> imapResponse = singletonList(createImapResponse(response)); UidCopyResponse uidCopyResponse = UidCopyResponse.parse(singletonList(imapResponse)); when(imapConnection.executeSelectedStateCommand(any(UidCopyCommand.class))) .thenReturn(uidCopyResponse); } }
k9mail-library/src/test/java/com/fsck/k9/mail/store/imap/selectedstate/command/FolderSelectedStateCommandTest.java +9 −12 Original line number Diff line number Diff line package com.fsck.k9.mail.store.imap.selectedstate.command; import java.util.Collections; import java.util.List; import com.fsck.k9.mail.store.imap.ImapConnection; import com.fsck.k9.mail.store.imap.ImapFolder; import com.fsck.k9.mail.store.imap.ImapResponseHelper; import org.junit.Before; import org.junit.Test; import java.util.Collections; import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.internal.util.collections.Sets.newSet; Loading Loading @@ -80,21 +77,21 @@ public class FolderSelectedStateCommandTest { } @Test public void executeInternal_withShortCommand_shouldNotSplitCommand() throws Exception { public void optimizeAndSplit_withShortCommand_shouldNotSplitCommand() throws Exception { TestCommand command = TestCommand.createWithIdSet(newSet(1L, 2L, 3L)); command.executeInternal(imapConnection, imapFolder); List<String> splitCommands = command.optimizeAndSplit(false); verify(imapFolder, times(1)).executeSimpleCommand(anyString()); assertEquals(splitCommands.size(), 1); } @Test public void executeInternal_withLongCommand_shouldSplitCommand() throws Exception { public void optimizeAndSplit_withLongCommand_shouldSplitCommand() throws Exception { TestCommand command = TestCommand.createWithIdSet(ImapResponseHelper .createNonContiguousIdSet(10000L, 10500L, 2)); command.executeInternal(imapConnection, imapFolder); List<String> splitCommands = command.optimizeAndSplit(false); verify(imapFolder, atLeast(2)).executeSimpleCommand(anyString()); assertEquals(splitCommands.size(), 2); } }
k9mail-library/src/test/java/com/fsck/k9/mail/store/imap/selectedstate/command/TestCommand.java +10 −1 Original line number Diff line number Diff line package com.fsck.k9.mail.store.imap.selectedstate.command; import java.util.Collections; import java.util.List; import java.util.Set; class TestCommand extends FolderSelectedStateCommand { import com.fsck.k9.mail.store.imap.selectedstate.response.SelectedStateResponse; class TestCommand extends FolderSelectedStateCommand<SelectedStateResponse> { private TestCommand(Set<Long> ids) { super(ids); Loading @@ -14,6 +18,11 @@ class TestCommand extends FolderSelectedStateCommand { return String.format("TEST %s", createCombinedIdString()).trim(); } @Override public SelectedStateResponse parseResponses(List unparsedResponses) { return null; } static TestCommand createWithIdSetAndGroup(Set<Long> ids, Long start, Long end) { TestCommand command = new TestCommand(ids); command.addIdGroup(start, end); Loading