Merge pull request #7722 from thunderbird/expunge_handling
IMAP: Change EXPUNGE behavior after moving a message
This commit is contained in:
commit
8ef13f5dcd
10 changed files with 51 additions and 5 deletions
|
@ -2,6 +2,7 @@ package com.fsck.k9.backends
|
|||
|
||||
import android.content.Context
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.Account.Expunge
|
||||
import com.fsck.k9.backend.BackendFactory
|
||||
import com.fsck.k9.backend.api.Backend
|
||||
import com.fsck.k9.backend.imap.ImapBackend
|
||||
|
@ -74,6 +75,8 @@ class ImapBackendFactory(
|
|||
|
||||
override fun isSubscribedFoldersOnly() = account.isSubscribedFoldersOnly
|
||||
|
||||
override fun isExpungeImmediately() = account.expungePolicy == Expunge.EXPUNGE_IMMEDIATELY
|
||||
|
||||
override fun clientId() = ImapClientId(appName = clientIdAppName, appVersion = clientIdAppVersion)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ class ImapFolderFetcher internal constructor(
|
|||
val config = object : ImapStoreConfig {
|
||||
override val logLabel = "folder-fetcher"
|
||||
override fun isSubscribedFoldersOnly() = false
|
||||
override fun isExpungeImmediately() = false
|
||||
override fun clientId() = ImapClientId(appName = clientIdAppName, appVersion = clientIdAppVersion)
|
||||
}
|
||||
val oAuth2TokenProvider = createOAuth2TokenProviderOrNull(authStateStorage)
|
||||
|
|
|
@ -32,6 +32,7 @@ class ImapServerSettingsValidator(
|
|||
val config = object : ImapStoreConfig {
|
||||
override val logLabel = "check"
|
||||
override fun isSubscribedFoldersOnly() = false
|
||||
override fun isExpungeImmediately() = false
|
||||
override fun clientId() = ImapClientId(appName = clientIdAppName, appVersion = clientIdAppVersion)
|
||||
}
|
||||
val oAuth2TokenProvider = createOAuth2TokenProviderOrNull(authStateStorage)
|
||||
|
|
|
@ -3,5 +3,6 @@ package com.fsck.k9.mail.store.imap
|
|||
interface ImapStoreConfig {
|
||||
val logLabel: String
|
||||
fun isSubscribedFoldersOnly(): Boolean
|
||||
fun isExpungeImmediately(): Boolean
|
||||
fun clientId(): ImapClientId
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.fsck.k9.mail.Flag
|
|||
|
||||
internal interface InternalImapStore {
|
||||
val logLabel: String
|
||||
val config: ImapStoreConfig
|
||||
|
||||
fun getCombinedPrefix(): String
|
||||
|
||||
|
|
|
@ -354,7 +354,7 @@ internal class RealImapFolder(
|
|||
|
||||
val uidMapping = copyMessages(messages, folder)
|
||||
setFlags(messages, setOf(Flag.DELETED), true)
|
||||
expungeUidsOnly(uids)
|
||||
expungeUidsAfterDelete(uids)
|
||||
|
||||
return uidMapping
|
||||
}
|
||||
|
@ -1117,8 +1117,8 @@ internal class RealImapFolder(
|
|||
expungeUids(uids, fullExpungeFallback = true)
|
||||
}
|
||||
|
||||
private fun expungeUidsOnly(uids: List<String>) {
|
||||
expungeUids(uids, fullExpungeFallback = false)
|
||||
private fun expungeUidsAfterDelete(uids: List<String>) {
|
||||
expungeUids(uids, fullExpungeFallback = internalImapStore.config.isExpungeImmediately())
|
||||
}
|
||||
|
||||
private fun expungeUids(uids: List<String>, fullExpungeFallback: Boolean) {
|
||||
|
|
|
@ -20,7 +20,7 @@ import java.util.LinkedList
|
|||
|
||||
internal open class RealImapStore(
|
||||
private val serverSettings: ServerSettings,
|
||||
private val config: ImapStoreConfig,
|
||||
override val config: ImapStoreConfig,
|
||||
private val trustedSocketFactory: TrustedSocketFactory,
|
||||
private val oauthTokenProvider: OAuth2TokenProvider?,
|
||||
) : ImapStore, ImapConnectionManager, InternalImapStore {
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package com.fsck.k9.mail.store.imap
|
||||
|
||||
class FakeImapStoreConfig : ImapStoreConfig {
|
||||
var expungeImmediately = true
|
||||
|
||||
override var logLabel: String = "irrelevant"
|
||||
|
||||
override fun isSubscribedFoldersOnly(): Boolean {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
}
|
||||
|
||||
override fun isExpungeImmediately(): Boolean = expungeImmediately
|
||||
|
||||
override fun clientId(): ImapClientId {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
}
|
||||
}
|
|
@ -54,8 +54,10 @@ import org.mockito.kotlin.stub
|
|||
import org.mockito.kotlin.whenever
|
||||
|
||||
class RealImapFolderTest {
|
||||
private val imapStoreConfig = FakeImapStoreConfig()
|
||||
private val internalImapStore = object : InternalImapStore {
|
||||
override val logLabel = "Account"
|
||||
override val config = imapStoreConfig
|
||||
override fun getCombinedPrefix() = ""
|
||||
override fun getPermanentFlagsIndex() = mutableSetOf<Flag>()
|
||||
}
|
||||
|
@ -355,7 +357,26 @@ class RealImapFolderTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `moveMessages() should delete messages from source folder but not issue EXPUNGE command`() {
|
||||
fun `moveMessages() with expungeImmediately = true should delete and expunge`() {
|
||||
imapStoreConfig.expungeImmediately = true
|
||||
val sourceFolder = createFolder("Folder")
|
||||
prepareImapFolderForOpen(OpenMode.READ_WRITE)
|
||||
imapConnection.stub {
|
||||
on { isUidPlusCapable } doReturn false
|
||||
}
|
||||
val destinationFolder = createFolder("Destination")
|
||||
val messages = listOf(createImapMessage("1"))
|
||||
sourceFolder.open(OpenMode.READ_WRITE)
|
||||
|
||||
sourceFolder.moveMessages(messages, destinationFolder)
|
||||
|
||||
assertCommandWithIdsIssued("UID STORE 1 +FLAGS.SILENT (\\Deleted)")
|
||||
assertCommandIssued("EXPUNGE")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `moveMessages() with expungeImmediately = false should delete but not expunge`() {
|
||||
imapStoreConfig.expungeImmediately = false
|
||||
val sourceFolder = createFolder("Folder")
|
||||
prepareImapFolderForOpen(OpenMode.READ_WRITE)
|
||||
imapConnection.stub {
|
||||
|
|
|
@ -408,6 +408,7 @@ class RealImapStoreTest {
|
|||
return object : ImapStoreConfig {
|
||||
override val logLabel: String = "irrelevant"
|
||||
override fun isSubscribedFoldersOnly(): Boolean = isSubscribedFoldersOnly
|
||||
override fun isExpungeImmediately(): Boolean = true
|
||||
override fun clientId(): ImapClientId = ImapClientId(appName = "irrelevant", appVersion = "irrelevant")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue