1
0
Fork 0

For #8565: Fix updating dropdown preferences in ETP settings! (#8573)

* For #8565: Create custom SharedPreferenceUpdater for String Preferences

* For #8565: Use custom updater to correctly update DropDownPreference

* For #8565: Set default values for dropDown preferences

* For 8565: add tests for findEntriesValue

* For 8565: clarified findEntryValue

Co-authored-by: Severin Rudie <Baron-Severin@users.noreply.github.com>
master
Mihai Adrian 2020-02-25 04:07:02 +02:00 committed by GitHub
parent 342ad1bfca
commit 4be693255d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 117 additions and 12 deletions

View File

@ -8,6 +8,7 @@ import android.content.Context
import android.util.AttributeSet
import android.widget.ArrayAdapter
import androidx.preference.DropDownPreference
import androidx.preference.ListPreference
import org.mozilla.fenix.R
class DropDownListPreference @JvmOverloads constructor(
@ -23,3 +24,19 @@ class DropDownListPreference @JvmOverloads constructor(
return ArrayAdapter(context, R.layout.etp_dropdown_item)
}
}
/**
* Return the (human-readable) entry that is matched to the (backing key) entryValue.
*
* E.g.
* entryValues == listOf("private", "normal")
* entries == listOf("Use private mode", "Use normal mode")
*
* findEntry("private) == "Use Private Mode"
*/
fun ListPreference.findEntry(key: Any?): CharSequence? {
if (key !is String) return null
val index = entryValues.indexOf(key)
return this.entries.getOrNull(index)
}

View File

@ -0,0 +1,24 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.settings
import androidx.core.content.edit
import androidx.preference.Preference
import org.mozilla.fenix.ext.settings
/**
* Updates the corresponding [android.content.SharedPreferences] when the String [Preference] is changed.
* The preference key is used as the shared preference key.
*/
open class StringSharedPreferenceUpdater : Preference.OnPreferenceChangeListener {
override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
val newStringValue = newValue as? String ?: return false
preference.context.settings().preferences.edit {
putString(preference.key, newStringValue)
}
return true
}
}

View File

@ -227,17 +227,20 @@ class TrackingProtectionFragment : PreferenceFragmentCompat() {
}
}
customCookiesSelect.onPreferenceChangeListener = object : SharedPreferenceUpdater() {
customCookiesSelect.onPreferenceChangeListener = object : StringSharedPreferenceUpdater() {
override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
updateTrackingProtectionPolicy()
return super.onPreferenceChange(preference, newValue)
val newValueEntry = (preference as DropDownListPreference).findEntry(key = newValue)
return super.onPreferenceChange(preference, newValueEntry)
}
}
customTrackingSelect.onPreferenceChangeListener = object : SharedPreferenceUpdater() {
customTrackingSelect.onPreferenceChangeListener = object : StringSharedPreferenceUpdater() {
override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
updateTrackingProtectionPolicy()
return super.onPreferenceChange(preference, newValue)
val newValueEntry = (preference as DropDownListPreference).findEntry(key = newValue)
return super.onPreferenceChange(preference, newValueEntry)
}
}

View File

@ -1,5 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="social">social</string>
<string name="unvisited">unvisited</string>
<string name="third_party">third-party</string>
<string name="all">all</string>
<string name="private_string">private</string>
<string-array name="cookies_options_entries">
<item>@string/preference_enhanced_tracking_protection_custom_cookies_1</item>
<item>@string/preference_enhanced_tracking_protection_custom_cookies_2</item>
@ -8,10 +15,10 @@
</string-array>
<string-array name="cookies_options_entry_values">
<item>social</item>
<item>unvisited</item>
<item>third-party</item>
<item>all</item>
<item>@string/social</item>
<item>@string/unvisited</item>
<item>@string/third_party</item>
<item>@string/all</item>
</string-array>
<string-array name="tracking_content_options_entries">
@ -20,7 +27,7 @@
</string-array>
<string-array name="tracking_content_options_entry_values">
<item>all</item>
<item>private</item>
<item>@string/all</item>
<item>@string/private_string</item>
</string-array>
</resources>

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
<?xml version="1.0" encoding="utf-8"?><!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
@ -41,6 +40,7 @@
android:layout="@layout/checkbox_left_preference_etp"
android:title="@string/preference_enhanced_tracking_protection_custom_cookies" />
<org.mozilla.fenix.settings.DropDownListPreference
android:defaultValue="@string/all"
android:dependency="@string/pref_key_tracking_protection_custom_cookies"
android:entries="@array/cookies_options_entries"
android:entryValues="@array/cookies_options_entry_values"
@ -53,6 +53,7 @@
android:layout="@layout/checkbox_left_preference_etp"
android:title="@string/preference_enhanced_tracking_protection_custom_tracking_content" />
<org.mozilla.fenix.settings.DropDownListPreference
android:defaultValue="@string/all"
android:dependency="@string/pref_key_tracking_protection_custom_tracking_content"
android:entries="@array/tracking_content_options_entries"
android:entryValues="@array/tracking_content_options_entry_values"

View File

@ -0,0 +1,53 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.settings
import io.mockk.every
import io.mockk.mockk
import org.junit.Assert.assertEquals
import androidx.preference.ListPreference
import org.junit.Assert.assertNull
import org.junit.Before
import org.junit.Test
class DropDownListPreferenceTest {
private lateinit var preference: ListPreference
@Before
fun before() {
preference = mockk()
}
@Test
fun `WHEN findEntriesValue is called with a non-string THEN it returns null`() {
assertNull(preference.findEntry(null))
assertNull(preference.findEntry(1))
assertNull(preference.findEntry(Object()))
assertNull(preference.findEntry(listOf<Char>()))
}
@Test
fun `GIVEN newValue is not found in entryValues WHEN findEntriesValue is called with newValue THEN it should return null`() {
val newValue = "key"
every { preference.entries } returns arrayOf()
every { preference.entryValues } returns arrayOf()
assertNull(preference.findEntry(newValue))
}
@Test
fun `GIVEN entryValues and entries contain values WHEN findEntriesValue is called THEN it should return the entry`() {
val entries = arrayOf("use private mode!", "use normal mode!", "use something else!")
val entryValues = arrayOf("private", "normal", "other")
every { preference.entries } returns entries
every { preference.entryValues } returns entryValues
assertEquals(entries[0], preference.findEntry(entryValues[0]))
assertEquals(entries[1], preference.findEntry(entryValues[1]))
assertEquals(entries[2], preference.findEntry(entryValues[2]))
}
}