9cbc478574
Splitting allows easily making a fake that doesn't have to override the implementation details of LauncherPrefs. The fake should not deal with SharedPreferences. LauncherPrefs could be an interface, but then the companion object has more limitations. The solution there is to have a dedicated object class, e.g. `LauncherPrefItems`. I went with an abs class to make the refactor simpler. Flag: EXEMPT refactor Bug: 369641781 Test: go/testedequals Change-Id: I97a2d495d3b5fa892fa53a11fb3f7a7dfb98515b
231 lines
8.5 KiB
Kotlin
231 lines
8.5 KiB
Kotlin
/*
|
|
* Copyright (C) 2023 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
package com.android.launcher3
|
|
|
|
import android.content.Context
|
|
import android.content.SharedPreferences
|
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
|
import androidx.test.filters.SmallTest
|
|
import androidx.test.platform.app.InstrumentationRegistry
|
|
import com.android.launcher3.LauncherPrefs.Companion.BOOT_AWARE_PREFS_KEY
|
|
import com.google.common.truth.Truth.assertThat
|
|
import java.util.concurrent.CountDownLatch
|
|
import java.util.concurrent.TimeUnit
|
|
import org.junit.Test
|
|
import org.junit.runner.RunWith
|
|
|
|
private val TEST_BOOLEAN_ITEM = LauncherPrefs.nonRestorableItem("1", false)
|
|
private val TEST_STRING_ITEM = LauncherPrefs.nonRestorableItem("2", "( ͡❛ ͜ʖ ͡❛)")
|
|
private val TEST_INT_ITEM = LauncherPrefs.nonRestorableItem("3", -1)
|
|
private val TEST_CONTEXTUAL_ITEM =
|
|
ContextualItem("4", true, { true }, EncryptionType.ENCRYPTED, Boolean::class.java)
|
|
|
|
private const val TEST_DEFAULT_VALUE = "default"
|
|
private const val TEST_PREF_KEY = "test_pref_key"
|
|
|
|
private const val WAIT_TIME_IN_SECONDS = 3L
|
|
|
|
@SmallTest
|
|
@RunWith(AndroidJUnit4::class)
|
|
class LauncherPrefsTest {
|
|
|
|
private val context by lazy { InstrumentationRegistry.getInstrumentation().targetContext }
|
|
private val launcherPrefs by lazy { LauncherPrefs.get(context) }
|
|
|
|
@Test
|
|
fun has_keyMissingFromLauncherPrefs_returnsFalse() {
|
|
assertThat(launcherPrefs.has(TEST_BOOLEAN_ITEM)).isFalse()
|
|
}
|
|
|
|
@Test
|
|
fun has_keyPresentInLauncherPrefs_returnsTrue() {
|
|
with(launcherPrefs) {
|
|
putSync(TEST_BOOLEAN_ITEM.to(TEST_BOOLEAN_ITEM.defaultValue))
|
|
assertThat(has(TEST_BOOLEAN_ITEM)).isTrue()
|
|
remove(TEST_BOOLEAN_ITEM)
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun addListener_listeningForStringItemUpdates_isCorrectlyNotifiedOfUpdates() {
|
|
val latch = CountDownLatch(1)
|
|
val listener = LauncherPrefChangeListener { latch.countDown() }
|
|
|
|
with(launcherPrefs) {
|
|
putSync(TEST_STRING_ITEM.to(TEST_STRING_ITEM.defaultValue))
|
|
addListener(listener, TEST_STRING_ITEM)
|
|
putSync(TEST_STRING_ITEM.to(TEST_STRING_ITEM.defaultValue + "abc"))
|
|
|
|
assertThat(latch.await(WAIT_TIME_IN_SECONDS, TimeUnit.SECONDS)).isTrue()
|
|
remove(TEST_STRING_ITEM)
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun removeListener_previouslyListeningForStringItemUpdates_isNoLongerNotifiedOfUpdates() {
|
|
val latch = CountDownLatch(1)
|
|
val listener = LauncherPrefChangeListener { latch.countDown() }
|
|
|
|
with(launcherPrefs) {
|
|
addListener(listener, TEST_STRING_ITEM)
|
|
removeListener(listener, TEST_STRING_ITEM)
|
|
putSync(TEST_STRING_ITEM.to(TEST_STRING_ITEM.defaultValue + "hello."))
|
|
|
|
// latch will be still be 1 (and await will return false) if the listener was not called
|
|
assertThat(latch.await(WAIT_TIME_IN_SECONDS, TimeUnit.SECONDS)).isFalse()
|
|
remove(TEST_STRING_ITEM)
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun addListenerAndRemoveListener_forMultipleItems_bothWorkProperly() {
|
|
var latch = CountDownLatch(3)
|
|
val listener = LauncherPrefChangeListener { latch.countDown() }
|
|
|
|
with(launcherPrefs) {
|
|
addListener(listener, TEST_INT_ITEM, TEST_STRING_ITEM, TEST_BOOLEAN_ITEM)
|
|
putSync(
|
|
TEST_INT_ITEM.to(TEST_INT_ITEM.defaultValue + 123),
|
|
TEST_STRING_ITEM.to(TEST_STRING_ITEM.defaultValue + "abc"),
|
|
TEST_BOOLEAN_ITEM.to(!TEST_BOOLEAN_ITEM.defaultValue),
|
|
)
|
|
assertThat(latch.await(WAIT_TIME_IN_SECONDS, TimeUnit.SECONDS)).isTrue()
|
|
|
|
removeListener(listener, TEST_INT_ITEM, TEST_STRING_ITEM, TEST_BOOLEAN_ITEM)
|
|
latch = CountDownLatch(1)
|
|
putSync(
|
|
TEST_INT_ITEM.to(TEST_INT_ITEM.defaultValue),
|
|
TEST_STRING_ITEM.to(TEST_STRING_ITEM.defaultValue),
|
|
TEST_BOOLEAN_ITEM.to(TEST_BOOLEAN_ITEM.defaultValue),
|
|
)
|
|
remove(TEST_INT_ITEM, TEST_STRING_ITEM, TEST_BOOLEAN_ITEM)
|
|
|
|
assertThat(latch.await(WAIT_TIME_IN_SECONDS, TimeUnit.SECONDS)).isFalse()
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun get_booleanItemNotInLauncherprefs_returnsDefaultValue() {
|
|
assertThat(launcherPrefs.get(TEST_BOOLEAN_ITEM)).isEqualTo(TEST_BOOLEAN_ITEM.defaultValue)
|
|
}
|
|
|
|
@Test
|
|
fun get_stringItemNotInLauncherPrefs_returnsDefaultValue() {
|
|
assertThat(launcherPrefs.get(TEST_STRING_ITEM)).isEqualTo(TEST_STRING_ITEM.defaultValue)
|
|
}
|
|
|
|
@Test
|
|
fun get_intItemNotInLauncherprefs_returnsDefaultValue() {
|
|
assertThat(launcherPrefs.get(TEST_INT_ITEM)).isEqualTo(TEST_INT_ITEM.defaultValue)
|
|
}
|
|
|
|
@Test
|
|
fun put_storesItemInLauncherPrefs_successfully() {
|
|
val notDefaultValue = !TEST_BOOLEAN_ITEM.defaultValue
|
|
|
|
with(launcherPrefs) {
|
|
putSync(TEST_BOOLEAN_ITEM.to(notDefaultValue))
|
|
assertThat(get(TEST_BOOLEAN_ITEM)).isEqualTo(notDefaultValue)
|
|
remove(TEST_BOOLEAN_ITEM)
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun put_storesListOfItemsInLauncherPrefs_successfully() {
|
|
with(launcherPrefs) {
|
|
putSync(
|
|
TEST_STRING_ITEM.to(TEST_STRING_ITEM.defaultValue),
|
|
TEST_INT_ITEM.to(TEST_INT_ITEM.defaultValue),
|
|
TEST_BOOLEAN_ITEM.to(TEST_BOOLEAN_ITEM.defaultValue),
|
|
)
|
|
assertThat(has(TEST_BOOLEAN_ITEM, TEST_INT_ITEM, TEST_STRING_ITEM)).isTrue()
|
|
remove(TEST_STRING_ITEM, TEST_INT_ITEM, TEST_BOOLEAN_ITEM)
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun remove_deletesItemFromLauncherPrefs_successfully() {
|
|
val notDefaultValue = !TEST_BOOLEAN_ITEM.defaultValue
|
|
|
|
with(launcherPrefs) {
|
|
putSync(TEST_BOOLEAN_ITEM.to(notDefaultValue))
|
|
remove(TEST_BOOLEAN_ITEM)
|
|
assertThat(get(TEST_BOOLEAN_ITEM)).isEqualTo(TEST_BOOLEAN_ITEM.defaultValue)
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun get_contextualItem_returnsCorrectDefault() {
|
|
assertThat(launcherPrefs.get(TEST_CONTEXTUAL_ITEM)).isTrue()
|
|
}
|
|
|
|
@Test
|
|
fun getItemSharedPrefFile_forNonRestorableItem_isCorrect() {
|
|
val nonRestorableItem = LauncherPrefs.nonRestorableItem(TEST_PREF_KEY, TEST_DEFAULT_VALUE)
|
|
assertThat(nonRestorableItem.sharedPrefFile).isEqualTo(LauncherFiles.DEVICE_PREFERENCES_KEY)
|
|
}
|
|
|
|
@Test
|
|
fun getItemSharedPrefFile_forBackedUpItem_isCorrect() {
|
|
val backedUpItem = LauncherPrefs.backedUpItem(TEST_PREF_KEY, TEST_DEFAULT_VALUE)
|
|
assertThat(backedUpItem.sharedPrefFile).isEqualTo(LauncherFiles.SHARED_PREFERENCES_KEY)
|
|
}
|
|
|
|
@Test
|
|
fun put_bootAwareItem_updatesDeviceProtectedStorage() {
|
|
val bootAwareItem =
|
|
LauncherPrefs.backedUpItem(
|
|
TEST_PREF_KEY,
|
|
TEST_DEFAULT_VALUE,
|
|
EncryptionType.DEVICE_PROTECTED,
|
|
)
|
|
|
|
val bootAwarePrefs: SharedPreferences =
|
|
context
|
|
.createDeviceProtectedStorageContext()
|
|
.getSharedPreferences(BOOT_AWARE_PREFS_KEY, Context.MODE_PRIVATE)
|
|
bootAwarePrefs.edit().remove(bootAwareItem.sharedPrefKey).commit()
|
|
|
|
launcherPrefs.putSync(bootAwareItem.to(bootAwareItem.defaultValue))
|
|
assertThat(bootAwarePrefs.contains(bootAwareItem.sharedPrefKey)).isTrue()
|
|
|
|
launcherPrefs.removeSync(bootAwareItem)
|
|
}
|
|
|
|
@Test
|
|
fun remove_bootAwareItem_removesFromDeviceProtectedStorage() {
|
|
val bootAwareItem =
|
|
LauncherPrefs.backedUpItem(
|
|
TEST_PREF_KEY,
|
|
TEST_DEFAULT_VALUE,
|
|
EncryptionType.DEVICE_PROTECTED,
|
|
)
|
|
|
|
val bootAwarePrefs: SharedPreferences =
|
|
context
|
|
.createDeviceProtectedStorageContext()
|
|
.getSharedPreferences(BOOT_AWARE_PREFS_KEY, Context.MODE_PRIVATE)
|
|
|
|
bootAwarePrefs
|
|
.edit()
|
|
.putString(bootAwareItem.sharedPrefKey, bootAwareItem.defaultValue)
|
|
.commit()
|
|
|
|
launcherPrefs.removeSync(bootAwareItem)
|
|
assertThat(bootAwarePrefs.contains(bootAwareItem.sharedPrefKey)).isFalse()
|
|
}
|
|
}
|