remove ClassicPrefsFormat

This commit is contained in:
Milos Kozak 2021-10-19 23:20:50 +02:00
parent fb49c93104
commit 29da63d264
13 changed files with 67 additions and 264 deletions

View file

@ -3,7 +3,6 @@ package info.nightscout.androidaps.dependencyInjection
import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider
import info.nightscout.androidaps.plugins.general.maintenance.formats.ClassicPrefsFormat
import info.nightscout.androidaps.plugins.general.maintenance.formats.EncryptedPrefsFormat
import info.nightscout.androidaps.utils.CryptoUtil
@ -13,6 +12,5 @@ abstract class PreferencesModule {
@ContributesAndroidInjector abstract fun cryptoUtilInjector(): CryptoUtil
@ContributesAndroidInjector abstract fun encryptedPrefsFormatInjector(): EncryptedPrefsFormat
@ContributesAndroidInjector abstract fun classicPrefsFormatInjector(): ClassicPrefsFormat
@ContributesAndroidInjector abstract fun prefImportListProviderInjector(): PrefFileListProvider
}

View file

@ -14,11 +14,11 @@ import androidx.fragment.app.FragmentActivity
import androidx.work.*
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.BuildConfig
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.DaggerAppCompatActivityWithResult
import info.nightscout.androidaps.activities.PreferencesActivity
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.UserEntry
import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.events.EventAppExit
@ -42,6 +42,8 @@ import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.protection.PasswordCheck
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import info.nightscout.androidaps.utils.storage.Storage
import info.nightscout.androidaps.utils.userEntry.UserEntryPresentationHelper
import java.io.File
import java.io.FileNotFoundException
import java.io.IOException
@ -63,7 +65,6 @@ class ImportExportPrefsImpl @Inject constructor(
private val passwordCheck: PasswordCheck,
private val config: Config,
private val androidPermission: AndroidPermission,
private val classicPrefsFormat: ClassicPrefsFormat,
private val encryptedPrefsFormat: EncryptedPrefsFormat,
private val prefFileList: PrefFileListProvider,
private val uel: UserEntryLogger,
@ -103,12 +104,7 @@ class ImportExportPrefsImpl @Inject constructor(
metadata[PrefsMetadataKey.AAPS_VERSION] = PrefMetadata(BuildConfig.VERSION_NAME, PrefsStatus.OK)
metadata[PrefsMetadataKey.AAPS_FLAVOUR] = PrefMetadata(BuildConfig.FLAVOR, PrefsStatus.OK)
metadata[PrefsMetadataKey.DEVICE_MODEL] = PrefMetadata(config.currentDeviceModelString, PrefsStatus.OK)
if (prefsEncryptionIsDisabled()) {
metadata[PrefsMetadataKey.ENCRYPTION] = PrefMetadata("Disabled", PrefsStatus.DISABLED)
} else {
metadata[PrefsMetadataKey.ENCRYPTION] = PrefMetadata("Enabled", PrefsStatus.OK)
}
metadata[PrefsMetadataKey.ENCRYPTION] = PrefMetadata("Enabled", PrefsStatus.OK)
return metadata
}
@ -132,9 +128,6 @@ class ImportExportPrefsImpl @Inject constructor(
return if (patientName.isNotEmpty() && patientName != defaultPatientName) patientName else systemName
}
private fun prefsEncryptionIsDisabled() =
buildHelper.isEngineeringMode() && !sp.getBoolean(R.string.key_maintenance_encrypt_exported_prefs, true)
private fun askForMasterPass(activity: FragmentActivity, @StringRes canceledMsg: Int, then: ((password: String) -> Unit)) {
passwordCheck.queryPassword(activity, R.string.master_password, R.string.key_master_password, { password ->
then(password)
@ -155,11 +148,7 @@ class ImportExportPrefsImpl @Inject constructor(
@Suppress("SameParameterValue")
private fun askForMasterPassIfNeeded(activity: FragmentActivity, @StringRes canceledMsg: Int, then: ((password: String) -> Unit)) {
if (prefsEncryptionIsDisabled()) {
then("")
} else {
askForMasterPass(activity, canceledMsg, then)
}
}
private fun assureMasterPasswordSet(activity: FragmentActivity, @StringRes wrongPwdTitle: Int): Boolean {
@ -179,7 +168,7 @@ class ImportExportPrefsImpl @Inject constructor(
}
private fun askToConfirmExport(activity: FragmentActivity, fileToExport: File, then: ((password: String) -> Unit)) {
if (!prefsEncryptionIsDisabled() && !assureMasterPasswordSet(activity, R.string.nav_export)) return
if (!assureMasterPasswordSet(activity, R.string.nav_export)) return
TwoMessagesAlertDialog.showAlert(activity, resourceHelper.gs(R.string.nav_export),
resourceHelper.gs(R.string.export_to) + " " + fileToExport.name + " ?",
@ -189,20 +178,12 @@ class ImportExportPrefsImpl @Inject constructor(
}
private fun askToConfirmImport(activity: FragmentActivity, fileToImport: PrefsFile, then: ((password: String) -> Unit)) {
if (fileToImport.handler == PrefsFormatsHandler.ENCRYPTED) {
if (!assureMasterPasswordSet(activity, R.string.nav_import)) return
TwoMessagesAlertDialog.showAlert(activity, resourceHelper.gs(R.string.nav_import),
resourceHelper.gs(R.string.import_from) + " " + fileToImport.name + " ?",
resourceHelper.gs(R.string.password_preferences_decrypt_prompt), {
askForMasterPass(activity, R.string.preferences_import_canceled, then)
}, null, R.drawable.ic_header_import)
} else {
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.nav_import),
resourceHelper.gs(R.string.import_from) + " " + fileToImport.file + " ?",
Runnable { then("") })
}
if (!assureMasterPasswordSet(activity, R.string.nav_import)) return
TwoMessagesAlertDialog.showAlert(activity, resourceHelper.gs(R.string.nav_import),
resourceHelper.gs(R.string.import_from) + " " + fileToImport.name + " ?",
resourceHelper.gs(R.string.password_preferences_decrypt_prompt), {
askForMasterPass(activity, R.string.preferences_import_canceled, then)
}, null, R.drawable.ic_header_import)
}
private fun promptForDecryptionPasswordIfNeeded(activity: FragmentActivity, prefs: Prefs, importOk: Boolean,
@ -230,7 +211,6 @@ class ImportExportPrefsImpl @Inject constructor(
private fun exportSharedPreferences(activity: FragmentActivity) {
prefFileList.ensureExportDirExists()
val legacyFile = prefFileList.legacyFile()
val newFile = prefFileList.newExportFile()
askToConfirmExport(activity, newFile) { password ->
@ -242,9 +222,6 @@ class ImportExportPrefsImpl @Inject constructor(
val prefs = Prefs(entries, prepareMetadata(activity))
if (BuildConfig.DEBUG && buildHelper.isEngineeringMode()) {
classicPrefsFormat.savePreferences(legacyFile, prefs)
}
encryptedPrefsFormat.savePreferences(newFile, prefs, password)
ToastUtils.okToast(activity, resourceHelper.gs(R.string.exported))
@ -292,10 +269,7 @@ class ImportExportPrefsImpl @Inject constructor(
askToConfirmImport(activity, importFile) { password ->
val format: PrefsFormat = when (importFile.handler) {
PrefsFormatsHandler.CLASSIC -> classicPrefsFormat
PrefsFormatsHandler.ENCRYPTED -> encryptedPrefsFormat
}
val format: PrefsFormat = encryptedPrefsFormat
try {
@ -380,10 +354,11 @@ class ImportExportPrefsImpl @Inject constructor(
@Inject lateinit var injector: HasAndroidInjector
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var repository: AppRepository
@Inject lateinit var classicPrefsFormat: ClassicPrefsFormat
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var prefFileList: PrefFileListProvider
@Inject lateinit var mainApp: MainApp
@Inject lateinit var context: Context
@Inject lateinit var userEntryPresentationHelper: UserEntryPresentationHelper
@Inject lateinit var storage: Storage
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
@ -395,18 +370,30 @@ class ImportExportPrefsImpl @Inject constructor(
val newFile = prefFileList.newExportCsvFile()
var ret = Result.success()
try {
classicPrefsFormat.saveCsv(newFile, entries)
ToastUtils.okToast(mainApp, resourceHelper.gs(R.string.ue_exported))
saveCsv(newFile, entries)
ToastUtils.okToast(context, resourceHelper.gs(R.string.ue_exported))
} catch (e: FileNotFoundException) {
ToastUtils.errorToast(mainApp, resourceHelper.gs(R.string.filenotfound) + " " + newFile)
ToastUtils.errorToast(context, resourceHelper.gs(R.string.filenotfound) + " " + newFile)
aapsLogger.error(LTag.CORE, "Unhandled exception", e)
ret = Result.failure(workDataOf("Error" to "Error FileNotFoundException"))
} catch (e: IOException) {
ToastUtils.errorToast(mainApp, e.message)
ToastUtils.errorToast(context, e.message)
aapsLogger.error(LTag.CORE, "Unhandled exception", e)
ret = Result.failure(workDataOf("Error" to "Error IOException"))
}
return ret
}
private fun saveCsv(file: File, userEntries: List<UserEntry>) {
try {
val contents = userEntryPresentationHelper.userEntriesToCsv(userEntries)
storage.putFileContents(file, contents)
} catch (e: FileNotFoundException) {
throw PrefFileNotFoundError(file.absolutePath)
} catch (e: IOException) {
throw PrefIOError(file.absolutePath)
}
}
}
}

View file

@ -4,8 +4,6 @@ import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.core.content.FileProvider
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.BuildConfig
import info.nightscout.androidaps.R
@ -212,14 +210,4 @@ class MaintenancePlugin @Inject constructor(
emailIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
return emailIntent
}
override fun preprocessPreferences(preferenceFragment: PreferenceFragmentCompat) {
super.preprocessPreferences(preferenceFragment)
val encryptSwitch =
preferenceFragment.findPreference(resourceHelper.gs(R.string.key_maintenance_encrypt_exported_prefs)) as SwitchPreference?
?: return
encryptSwitch.isVisible = buildHelper.isEngineeringMode()
encryptSwitch.isEnabled = buildHelper.isEngineeringMode()
}
}

View file

@ -827,8 +827,6 @@
<string name="error_adding_treatment_title">Treatment data incomplete</string>
<string name="maintenance_settings">Maintenance Settings</string>
<string name="maintenance_email">Email recipient</string>
<string name="key_maintenance_encrypt_exported_prefs" translatable="false">maintenance_encrypt_exported_prefs</string>
<string name="maintenance_encrypt_exported_prefs">Encrypt exported settings</string>
<string name="key_maintenance_logs_email" translatable="false">maintenance_logs_email</string>
<string name="key_maintenance_logs_amount" translatable="false">maintenance_logs_amount</string>
<string name="key_logshipper_amount" translatable="false">logshipper_amount</string>

View file

@ -26,11 +26,6 @@
validate:minNumber="1"
validate:testType="numericRange"/>
<SwitchPreference
android:defaultValue="true"
android:key="@string/key_maintenance_encrypt_exported_prefs"
android:title="@string/maintenance_encrypt_exported_prefs" />
</PreferenceCategory>
</androidx.preference.PreferenceScreen>

View file

@ -24,7 +24,6 @@ import kotlin.math.abs
class PrefFileListProvider @Inject constructor(
private val resourceHelper: ResourceHelper,
private val config: Config,
private val classicPrefsFormat: ClassicPrefsFormat,
private val encryptedPrefsFormat: EncryptedPrefsFormat,
private val storage: Storage,
private val versionCheckerUtils: VersionCheckerUtils
@ -55,10 +54,8 @@ class PrefFileListProvider @Inject constructor(
path.walk().maxDepth(1).filter { it.isFile && (it.name.endsWith(".json") || it.name.contains("Preferences")) }.forEach {
val contents = storage.getFileContents(it)
val detectedNew = encryptedPrefsFormat.isPreferencesFile(it, contents)
val detectedOld = !detectedNew && classicPrefsFormat.isPreferencesFile(it, contents)
if (detectedNew || detectedOld) {
val formatHandler = if (detectedNew) PrefsFormatsHandler.ENCRYPTED else PrefsFormatsHandler.CLASSIC
prefFiles.add(PrefsFile(it.name, it, path, PrefsImportDir.ROOT_DIR, formatHandler, metadataFor(loadMetadata, formatHandler, contents)))
if (detectedNew) {
prefFiles.add(PrefsFile(it.name, it, path, PrefsImportDir.ROOT_DIR, metadataFor(loadMetadata, contents)))
}
}
@ -66,15 +63,14 @@ class PrefFileListProvider @Inject constructor(
aapsPath.walk().filter { it.isFile && it.name.endsWith(".json") }.forEach {
val contents = storage.getFileContents(it)
if (encryptedPrefsFormat.isPreferencesFile(it, contents)) {
prefFiles.add(PrefsFile(it.name, it, aapsPath, PrefsImportDir.AAPS_DIR, PrefsFormatsHandler.ENCRYPTED, metadataFor(loadMetadata, PrefsFormatsHandler.ENCRYPTED, contents)))
prefFiles.add(PrefsFile(it.name, it, aapsPath, PrefsImportDir.AAPS_DIR, metadataFor(loadMetadata, contents)))
}
}
// we sort only if we have metadata to be used for that
if (loadMetadata) {
prefFiles.sortWith(
compareByDescending<PrefsFile> { it.handler }
.thenBy { it.metadata[PrefsMetadataKey.AAPS_FLAVOUR]?.status }
compareByDescending<PrefsFile> { it.metadata[PrefsMetadataKey.AAPS_FLAVOUR]?.status }
.thenByDescending { it.metadata[PrefsMetadataKey.CREATED_AT]?.value }
)
}
@ -82,14 +78,11 @@ class PrefFileListProvider @Inject constructor(
return prefFiles
}
private fun metadataFor(loadMetadata: Boolean, formatHandler: PrefsFormatsHandler, contents: String): PrefMetadataMap {
private fun metadataFor(loadMetadata: Boolean, contents: String): PrefMetadataMap {
if (!loadMetadata) {
return mapOf()
}
return checkMetadata(when (formatHandler) {
PrefsFormatsHandler.CLASSIC -> classicPrefsFormat.loadMetadata(contents)
PrefsFormatsHandler.ENCRYPTED -> encryptedPrefsFormat.loadMetadata(contents)
})
return checkMetadata(encryptedPrefsFormat.loadMetadata(contents))
}
fun legacyFile(): File {

View file

@ -3,8 +3,8 @@ package info.nightscout.androidaps.plugins.general.maintenance
import android.os.Parcelable
import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefMetadata
import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefsMetadataKey
import kotlinx.parcelize.RawValue
import kotlinx.parcelize.Parcelize
import kotlinx.parcelize.RawValue
import java.io.File
@Parcelize
@ -13,7 +13,6 @@ data class PrefsFile(
val file: File,
val baseDir: File,
val dirKind: PrefsImportDir,
val handler: PrefsFormatsHandler,
// metadata here is used only for list display
val metadata: @RawValue Map<PrefsMetadataKey, PrefMetadata>

View file

@ -1,6 +0,0 @@
package info.nightscout.androidaps.plugins.general.maintenance
enum class PrefsFormatsHandler {
CLASSIC,
ENCRYPTED
}

View file

@ -5,6 +5,7 @@ import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.FragmentActivity
import androidx.recyclerview.widget.LinearLayoutManager
@ -16,10 +17,8 @@ import info.nightscout.androidaps.core.databinding.MaintenanceImportListItemBind
import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider
import info.nightscout.androidaps.plugins.general.maintenance.PrefsFile
import info.nightscout.androidaps.plugins.general.maintenance.PrefsFileContract
import info.nightscout.androidaps.plugins.general.maintenance.PrefsFormatsHandler
import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefsMetadataKey
import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefsStatus
import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.utils.locale.LocaleHelper
import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject
@ -83,38 +82,30 @@ class PrefImportListActivity : DaggerAppCompatActivity() {
filelistDir.text = resourceHelper.gs(R.string.in_directory, prefFile.file.parentFile?.absolutePath)
val visible = (prefFile.handler != PrefsFormatsHandler.CLASSIC).toVisibility()
metalineName.visibility = visible
metaDateTimeIcon.visibility = visible
metaAppVersion.visibility = visible
if (prefFile.handler == PrefsFormatsHandler.CLASSIC) {
metaVariantFormat.text = resourceHelper.gs(R.string.metadata_format_old)
metaVariantFormat.setTextColor(resourceHelper.gc(R.color.metadataTextWarning))
metaDateTime.text = " "
} else {
prefFile.metadata[PrefsMetadataKey.AAPS_FLAVOUR]?.let {
metaVariantFormat.text = it.value
val color = if (it.status == PrefsStatus.OK) R.color.metadataOk else R.color.metadataTextWarning
metaVariantFormat.setTextColor(resourceHelper.gc(color))
}
prefFile.metadata[PrefsMetadataKey.CREATED_AT]?.let {
metaDateTime.text = prefFileListProvider.formatExportedAgo(it.value)
}
prefFile.metadata[PrefsMetadataKey.AAPS_VERSION]?.let {
metaAppVersion.text = it.value
val color = if (it.status == PrefsStatus.OK) R.color.metadataOk else R.color.metadataTextWarning
metaAppVersion.setTextColor(resourceHelper.gc(color))
}
prefFile.metadata[PrefsMetadataKey.DEVICE_NAME]?.let {
metaDeviceName.text = it.value
}
metalineName.visibility = View.VISIBLE
metaDateTimeIcon.visibility = View.VISIBLE
metaAppVersion.visibility = View.VISIBLE
prefFile.metadata[PrefsMetadataKey.AAPS_FLAVOUR]?.let {
metaVariantFormat.text = it.value
val color = if (it.status == PrefsStatus.OK) R.color.metadataOk else R.color.metadataTextWarning
metaVariantFormat.setTextColor(resourceHelper.gc(color))
}
prefFile.metadata[PrefsMetadataKey.CREATED_AT]?.let {
metaDateTime.text = prefFileListProvider.formatExportedAgo(it.value)
}
prefFile.metadata[PrefsMetadataKey.AAPS_VERSION]?.let {
metaAppVersion.text = it.value
val color = if (it.status == PrefsStatus.OK) R.color.metadataOk else R.color.metadataTextWarning
metaAppVersion.setTextColor(resourceHelper.gc(color))
}
prefFile.metadata[PrefsMetadataKey.DEVICE_NAME]?.let {
metaDeviceName.text = it.value
}
}
}
}

View file

@ -1,83 +0,0 @@
package info.nightscout.androidaps.plugins.general.maintenance.formats
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.database.entities.UserEntry
import info.nightscout.androidaps.utils.userEntry.UserEntryPresentationHelper
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.storage.Storage
import java.io.File
import java.io.FileNotFoundException
import java.io.IOException
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class ClassicPrefsFormat @Inject constructor(
private var resourceHelper: ResourceHelper,
private var userEntryPresentationHelper: UserEntryPresentationHelper,
private var storage: Storage
) : PrefsFormat {
companion object {
val FORMAT_KEY = "aaps_old"
}
override fun isPreferencesFile(file: File, preloadedContents: String?): Boolean {
val contents = preloadedContents ?: storage.getFileContents(file)
return contents.contains("units::" + Constants.MGDL) || contents.contains("units::" + Constants.MMOL) || contents.contains("language::") || contents.contains("I_understand::")
}
override fun savePreferences(file: File, prefs: Prefs, masterPassword: String?) {
try {
val contents = prefs.values.entries.joinToString("\n") { entry ->
"${entry.key}::${entry.value}"
}
storage.putFileContents(file, contents)
} catch (e: FileNotFoundException) {
throw PrefFileNotFoundError(file.absolutePath)
} catch (e: IOException) {
throw PrefIOError(file.absolutePath)
}
}
override fun loadPreferences(file: File, masterPassword: String?): Prefs {
var lineParts: Array<String>
val entries: MutableMap<String, String> = mutableMapOf()
try {
val rawLines = storage.getFileContents(file).split("\n")
rawLines.forEach { line ->
lineParts = line.split("::").toTypedArray()
if (lineParts.size == 2) {
entries[lineParts[0]] = lineParts[1]
}
}
return Prefs(entries, loadMetadata())
} catch (e: FileNotFoundException) {
throw PrefFileNotFoundError(file.absolutePath)
} catch (e: IOException) {
throw PrefIOError(file.absolutePath)
}
}
override fun loadMetadata(contents: String?): PrefMetadataMap {
val metadata: MutableMap<PrefsMetadataKey, PrefMetadata> = mutableMapOf()
metadata[PrefsMetadataKey.FILE_FORMAT] = PrefMetadata(FORMAT_KEY, PrefsStatus.WARN, resourceHelper.gs(R.string.metadata_warning_outdated_format))
return metadata
}
fun saveCsv(file: File, userEntries: List<UserEntry>) {
try {
val contents = userEntryPresentationHelper.userEntriesToCsv(userEntries)
storage.putFileContents(file, contents)
} catch (e: FileNotFoundException) {
throw PrefFileNotFoundError(file.absolutePath)
} catch (e: IOException) {
throw PrefIOError(file.absolutePath)
}
}
}

View file

@ -19,28 +19,25 @@ enum class PrefsMetadataKey(val key: String, @DrawableRes val icon: Int, @String
ENCRYPTION("encryption", R.drawable.ic_meta_encryption, R.string.metadata_label_encryption);
companion object {
private val keyToEnumMap = HashMap<String, PrefsMetadataKey>()
init {
for (value in values()) {
keyToEnumMap.put(value.key, value)
}
for (value in values()) keyToEnumMap[value.key] = value
}
fun fromKey(key: String): PrefsMetadataKey? {
fun fromKey(key: String): PrefsMetadataKey? =
if (keyToEnumMap.containsKey(key)) {
return keyToEnumMap.get(key)
keyToEnumMap[key]
} else {
return null
null
}
}
}
fun formatForDisplay(context: Context, value: String): String {
return when (this) {
FILE_FORMAT -> when (value) {
ClassicPrefsFormat.FORMAT_KEY -> context.getString(R.string.metadata_format_old)
EncryptedPrefsFormat.FORMAT_KEY_ENC -> context.getString(R.string.metadata_format_new)
EncryptedPrefsFormat.FORMAT_KEY_NOENC -> context.getString(R.string.metadata_format_debug)
else -> context.getString(R.string.metadata_format_other)
@ -60,6 +57,7 @@ typealias PrefMetadataMap = Map<PrefsMetadataKey, PrefMetadata>
data class Prefs(val values: Map<String, String>, var metadata: PrefMetadataMap)
interface PrefsFormat {
fun savePreferences(file: File, prefs: Prefs, masterPassword: String? = null)
fun loadPreferences(file: File, masterPassword: String? = null): Prefs
fun loadMetadata(contents: String? = null): PrefMetadataMap

View file

@ -345,7 +345,6 @@
<string name="metadata_label_device_name">Exporting device patient name</string>
<string name="metadata_label_device_model">Exporting device model</string>
<string name="metadata_label_encryption">File encryption</string>
<string name="metadata_format_old">Old export format</string>
<string name="metadata_format_new">New encrypted format</string>
<string name="metadata_format_debug">New debug format (unencrypted)</string>
<string name="metadata_format_other">Unknown export format</string>

View file

@ -1,54 +0,0 @@
package info.nightscout.androidaps.plugins.general.maintenance.formats
import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.userEntry.UserEntryPresentationHelper
import org.junit.Assert
import org.junit.Test
import org.mockito.Mock
import org.mockito.Mockito.`when`
import java.io.File
class ClassicPrefsFormatTest : TestBase() {
@Mock lateinit var resourceHelper: ResourceHelper
@Mock lateinit var userEntryPresentationHelper: UserEntryPresentationHelper
@Mock lateinit var file: MockedFile
@Test
fun preferenceLoadingTest() {
val test = "key1::val1\nkeyB::valB"
val classicFormat = ClassicPrefsFormat(resourceHelper, userEntryPresentationHelper, SingleStringStorage(test))
val prefs = classicFormat.loadPreferences(getMockedFile(), "")
Assert.assertEquals(prefs.values.size, 2)
Assert.assertEquals(prefs.values["key1"], "val1")
Assert.assertEquals(prefs.values["keyB"], "valB")
Assert.assertNull(prefs.values["key3"])
}
@Test
fun preferenceSavingTest() {
val storage = SingleStringStorage("")
val classicFormat = ClassicPrefsFormat(resourceHelper, userEntryPresentationHelper, storage)
val prefs = Prefs(
mapOf(
"key1" to "A",
"keyB" to "2"
),
mapOf()
)
classicFormat.savePreferences(getMockedFile(), prefs)
}
class MockedFile(s: String) : File(s)
private fun getMockedFile(): File {
`when`(file.exists()).thenReturn(true)
`when`(file.canRead()).thenReturn(true)
`when`(file.canWrite()).thenReturn(true)
return file
}
}