Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package net.thunderbird.core.preference

import net.thunderbird.core.preference.storage.Storage
import net.thunderbird.core.preference.storage.StorageEditor

private const val OLD_KEY = "account_setup_auto_expand_folder"
private const val NEW_KEY = "auto_select_folder"

class FolderListPreferenceMigration(
private val storage: Storage,
private val editor: StorageEditor,
) {

fun apply() {
if (storage.contains(OLD_KEY)) {
val value = storage.getString(OLD_KEY)
editor.putString(NEW_KEY, value)
editor.remove(OLD_KEY)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package net.thunderbird.core.preference

import assertk.assertThat
import assertk.assertions.isEqualTo
import assertk.assertions.isFalse
import assertk.assertions.isTrue
import kotlin.test.Test
import net.thunderbird.core.preference.storage.Storage
import net.thunderbird.core.preference.storage.StorageEditor

class FolderListPreferenceMigrationTest {
private val OLD_KEY = "account_setup_auto_expand_folder"
private val NEW_KEY = "auto_select_folder"

@Test
fun `apply should migrate value when OLD_KEY exists`() {
// Given
val storage = FakeStorage().apply {
setString(OLD_KEY, "inbox")
}
val editor = FakeStorageEditor(storage)

val migration = FolderListPreferenceMigration(storage, editor)

// When
migration.apply()
editor.commit()

// Then
assertThat(storage.contains(NEW_KEY)).isTrue()
assertThat(storage.getString(NEW_KEY)).isEqualTo("inbox")

assertThat(storage.contains(OLD_KEY)).isFalse()
}

@Test
fun `apply should do nothing when OLD_KEY does not exist`() {
// Given
val storage = FakeStorage()
val editor = FakeStorageEditor(storage)
val migration = FolderListPreferenceMigration(storage, editor)

// When
migration.apply()
editor.commit()

// Then
assertThat(storage.contains(NEW_KEY)).isFalse()
assertThat(storage.contains(OLD_KEY)).isFalse()
}
}

class FakeStorage : Storage {

private val map = mutableMapOf<String, Any?>()

internal fun applyChanges(changes: Map<String, Any?>, removals: Set<String>) {
removals.forEach { map.remove(it) }
changes.forEach { (k, v) -> map[k] = v }
}

override fun isEmpty(): Boolean {
error("Not Implemented")
}

override fun contains(key: String): Boolean = map.containsKey(key)

override fun getAll(): Map<String, String> {
error("Not Implemented")
}

override fun getBoolean(key: String, defValue: Boolean): Boolean {
error("Not Implemented")
}

override fun getInt(key: String, defValue: Int): Int {
error("Not Implemented")
}

override fun getLong(key: String, defValue: Long): Long {
error("Not Implemented")
}

override fun getString(key: String): String =
map[key] as String? ?: throw NoSuchElementException()

override fun getStringOrDefault(key: String, defValue: String): String {
error("Not Implemented")
}

override fun getStringOrNull(key: String): String? {
error("Not Implemented")
}

fun setString(key: String, value: String?) {
map[key] = value
}

fun remove(key: String) {
map.remove(key)
}
}

class FakeStorageEditor(
private val storage: FakeStorage,
) : StorageEditor {

private val pendingChanges = mutableMapOf<String, Any?>()
private val pendingRemovals = mutableSetOf<String>()

override fun putBoolean(key: String, value: Boolean): StorageEditor {
pendingChanges[key] = value
return this
}

override fun putInt(key: String, value: Int): StorageEditor {
pendingChanges[key] = value
return this
}

override fun putLong(key: String, value: Long): StorageEditor {
pendingChanges[key] = value
return this
}

override fun putString(key: String, value: String?): StorageEditor {
pendingChanges[key] = value
return this
}

override fun remove(key: String): StorageEditor {
pendingRemovals.add(key)
return this
}

override fun commit(): Boolean {
storage.applyChanges(pendingChanges, pendingRemovals)
pendingChanges.clear()
pendingRemovals.clear()
return true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import net.thunderbird.core.android.account.LegacyAccountDtoManager
import net.thunderbird.core.logging.config.DebugLogConfigurator
import net.thunderbird.core.logging.config.PlatformInitializer
import net.thunderbird.core.preference.DefaultPreferenceChangeBroker
import net.thunderbird.core.preference.FolderListPreferenceMigration
import net.thunderbird.core.preference.GeneralSettingsManager
import net.thunderbird.core.preference.PreferenceChangeBroker
import net.thunderbird.core.preference.PreferenceChangePublisher
Expand Down Expand Up @@ -218,6 +219,7 @@ val preferencesModule = module {
)
}

single { FolderListPreferenceMigration(storage = get(), editor = get()) }
single { DefaultPreferenceChangeBroker() }
.binds(
arrayOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import net.thunderbird.core.android.account.LegacyAccountDto
import net.thunderbird.core.android.account.LegacyAccountDtoManager
import net.thunderbird.core.logging.Logger
import net.thunderbird.core.logging.legacy.Log
import net.thunderbird.core.preference.FolderListPreferenceMigration
import net.thunderbird.core.preference.GeneralSettingsManager
import net.thunderbird.core.preference.SplitViewMode
import net.thunderbird.core.preference.interaction.PostRemoveNavigation
Expand Down Expand Up @@ -101,6 +102,7 @@ open class MainActivity :
OnSwitchCompleteListener {

private val preferences: Preferences by inject()
private val folderListPreferenceMigration: FolderListPreferenceMigration by inject()
private val accountManager: LegacyAccountDtoManager by inject()
private val defaultFolderProvider: DefaultFolderProvider by inject()
private val accountRemover: BackgroundAccountRemover by inject()
Expand Down Expand Up @@ -162,6 +164,7 @@ open class MainActivity :
return
}

folderListPreferenceMigration.apply()
val accounts = accountManager.getAccounts()
deleteIncompleteAccounts(accounts)
val hasAccountSetup = accounts.any { it.isFinishedSetup }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ class AccountSettingsDataStore(
"message_format" -> account.messageFormat.name
"quote_style" -> account.quoteStyle.name
"account_quote_prefix" -> account.quotePrefix
"account_setup_auto_expand_folder" -> {
"auto_select_folder" -> {
loadSpecialFolder(account.autoExpandFolderId, SpecialFolderSelection.MANUAL)
}
"archive_folder" -> loadSpecialFolder(account.archiveFolderId, account.archiveFolderSelection)
Expand Down Expand Up @@ -164,7 +164,7 @@ class AccountSettingsDataStore(
"message_format" -> account.messageFormat = MessageFormat.valueOf(value)
"quote_style" -> account.quoteStyle = QuoteStyle.valueOf(value)
"account_quote_prefix" -> account.quotePrefix = value
"account_setup_auto_expand_folder" -> account.autoExpandFolderId = extractFolderId(value)
"auto_select_folder" -> account.autoExpandFolderId = extractFolderId(value)
"archive_folder" -> saveSpecialFolderSelection(value, account::setArchiveFolderId)
"drafts_folder" -> saveSpecialFolderSelection(value, account::setDraftsFolderId)
"sent_folder" -> saveSpecialFolderSelection(value, account::setSentFolderId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), ConfirmationDialogFr
private fun loadFolders(account: LegacyAccountDto) {
viewModel.getFolders(account).observe(this@AccountSettingsFragment) { remoteFolderInfo ->
if (remoteFolderInfo != null) {
setFolders(PREFERENCE_AUTO_EXPAND_FOLDER, remoteFolderInfo.folders)
setFolders(PREFERENCE_AUTO_SELECT_FOLDER, remoteFolderInfo.folders)
setFolders(PREFERENCE_ARCHIVE_FOLDER, remoteFolderInfo, FolderType.ARCHIVE)
setFolders(PREFERENCE_DRAFTS_FOLDER, remoteFolderInfo, FolderType.DRAFTS)
setFolders(PREFERENCE_SENT_FOLDER, remoteFolderInfo, FolderType.SENT)
Expand Down Expand Up @@ -480,7 +480,7 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), ConfirmationDialogFr
private const val PREFERENCE_OPENPGP_KEY = "openpgp_key"
private const val PREFERENCE_AUTOCRYPT_TRANSFER = "autocrypt_transfer"
internal const val PREFERENCE_FOLDERS = "folders"
private const val PREFERENCE_AUTO_EXPAND_FOLDER = "account_setup_auto_expand_folder"
private const val PREFERENCE_AUTO_SELECT_FOLDER = "auto_select_folder"
private const val PREFERENCE_SUBSCRIBED_FOLDERS_ONLY = "subscribed_folders_only"
private const val PREFERENCE_ARCHIVE_FOLDER = "archive_folder"
private const val PREFERENCE_DRAFTS_FOLDER = "drafts_folder"
Expand Down
2 changes: 1 addition & 1 deletion legacy/ui/legacy/src/main/res/xml/account_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@
>

<com.fsck.k9.ui.settings.account.FolderListPreference
android:key="account_setup_auto_expand_folder"
android:key="auto_select_folder"
app:useSimpleSummaryProvider="true"
android:title="@string/account_setup_auto_select_folder"
/>
Expand Down
Loading