From 002b70fcf9c99a8651dbfadd041dc91a767f0265 Mon Sep 17 00:00:00 2001 From: cketti Date: Wed, 10 Aug 2022 17:41:36 +0200 Subject: [PATCH] Convert `RealImapStoreTest` to Kotlin --- .../k9/mail/store/imap/RealImapStoreTest.kt | 670 ++++++++---------- 1 file changed, 311 insertions(+), 359 deletions(-) diff --git a/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapStoreTest.kt b/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapStoreTest.kt index e87a95b06..113b42f20 100644 --- a/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapStoreTest.kt +++ b/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapStoreTest.kt @@ -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 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 folders = imapStore.getFolders(); + val folders = imapStore.getFolders() - Map 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 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 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 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 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 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 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 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 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 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 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 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 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 extra = ImapStoreSettings.createExtra(true, null); - return new ServerSettings( - "imap", - "imap.example.org", - 143, - ConnectionSecurity.NONE, - AuthType.PLAIN, - "user", - "password", - null, - extra); - } - - private Set extractFolderServerIds(List folders) { - Set 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 extractFolderNames(List folders) { - Set 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 extractOldFolderServerIds(List folders) { - Set 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 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 toFolderMap(List folders) { - Map 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 = ArrayDeque() + private var testCombinedPrefix: String? = null - static class TestImapStore extends RealImapStore { - private Deque 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 } } }