Convert RealImapStoreTest to Kotlin

This commit is contained in:
cketti 2022-08-10 17:41:36 +02:00
parent 48f13ca3dc
commit 002b70fcf9

View file

@ -1,489 +1,441 @@
package com.fsck.k9.mail.store.imap;
package com.fsck.k9.mail.store.imap
import com.fsck.k9.mail.AuthType
import com.fsck.k9.mail.ConnectionSecurity
import com.fsck.k9.mail.FolderType
import com.fsck.k9.mail.MessagingException
import com.fsck.k9.mail.ServerSettings
import com.fsck.k9.mail.oauth.OAuth2TokenProvider
import com.fsck.k9.mail.ssl.TrustedSocketFactory
import com.fsck.k9.mail.store.imap.ImapResponseHelper.createImapResponse
import com.fsck.k9.mail.store.imap.ImapStoreSettings.createExtra
import com.google.common.truth.Truth.assertThat
import java.io.IOException
import java.util.ArrayDeque
import java.util.Deque
import org.junit.Assert.fail
import org.junit.Test
import org.mockito.ArgumentMatchers.anyString
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.doThrow
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.stub
import org.mockito.kotlin.verify
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
class RealImapStoreTest {
private val imapStore = createTestImapStore()
import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.FolderType;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.ServerSettings;
import com.fsck.k9.mail.oauth.OAuth2TokenProvider;
import com.fsck.k9.mail.ssl.TrustedSocketFactory;
import org.jetbrains.annotations.NotNull;
import org.junit.Before;
import org.junit.Test;
import org.mockito.internal.util.collections.Sets;
@Test
fun `checkSettings() should create ImapConnection and call open()`() {
val imapConnection = createMockConnection()
imapStore.enqueueImapConnection(imapConnection)
import static com.fsck.k9.mail.store.imap.ImapResponseHelper.createImapResponse;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
imapStore.checkSettings()
public class RealImapStoreTest {
private ImapStoreConfig config = mock(ImapStoreConfig.class);
private TestImapStore imapStore;
@Before
public void setUp() throws Exception {
ServerSettings serverSettings = createServerSettings();
TrustedSocketFactory trustedSocketFactory = mock(TrustedSocketFactory.class);
OAuth2TokenProvider oauth2TokenProvider = mock(OAuth2TokenProvider.class);
imapStore = new TestImapStore(serverSettings, config, trustedSocketFactory,
oauth2TokenProvider);
verify(imapConnection).open()
}
@Test
public void checkSettings_shouldCreateImapConnectionAndCallOpen() throws Exception {
ImapConnection imapConnection = createMockConnection();
imapStore.enqueueImapConnection(imapConnection);
imapStore.checkSettings();
verify(imapConnection).open();
}
@Test
public void checkSettings_withOpenThrowing_shouldThrowMessagingException() throws Exception {
ImapConnection imapConnection = createMockConnection();
doThrow(IOException.class).when(imapConnection).open();
imapStore.enqueueImapConnection(imapConnection);
fun `checkSettings() with open throwing should throw MessagingException`() {
val imapConnection = createMockConnection().stub {
on { open() } doThrow IOException::class
}
imapStore.enqueueImapConnection(imapConnection)
try {
imapStore.checkSettings();
fail("Expected exception");
} catch (MessagingException e) {
assertEquals("Unable to connect", e.getMessage());
assertNotNull(e.getCause());
assertEquals(IOException.class, e.getCause().getClass());
imapStore.checkSettings()
fail("Expected exception")
} catch (e: MessagingException) {
assertThat(e).hasMessageThat().isEqualTo("Unable to connect")
assertThat(e).hasCauseThat().isInstanceOf(IOException::class.java)
}
}
@Test
public void getFolders_withSpecialUseCapability_shouldReturnSpecialFolderInfo() throws Exception {
ImapConnection imapConnection = createMockConnection();
when(imapConnection.hasCapability(Capabilities.LIST_EXTENDED)).thenReturn(true);
when(imapConnection.hasCapability(Capabilities.SPECIAL_USE)).thenReturn(true);
List<ImapResponse> imapResponses = Arrays.asList(
createImapResponse("* LIST (\\HasNoChildren) \"/\" \"INBOX\""),
createImapResponse("* LIST (\\Noselect \\HasChildren) \"/\" \"[Gmail]\""),
createImapResponse("* LIST (\\HasNoChildren \\All) \"/\" \"[Gmail]/All Mail\""),
createImapResponse("* LIST (\\HasNoChildren \\Drafts) \"/\" \"[Gmail]/Drafts\""),
createImapResponse("* LIST (\\HasNoChildren \\Important) \"/\" \"[Gmail]/Important\""),
createImapResponse("* LIST (\\HasNoChildren \\Sent) \"/\" \"[Gmail]/Sent Mail\""),
createImapResponse("* LIST (\\HasNoChildren \\Junk) \"/\" \"[Gmail]/Spam\""),
createImapResponse("* LIST (\\HasNoChildren \\Flagged) \"/\" \"[Gmail]/Starred\""),
createImapResponse("* LIST (\\HasNoChildren \\Trash) \"/\" \"[Gmail]/Trash\""),
fun `getFolders() with SPECIAL-USE capability should return special FolderInfo`() {
val imapConnection = createMockConnection().stub {
on { hasCapability(Capabilities.LIST_EXTENDED) } doReturn true
on { hasCapability(Capabilities.SPECIAL_USE) } doReturn true
on { executeSimpleCommand("""LIST "" "*" RETURN (SPECIAL-USE)""") } doReturn listOf(
createImapResponse("""* LIST (\HasNoChildren) "/" "INBOX""""),
createImapResponse("""* LIST (\Noselect \HasChildren) "/" "[Gmail]""""),
createImapResponse("""* LIST (\HasNoChildren \All) "/" "[Gmail]/All Mail""""),
createImapResponse("""* LIST (\HasNoChildren \Drafts) "/" "[Gmail]/Drafts""""),
createImapResponse("""* LIST (\HasNoChildren \Important) "/" "[Gmail]/Important""""),
createImapResponse("""* LIST (\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail""""),
createImapResponse("""* LIST (\HasNoChildren \Junk) "/" "[Gmail]/Spam""""),
createImapResponse("""* LIST (\HasNoChildren \Flagged) "/" "[Gmail]/Starred""""),
createImapResponse("""* LIST (\HasNoChildren \Trash) "/" "[Gmail]/Trash""""),
createImapResponse("5 OK Success")
);
when(imapConnection.executeSimpleCommand("LIST \"\" \"*\" RETURN (SPECIAL-USE)")).thenReturn(imapResponses);
imapStore.enqueueImapConnection(imapConnection);
)
}
imapStore.enqueueImapConnection(imapConnection)
List<FolderListItem> folders = imapStore.getFolders();
val folders = imapStore.getFolders()
Map<String, FolderListItem> folderMap = toFolderMap(folders);
assertEquals(FolderType.INBOX, folderMap.get("INBOX").getType());
assertEquals(FolderType.DRAFTS, folderMap.get("[Gmail]/Drafts").getType());
assertEquals(FolderType.SENT, folderMap.get("[Gmail]/Sent Mail").getType());
assertEquals(FolderType.SPAM, folderMap.get("[Gmail]/Spam").getType());
assertEquals(FolderType.TRASH, folderMap.get("[Gmail]/Trash").getType());
assertEquals(FolderType.ARCHIVE, folderMap.get("[Gmail]/All Mail").getType());
val foldersMap = folders.map { it.serverId to it.type }
assertThat(foldersMap).containsExactly(
"INBOX" to FolderType.INBOX,
"[Gmail]/All Mail" to FolderType.ARCHIVE,
"[Gmail]/Drafts" to FolderType.DRAFTS,
"[Gmail]/Important" to FolderType.REGULAR,
"[Gmail]/Sent Mail" to FolderType.SENT,
"[Gmail]/Spam" to FolderType.SPAM,
"[Gmail]/Starred" to FolderType.REGULAR,
"[Gmail]/Trash" to FolderType.TRASH
)
}
@Test
public void getFolders_withoutSpecialUseCapability_shouldUseSimpleListCommand() throws Exception {
ImapConnection imapConnection = createMockConnection();
when(imapConnection.hasCapability(Capabilities.LIST_EXTENDED)).thenReturn(true);
when(imapConnection.hasCapability(Capabilities.SPECIAL_USE)).thenReturn(false);
imapStore.enqueueImapConnection(imapConnection);
fun `getFolders() without SPECIAL-USE capability should use simple LIST command`() {
val imapConnection = createMockConnection().stub {
on { hasCapability(Capabilities.LIST_EXTENDED) } doReturn true
on { hasCapability(Capabilities.SPECIAL_USE) } doReturn false
}
imapStore.enqueueImapConnection(imapConnection)
imapStore.getFolders();
imapStore.getFolders()
verify(imapConnection, never()).executeSimpleCommand("LIST \"\" \"*\" RETURN (SPECIAL-USE)");
verify(imapConnection).executeSimpleCommand("LIST \"\" \"*\"");
verify(imapConnection, never()).executeSimpleCommand("""LIST "" "*" RETURN (SPECIAL-USE)""")
verify(imapConnection).executeSimpleCommand("""LIST "" "*"""")
}
@Test
public void getFolders_withoutListExtendedCapability_shouldUseSimpleListCommand() throws Exception {
ImapConnection imapConnection = createMockConnection();
when(imapConnection.hasCapability(Capabilities.LIST_EXTENDED)).thenReturn(false);
when(imapConnection.hasCapability(Capabilities.SPECIAL_USE)).thenReturn(true);
imapStore.enqueueImapConnection(imapConnection);
fun `getFolders() without LIST-EXTENDED capability should use simple LIST command`() {
val imapConnection = createMockConnection().stub {
on { hasCapability(Capabilities.LIST_EXTENDED) } doReturn false
on { hasCapability(Capabilities.SPECIAL_USE) } doReturn true
}
imapStore.enqueueImapConnection(imapConnection)
imapStore.getFolders();
imapStore.getFolders()
verify(imapConnection, never()).executeSimpleCommand("LIST \"\" \"*\" RETURN (SPECIAL-USE)");
verify(imapConnection).executeSimpleCommand("LIST \"\" \"*\"");
verify(imapConnection, never()).executeSimpleCommand("""LIST "" "*" RETURN (SPECIAL-USE)""")
verify(imapConnection).executeSimpleCommand("""LIST "" "*"""")
}
@Test
public void getFolders_withoutSubscribedFoldersOnly() throws Exception {
when(config.isSubscribedFoldersOnly()).thenReturn(false);
ImapConnection imapConnection = createMockConnection();
List<ImapResponse> imapResponses = Arrays.asList(
createImapResponse("* LIST (\\HasNoChildren) \".\" \"INBOX\""),
createImapResponse("* LIST (\\Noselect \\HasChildren) \".\" \"Folder\""),
createImapResponse("* LIST (\\HasNoChildren) \".\" \"Folder.SubFolder\""),
fun `getFolders() with subscribedFoldersOnly = false`() {
val imapStore = createTestImapStore(isSubscribedFoldersOnly = false)
val imapConnection = createMockConnection().stub {
on { executeSimpleCommand("""LIST "" "*"""") } doReturn listOf(
createImapResponse("""* LIST (\HasNoChildren) "." "INBOX""""),
createImapResponse("""* LIST (\Noselect \HasChildren) "." "Folder""""),
createImapResponse("""* LIST (\HasNoChildren) "." "Folder.SubFolder""""),
createImapResponse("6 OK Success")
);
when(imapConnection.executeSimpleCommand("LIST \"\" \"*\"")).thenReturn(imapResponses);
imapStore.enqueueImapConnection(imapConnection);
)
}
imapStore.enqueueImapConnection(imapConnection)
List<FolderListItem> result = imapStore.getFolders();
val folders = imapStore.getFolders()
assertNotNull(result);
assertEquals(Sets.newSet("INBOX", "Folder.SubFolder"), extractFolderServerIds(result));
assertThat(folders).isNotNull()
assertThat(folders.map { it.serverId }).containsExactly("INBOX", "Folder.SubFolder")
}
@Test
public void getFolders_withSubscribedFoldersOnly_shouldOnlyReturnExistingSubscribedFolders()
throws Exception {
when(config.isSubscribedFoldersOnly()).thenReturn(true);
ImapConnection imapConnection = createMockConnection();
List<ImapResponse> lsubResponses = Arrays.asList(
createImapResponse("* LSUB (\\HasNoChildren) \".\" \"INBOX\""),
createImapResponse("* LSUB (\\Noselect \\HasChildren) \".\" \"Folder\""),
createImapResponse("* LSUB (\\HasNoChildren) \".\" \"Folder.SubFolder\""),
createImapResponse("* LSUB (\\HasNoChildren) \".\" \"SubscribedFolderThatHasBeenDeleted\""),
fun `getFolders() with subscribedFoldersOnly = true should only return existing subscribed folders`() {
val imapStore = createTestImapStore(isSubscribedFoldersOnly = true)
val imapConnection = createMockConnection().stub {
on { executeSimpleCommand("""LSUB "" "*"""") } doReturn listOf(
createImapResponse("""* LSUB (\HasNoChildren) "." "INBOX""""),
createImapResponse("""* LSUB (\Noselect \HasChildren) "." "Folder""""),
createImapResponse("""* LSUB (\HasNoChildren) "." "Folder.SubFolder""""),
createImapResponse("""* LSUB (\HasNoChildren) "." "SubscribedFolderThatHasBeenDeleted""""),
createImapResponse("5 OK Success")
);
when(imapConnection.executeSimpleCommand("LSUB \"\" \"*\"")).thenReturn(lsubResponses);
List<ImapResponse> imapResponses = Arrays.asList(
createImapResponse("* LIST (\\HasNoChildren) \".\" \"INBOX\""),
createImapResponse("* LIST (\\Noselect \\HasChildren) \".\" \"Folder\""),
createImapResponse("* LIST (\\HasNoChildren) \".\" \"Folder.SubFolder\""),
)
on { executeSimpleCommand("""LIST "" "*"""") } doReturn listOf(
createImapResponse("""* LIST (\HasNoChildren) "." "INBOX""""),
createImapResponse("""* LIST (\Noselect \HasChildren) "." "Folder""""),
createImapResponse("""* LIST (\HasNoChildren) "." "Folder.SubFolder""""),
createImapResponse("6 OK Success")
);
when(imapConnection.executeSimpleCommand("LIST \"\" \"*\"")).thenReturn(imapResponses);
imapStore.enqueueImapConnection(imapConnection);
)
}
imapStore.enqueueImapConnection(imapConnection)
List<FolderListItem> result = imapStore.getFolders();
val folders = imapStore.getFolders()
assertNotNull(result);
assertEquals(Sets.newSet("INBOX", "Folder.SubFolder"), extractFolderServerIds(result));
assertThat(folders).isNotNull()
assertThat(folders.map { it.serverId }).containsExactly("INBOX", "Folder.SubFolder")
}
@Test
public void getFolders_withNamespacePrefix() throws Exception {
ImapConnection imapConnection = createMockConnection();
List<ImapResponse> imapResponses = Arrays.asList(
createImapResponse("* LIST () \".\" \"INBOX\""),
createImapResponse("* LIST () \".\" \"INBOX.FolderOne\""),
createImapResponse("* LIST () \".\" \"INBOX.FolderTwo\""),
fun `getFolders() with namespace prefix`() {
val imapConnection = createMockConnection().stub {
on { executeSimpleCommand("""LIST "" "INBOX.*"""") } doReturn listOf(
createImapResponse("""* LIST () "." "INBOX""""),
createImapResponse("""* LIST () "." "INBOX.FolderOne""""),
createImapResponse("""* LIST () "." "INBOX.FolderTwo""""),
createImapResponse("5 OK Success")
);
when(imapConnection.executeSimpleCommand("LIST \"\" \"INBOX.*\"")).thenReturn(imapResponses);
imapStore.enqueueImapConnection(imapConnection);
imapStore.setTestCombinedPrefix("INBOX.");
)
}
imapStore.enqueueImapConnection(imapConnection)
imapStore.setTestCombinedPrefix("INBOX.")
List<FolderListItem> result = imapStore.getFolders();
val folders = imapStore.getFolders()
assertNotNull(result);
assertEquals(Sets.newSet("INBOX", "INBOX.FolderOne", "INBOX.FolderTwo"), extractFolderServerIds(result));
assertEquals(Sets.newSet("INBOX", "FolderOne", "FolderTwo"), extractFolderNames(result));
assertEquals(Sets.newSet("INBOX", "FolderOne", "FolderTwo"), extractOldFolderServerIds(result));
assertThat(folders).isNotNull()
assertThat(folders.map { it.serverId }).containsExactly("INBOX", "INBOX.FolderOne", "INBOX.FolderTwo")
assertThat(folders.map { it.name }).containsExactly("INBOX", "FolderOne", "FolderTwo")
assertThat(folders.map { it.oldServerId }).containsExactly("INBOX", "FolderOne", "FolderTwo")
}
@Test
public void getFolders_withFolderNotMatchingNamespacePrefix() throws Exception {
ImapConnection imapConnection = createMockConnection();
List<ImapResponse> imapResponses = Arrays.asList(
createImapResponse("* LIST () \".\" \"INBOX\""),
createImapResponse("* LIST () \".\" \"INBOX.FolderOne\""),
createImapResponse("* LIST () \".\" \"FolderTwo\""),
fun `getFolders() with folder not matching namespace prefix`() {
val imapConnection = createMockConnection().stub {
on { executeSimpleCommand("""LIST "" "INBOX.*"""") } doReturn listOf(
createImapResponse("""* LIST () "." "INBOX""""),
createImapResponse("""* LIST () "." "INBOX.FolderOne""""),
createImapResponse("""* LIST () "." "FolderTwo""""),
createImapResponse("5 OK Success")
);
when(imapConnection.executeSimpleCommand("LIST \"\" \"INBOX.*\"")).thenReturn(imapResponses);
imapStore.enqueueImapConnection(imapConnection);
imapStore.setTestCombinedPrefix("INBOX.");
)
}
imapStore.enqueueImapConnection(imapConnection)
imapStore.setTestCombinedPrefix("INBOX.")
List<FolderListItem> result = imapStore.getFolders();
val folders = imapStore.getFolders()
assertNotNull(result);
assertEquals(Sets.newSet("INBOX", "INBOX.FolderOne", "FolderTwo"), extractFolderServerIds(result));
assertEquals(Sets.newSet("INBOX", "FolderOne", "FolderTwo"), extractFolderNames(result));
assertEquals(Sets.newSet("INBOX", "FolderOne"), extractOldFolderServerIds(result));
assertThat(folders).isNotNull()
assertThat(folders.map { it.serverId }).containsExactly("INBOX", "INBOX.FolderOne", "FolderTwo")
assertThat(folders.map { it.name }).containsExactly("INBOX", "FolderOne", "FolderTwo")
assertThat(folders.mapNotNull { it.oldServerId }).containsExactly("INBOX", "FolderOne")
}
@Test
public void getFolders_withDuplicateFolderNames_shouldRemoveDuplicatesAndKeepFolderType()
throws Exception {
ImapConnection imapConnection = createMockConnection();
when(imapConnection.hasCapability(Capabilities.LIST_EXTENDED)).thenReturn(true);
when(imapConnection.hasCapability(Capabilities.SPECIAL_USE)).thenReturn(true);
List<ImapResponse> imapResponses = Arrays.asList(
createImapResponse("* LIST () \".\" \"INBOX\""),
createImapResponse("* LIST (\\HasNoChildren) \".\" \"Junk\""),
createImapResponse("* LIST (\\Junk) \".\" \"Junk\""),
createImapResponse("* LIST (\\HasNoChildren) \".\" \"Junk\""),
fun `getFolders() with duplicate folder names should remove duplicates and keep FolderType`() {
val imapConnection = createMockConnection().stub {
on { hasCapability(Capabilities.LIST_EXTENDED) } doReturn true
on { hasCapability(Capabilities.SPECIAL_USE) } doReturn true
on { executeSimpleCommand("""LIST "" "*" RETURN (SPECIAL-USE)""") } doReturn listOf(
createImapResponse("""* LIST () "." "INBOX""""),
createImapResponse("""* LIST (\HasNoChildren) "." "Junk""""),
createImapResponse("""* LIST (\Junk) "." "Junk""""),
createImapResponse("""* LIST (\HasNoChildren) "." "Junk""""),
createImapResponse("5 OK Success")
);
when(imapConnection.executeSimpleCommand("LIST \"\" \"*\" RETURN (SPECIAL-USE)")).thenReturn(imapResponses);
imapStore.enqueueImapConnection(imapConnection);
)
}
imapStore.enqueueImapConnection(imapConnection)
List<FolderListItem> result = imapStore.getFolders();
val folders = imapStore.getFolders()
assertNotNull(result);
assertEquals(2, result.size());
FolderListItem junkFolder = getFolderByServerId(result, "Junk");
assertNotNull(junkFolder);
assertEquals(FolderType.SPAM, junkFolder.getType());
assertThat(folders.map { it.serverId to it.type }).containsExactly(
"INBOX" to FolderType.INBOX,
"Junk" to FolderType.SPAM
)
}
@Test
public void getFolders_withoutException_shouldLeaveImapConnectionOpen() throws Exception {
ImapConnection imapConnection = createMockConnection();
List<ImapResponse> imapResponses = Collections.singletonList(createImapResponse("5 OK Success"));
when(imapConnection.executeSimpleCommand(anyString())).thenReturn(imapResponses);
imapStore.enqueueImapConnection(imapConnection);
fun `getFolders() without exception should leave ImapConnection open`() {
val imapConnection = createMockConnection().stub {
on { executeSimpleCommand(anyString()) } doReturn listOf(createImapResponse("5 OK Success"))
}
imapStore.enqueueImapConnection(imapConnection)
imapStore.getFolders();
imapStore.getFolders()
verify(imapConnection, never()).close();
verify(imapConnection, never()).close()
}
@Test
public void getFolders_withIoException_shouldCloseImapConnection() throws Exception {
ImapConnection imapConnection = createMockConnection();
doThrow(IOException.class).when(imapConnection).executeSimpleCommand("LIST \"\" \"*\"");
imapStore.enqueueImapConnection(imapConnection);
fun `getFolders() with IOException should close ImapConnection`() {
val imapConnection = createMockConnection().stub {
on { executeSimpleCommand("""LIST "" "*"""") } doThrow IOException::class
}
imapStore.enqueueImapConnection(imapConnection)
try {
imapStore.getFolders();
fail("Expected exception");
} catch (MessagingException ignored) {
imapStore.getFolders()
fail("Expected exception")
} catch (ignored: MessagingException) {
}
verify(imapConnection).close();
verify(imapConnection).close()
}
@Test
public void getConnection_shouldCreateImapConnection() throws Exception {
ImapConnection imapConnection = createMockConnection();
imapStore.enqueueImapConnection(imapConnection);
fun `getConnection() should create ImapConnection`() {
val imapConnection = createMockConnection()
imapStore.enqueueImapConnection(imapConnection)
ImapConnection result = imapStore.getConnection();
val result = imapStore.getConnection()
assertSame(imapConnection, result);
assertThat(result).isSameInstanceAs(imapConnection)
}
@Test
public void getConnection_calledTwiceWithoutRelease_shouldCreateTwoImapConnection() throws Exception {
ImapConnection imapConnectionOne = createMockConnection();
ImapConnection imapConnectionTwo = createMockConnection();
imapStore.enqueueImapConnection(imapConnectionOne);
imapStore.enqueueImapConnection(imapConnectionTwo);
fun `getConnection() called twice without release should create two ImapConnection instances`() {
val imapConnectionOne = createMockConnection()
val imapConnectionTwo = createMockConnection()
imapStore.enqueueImapConnection(imapConnectionOne)
imapStore.enqueueImapConnection(imapConnectionTwo)
ImapConnection resultOne = imapStore.getConnection();
ImapConnection resultTwo = imapStore.getConnection();
val resultOne = imapStore.getConnection()
val resultTwo = imapStore.getConnection()
assertSame(imapConnectionOne, resultOne);
assertSame(imapConnectionTwo, resultTwo);
assertThat(resultOne).isSameInstanceAs(imapConnectionOne)
assertThat(resultTwo).isSameInstanceAs(imapConnectionTwo)
}
@Test
public void getConnection_calledAfterRelease_shouldReturnCachedImapConnection() throws Exception {
ImapConnection imapConnection = createMockConnection();
when(imapConnection.isConnected()).thenReturn(true);
imapStore.enqueueImapConnection(imapConnection);
ImapConnection connection = imapStore.getConnection();
imapStore.releaseConnection(connection);
fun `getConnection() called after release should return cached ImapConnection`() {
val imapConnection = createMockConnection().stub {
on { isConnected } doReturn true
}
imapStore.enqueueImapConnection(imapConnection)
ImapConnection result = imapStore.getConnection();
val connection = imapStore.getConnection()
imapStore.releaseConnection(connection)
assertSame(imapConnection, result);
val result = imapStore.getConnection()
assertThat(result).isSameInstanceAs(imapConnection)
}
@Test
public void getConnection_calledAfterReleaseWithAClosedConnection_shouldReturnNewImapConnectionInstance()
throws Exception {
ImapConnection imapConnectionOne = createMockConnection();
ImapConnection imapConnectionTwo = createMockConnection();
imapStore.enqueueImapConnection(imapConnectionOne);
imapStore.enqueueImapConnection(imapConnectionTwo);
imapStore.getConnection();
when(imapConnectionOne.isConnected()).thenReturn(false);
imapStore.releaseConnection(imapConnectionOne);
fun `getConnection() called after release with closed connection should return new ImapConnection instance`() {
val imapConnectionOne = createMockConnection()
val imapConnectionTwo = createMockConnection()
imapStore.enqueueImapConnection(imapConnectionOne)
imapStore.enqueueImapConnection(imapConnectionTwo)
ImapConnection result = imapStore.getConnection();
imapStore.getConnection()
imapConnectionOne.stub {
on { isConnected } doReturn false
}
imapStore.releaseConnection(imapConnectionOne)
assertSame(imapConnectionTwo, result);
val result = imapStore.getConnection()
assertThat(result).isSameInstanceAs(imapConnectionTwo)
}
@Test
public void getConnection_withDeadConnectionInPool_shouldReturnNewImapConnectionInstance() throws Exception {
ImapConnection imapConnectionOne = createMockConnection();
ImapConnection imapConnectionTwo = createMockConnection();
imapStore.enqueueImapConnection(imapConnectionOne);
imapStore.enqueueImapConnection(imapConnectionTwo);
imapStore.getConnection();
when(imapConnectionOne.isConnected()).thenReturn(true);
doThrow(IOException.class).when(imapConnectionOne).executeSimpleCommand(Commands.NOOP);
imapStore.releaseConnection(imapConnectionOne);
fun `getConnection() with dead connection in pool should return new ImapConnection instance`() {
val imapConnectionOne = createMockConnection()
val imapConnectionTwo = createMockConnection()
imapStore.enqueueImapConnection(imapConnectionOne)
imapStore.enqueueImapConnection(imapConnectionTwo)
ImapConnection result = imapStore.getConnection();
imapStore.getConnection()
imapConnectionOne.stub {
on { isConnected } doReturn true
on { executeSimpleCommand(Commands.NOOP) } doThrow IOException::class
}
imapStore.releaseConnection(imapConnectionOne)
assertSame(imapConnectionTwo, result);
val result = imapStore.getConnection()
assertThat(result).isSameInstanceAs(imapConnectionTwo)
}
@Test
public void getConnection_withConnectionInPoolAndCloseAllConnections_shouldReturnNewImapConnectionInstance()
throws Exception {
ImapConnection imapConnectionOne = createMockConnection(1);
ImapConnection imapConnectionTwo = createMockConnection(2);
imapStore.enqueueImapConnection(imapConnectionOne);
imapStore.enqueueImapConnection(imapConnectionTwo);
imapStore.getConnection();
when(imapConnectionOne.isConnected()).thenReturn(true);
imapStore.releaseConnection(imapConnectionOne);
imapStore.closeAllConnections();
fun `getConnection() with connection in pool and closeAllConnections() should return new ImapConnection instance`() {
val imapConnectionOne = createMockConnection(1)
val imapConnectionTwo = createMockConnection(2)
imapStore.enqueueImapConnection(imapConnectionOne)
imapStore.enqueueImapConnection(imapConnectionTwo)
ImapConnection result = imapStore.getConnection();
imapStore.getConnection()
imapConnectionOne.stub {
on { isConnected } doReturn true
}
imapStore.releaseConnection(imapConnectionOne)
imapStore.closeAllConnections()
assertSame(imapConnectionTwo, result);
val result = imapStore.getConnection()
assertThat(result).isSameInstanceAs(imapConnectionTwo)
}
@Test
public void getConnection_withConnectionOutsideOfPoolAndCloseAllConnections_shouldReturnNewImapConnectionInstance()
throws Exception {
ImapConnection imapConnectionOne = createMockConnection(1);
ImapConnection imapConnectionTwo = createMockConnection(2);
imapStore.enqueueImapConnection(imapConnectionOne);
imapStore.enqueueImapConnection(imapConnectionTwo);
imapStore.getConnection();
when(imapConnectionOne.isConnected()).thenReturn(true);
imapStore.closeAllConnections();
imapStore.releaseConnection(imapConnectionOne);
fun `getConnection() with connection outside of pool and closeAllConnections() should return new ImapConnection instance`() {
val imapConnectionOne = createMockConnection(1)
val imapConnectionTwo = createMockConnection(2)
imapStore.enqueueImapConnection(imapConnectionOne)
imapStore.enqueueImapConnection(imapConnectionTwo)
ImapConnection result = imapStore.getConnection();
assertSame(imapConnectionTwo, result);
}
private ImapConnection createMockConnection() {
ImapConnection imapConnection = mock(ImapConnection.class);
when(imapConnection.getConnectionGeneration()).thenReturn(1);
return imapConnection;
}
private ImapConnection createMockConnection(int connectionGeneration) {
ImapConnection imapConnection = mock(ImapConnection.class);
when(imapConnection.getConnectionGeneration()).thenReturn(connectionGeneration);
return imapConnection;
}
private ServerSettings createServerSettings() {
Map<String, String> extra = ImapStoreSettings.createExtra(true, null);
return new ServerSettings(
"imap",
"imap.example.org",
143,
ConnectionSecurity.NONE,
AuthType.PLAIN,
"user",
"password",
null,
extra);
}
private Set<String> extractFolderServerIds(List<FolderListItem> folders) {
Set<String> folderServerIds = new HashSet<>(folders.size());
for (FolderListItem folder : folders) {
folderServerIds.add(folder.getServerId());
imapStore.getConnection()
imapConnectionOne.stub {
on { isConnected } doReturn true
}
imapStore.closeAllConnections()
imapStore.releaseConnection(imapConnectionOne)
return folderServerIds;
val result = imapStore.getConnection()
assertThat(result).isSameInstanceAs(imapConnectionTwo)
}
private Set<String> extractFolderNames(List<FolderListItem> folders) {
Set<String> folderNames = new HashSet<>(folders.size());
for (FolderListItem folder : folders) {
folderNames.add(folder.getName());
private fun createMockConnection(connectionGeneration: Int = 1): ImapConnection {
return mock {
on { this.connectionGeneration } doReturn connectionGeneration
}
return folderNames;
}
private Set<String> extractOldFolderServerIds(List<FolderListItem> folders) {
Set<String> folderNames = new HashSet<>(folders.size());
for (FolderListItem folder : folders) {
String oldServerId = folder.getOldServerId();
if (oldServerId != null) {
folderNames.add(oldServerId);
}
}
return folderNames;
private fun createServerSettings(): ServerSettings {
return ServerSettings(
type = "imap",
host = "imap.example.org",
port = 143,
connectionSecurity = ConnectionSecurity.NONE,
authenticationType = AuthType.PLAIN,
username = "user",
password = "password",
clientCertificateAlias = null,
extra = createExtra(autoDetectNamespace = true, pathPrefix = null)
)
}
private FolderListItem getFolderByServerId(List<FolderListItem> result, String serverId) {
for (FolderListItem imapFolder : result) {
if (imapFolder.getServerId().equals(serverId)) {
return imapFolder;
}
}
return null;
private fun createTestImapStore(
isSubscribedFoldersOnly: Boolean = false,
useCompression: Boolean = false
): TestImapStore {
return TestImapStore(
serverSettings = createServerSettings(),
config = createImapStoreConfig(isSubscribedFoldersOnly, useCompression),
trustedSocketFactory = mock(),
oauth2TokenProvider = null
)
}
private Map<String, FolderListItem> toFolderMap(List<FolderListItem> folders) {
Map<String, FolderListItem> folderMap = new HashMap<>();
for (FolderListItem folder : folders) {
folderMap.put(folder.getServerId(), folder);
private fun createImapStoreConfig(isSubscribedFoldersOnly: Boolean, useCompression: Boolean): ImapStoreConfig {
return object : ImapStoreConfig {
override val logLabel: String = "irrelevant"
override fun isSubscribedFoldersOnly(): Boolean = isSubscribedFoldersOnly
override fun useCompression(): Boolean = useCompression
}
return folderMap;
}
private class TestImapStore(
serverSettings: ServerSettings,
config: ImapStoreConfig,
trustedSocketFactory: TrustedSocketFactory,
oauth2TokenProvider: OAuth2TokenProvider?
) : RealImapStore(
serverSettings, config, trustedSocketFactory, oauth2TokenProvider
) {
private val imapConnections: Deque<ImapConnection> = ArrayDeque()
private var testCombinedPrefix: String? = null
static class TestImapStore extends RealImapStore {
private Deque<ImapConnection> imapConnections = new ArrayDeque<>();
private String testCombinedPrefix;
public TestImapStore(ServerSettings serverSettings, ImapStoreConfig config,
TrustedSocketFactory trustedSocketFactory, OAuth2TokenProvider oauth2TokenProvider) {
super(serverSettings, config, trustedSocketFactory, oauth2TokenProvider);
}
@Override
public ImapConnection createImapConnection() {
override fun createImapConnection(): ImapConnection {
if (imapConnections.isEmpty()) {
throw new AssertionError("Unexpectedly tried to create an ImapConnection instance");
throw AssertionError("Unexpectedly tried to create an ImapConnection instance")
}
return imapConnections.pop();
return imapConnections.pop()
}
public void enqueueImapConnection(ImapConnection imapConnection) {
imapConnections.add(imapConnection);
fun enqueueImapConnection(imapConnection: ImapConnection) {
imapConnections.add(imapConnection)
}
@Override
@NotNull
public String getCombinedPrefix() {
return testCombinedPrefix != null ? testCombinedPrefix : super.getCombinedPrefix();
override fun getCombinedPrefix(): String {
return testCombinedPrefix ?: super.getCombinedPrefix()
}
void setTestCombinedPrefix(String prefix) {
testCombinedPrefix = prefix;
fun setTestCombinedPrefix(prefix: String?) {
testCombinedPrefix = prefix
}
}
}