summaryrefslogtreecommitdiff
path: root/java/tests
diff options
context:
space:
mode:
author Mark Renouf <mrenouf@google.com> 2023-09-11 10:53:02 -0400
committer Mark Renouf <mrenouf@google.com> 2023-10-10 15:51:55 -0400
commit35018884b00755252f5268507065a7ea6cb9404b (patch)
tree642993f8396e95e561a58b6b9022a2614ea24122 /java/tests
parent73bad17b4fa5a7c07409ed6d46121614b48adb33 (diff)
Inject ComponentNames for image editor and nearby share
Adds a SecureSettings fake Adds test coverage for new modules Removes another overload from ChooserActivityWrapper Uses @BindValue in tests to alter the configured editor component Test: atest --test-mapping packages/modules/IntentResolver Bug: 300157408 Bug: 302113519 Change-Id: Ie7d5fe12ad0d8e7fd074154641de35fe89d50ce6
Diffstat (limited to 'java/tests')
-rw-r--r--java/tests/Android.bp3
-rw-r--r--java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java2
-rw-r--r--java/tests/src/com/android/intentresolver/v2/ChooserActionFactoryTest.kt232
-rw-r--r--java/tests/src/com/android/intentresolver/v2/ChooserWrapperActivity.java12
-rw-r--r--java/tests/src/com/android/intentresolver/v2/UnbundledChooserActivityTest.java44
-rw-r--r--java/tests/src/com/android/intentresolver/v2/platform/FakeSecureSettings.kt44
-rw-r--r--java/tests/src/com/android/intentresolver/v2/platform/FakeSecureSettingsTest.kt61
-rw-r--r--java/tests/src/com/android/intentresolver/v2/platform/NearbyShareModuleTest.kt83
8 files changed, 453 insertions, 28 deletions
diff --git a/java/tests/Android.bp b/java/tests/Android.bp
index 5244bf7b..a17400f8 100644
--- a/java/tests/Android.bp
+++ b/java/tests/Android.bp
@@ -50,7 +50,8 @@ android_test {
"kotlinx_coroutines_test",
"mockito-target-minus-junit4",
"testables",
- "truth-prebuilt",
+ "truth",
+ "truth-java8-extension",
"flag-junit",
"platform-test-annotations",
],
diff --git a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java
index 73977f86..53a505df 100644
--- a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java
+++ b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java
@@ -2751,7 +2751,7 @@ public class UnbundledChooserActivityTest {
final ChooserActivity activity = mActivityRule.launchActivity(
Intent.createChooser(new Intent("ACTION_FOO"), "foo"));
waitForIdle();
- assertThat(activity).isInstanceOf(com.android.intentresolver.ChooserWrapperActivity.class);
+ assertThat(activity).isInstanceOf(ChooserWrapperActivity.class);
}
private ResolveInfo createFakeResolveInfo() {
diff --git a/java/tests/src/com/android/intentresolver/v2/ChooserActionFactoryTest.kt b/java/tests/src/com/android/intentresolver/v2/ChooserActionFactoryTest.kt
new file mode 100644
index 00000000..a1a9bc92
--- /dev/null
+++ b/java/tests/src/com/android/intentresolver/v2/ChooserActionFactoryTest.kt
@@ -0,0 +1,232 @@
+/*
+ * 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.intentresolver.v2
+
+import android.app.Activity
+import android.app.PendingIntent
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Context.RECEIVER_EXPORTED
+import android.content.Intent
+import android.content.IntentFilter
+import android.content.res.Resources
+import android.graphics.drawable.Icon
+import android.service.chooser.ChooserAction
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.intentresolver.ChooserRequestParameters
+import com.android.intentresolver.logging.EventLog
+import com.android.intentresolver.mock
+import com.android.intentresolver.whenever
+import com.google.common.collect.ImmutableList
+import com.google.common.truth.Truth.assertThat
+import java.util.Optional
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import java.util.function.Consumer
+import org.junit.After
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mockito
+
+@RunWith(AndroidJUnit4::class)
+class ChooserActionFactoryTest {
+ private val context = InstrumentationRegistry.getInstrumentation().context
+
+ private val logger = mock<EventLog>()
+ private val actionLabel = "Action label"
+ private val modifyShareLabel = "Modify share"
+ private val testAction = "com.android.intentresolver.testaction"
+ private val countdown = CountDownLatch(1)
+ private val testReceiver: BroadcastReceiver =
+ object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ // Just doing at most a single countdown per test.
+ countdown.countDown()
+ }
+ }
+ private val resultConsumer =
+ object : Consumer<Int> {
+ var latestReturn = Integer.MIN_VALUE
+
+ override fun accept(resultCode: Int) {
+ latestReturn = resultCode
+ }
+ }
+
+ @Before
+ fun setup() {
+ context.registerReceiver(testReceiver, IntentFilter(testAction), RECEIVER_EXPORTED)
+ }
+
+ @After
+ fun teardown() {
+ context.unregisterReceiver(testReceiver)
+ }
+
+ @Test
+ fun testCreateCustomActions() {
+ val factory = createFactory()
+
+ val customActions = factory.createCustomActions()
+
+ assertThat(customActions.size).isEqualTo(1)
+ assertThat(customActions[0].label).isEqualTo(actionLabel)
+
+ // click it
+ customActions[0].onClicked.run()
+
+ Mockito.verify(logger).logCustomActionSelected(eq(0))
+ assertEquals(Activity.RESULT_OK, resultConsumer.latestReturn)
+ // Verify the pending intent has been called
+ assertTrue("Timed out waiting for broadcast", countdown.await(2500, TimeUnit.MILLISECONDS))
+ }
+
+ @Test
+ fun testNoModifyShareAction() {
+ val factory = createFactory(includeModifyShare = false)
+
+ assertThat(factory.modifyShareAction).isNull()
+ }
+
+ @Test
+ fun testModifyShareAction() {
+ val factory = createFactory(includeModifyShare = true)
+
+ val action = factory.modifyShareAction ?: error("Modify share action should not be null")
+ action.onClicked.run()
+
+ Mockito.verify(logger).logActionSelected(eq(EventLog.SELECTION_TYPE_MODIFY_SHARE))
+ assertEquals(Activity.RESULT_OK, resultConsumer.latestReturn)
+ // Verify the pending intent has been called
+ assertTrue("Timed out waiting for broadcast", countdown.await(2500, TimeUnit.MILLISECONDS))
+ }
+
+ @Test
+ fun nonSendAction_noCopyRunnable() {
+ val targetIntent =
+ Intent(Intent.ACTION_SEND_MULTIPLE).apply {
+ putExtra(Intent.EXTRA_TEXT, "Text to show")
+ }
+
+ val chooserRequest =
+ mock<ChooserRequestParameters> {
+ whenever(this.targetIntent).thenReturn(targetIntent)
+ whenever(chooserActions).thenReturn(ImmutableList.of())
+ }
+ val testSubject =
+ ChooserActionFactory(
+ context,
+ chooserRequest,
+ Optional.empty(),
+ logger,
+ {},
+ { null },
+ mock(),
+ {},
+ )
+ assertThat(testSubject.copyButtonRunnable).isNull()
+ }
+
+ @Test
+ fun sendActionNoText_noCopyRunnable() {
+ val targetIntent = Intent(Intent.ACTION_SEND)
+
+ val chooserRequest =
+ mock<ChooserRequestParameters> {
+ whenever(this.targetIntent).thenReturn(targetIntent)
+ whenever(chooserActions).thenReturn(ImmutableList.of())
+ }
+ val testSubject =
+ ChooserActionFactory(
+ context,
+ chooserRequest,
+ Optional.empty(),
+ logger,
+ {},
+ { null },
+ mock(),
+ {},
+ )
+ assertThat(testSubject.copyButtonRunnable).isNull()
+ }
+
+ @Test
+ fun sendActionWithText_nonNullCopyRunnable() {
+ val targetIntent = Intent(Intent.ACTION_SEND).apply { putExtra(Intent.EXTRA_TEXT, "Text") }
+
+ val chooserRequest =
+ mock<ChooserRequestParameters> {
+ whenever(this.targetIntent).thenReturn(targetIntent)
+ whenever(chooserActions).thenReturn(ImmutableList.of())
+ }
+ val testSubject =
+ ChooserActionFactory(
+ context,
+ chooserRequest,
+ Optional.empty(),
+ logger,
+ {},
+ { null },
+ mock(),
+ {},
+ )
+ assertThat(testSubject.copyButtonRunnable).isNotNull()
+ }
+
+ private fun createFactory(includeModifyShare: Boolean = false): ChooserActionFactory {
+ val testPendingIntent =
+ PendingIntent.getBroadcast(context, 0, Intent(testAction), PendingIntent.FLAG_IMMUTABLE)
+ val targetIntent = Intent()
+ val action =
+ ChooserAction.Builder(
+ Icon.createWithResource("", Resources.ID_NULL),
+ actionLabel,
+ testPendingIntent
+ )
+ .build()
+ val chooserRequest = mock<ChooserRequestParameters>()
+ whenever(chooserRequest.targetIntent).thenReturn(targetIntent)
+ whenever(chooserRequest.chooserActions).thenReturn(ImmutableList.of(action))
+
+ if (includeModifyShare) {
+ val modifyShare =
+ ChooserAction.Builder(
+ Icon.createWithResource("", Resources.ID_NULL),
+ modifyShareLabel,
+ testPendingIntent
+ )
+ .build()
+ whenever(chooserRequest.modifyShareAction).thenReturn(modifyShare)
+ }
+
+ return ChooserActionFactory(
+ context,
+ chooserRequest,
+ Optional.empty(),
+ logger,
+ {},
+ { null },
+ mock(),
+ resultConsumer
+ )
+ }
+}
diff --git a/java/tests/src/com/android/intentresolver/v2/ChooserWrapperActivity.java b/java/tests/src/com/android/intentresolver/v2/ChooserWrapperActivity.java
index 41b31d01..65d33485 100644
--- a/java/tests/src/com/android/intentresolver/v2/ChooserWrapperActivity.java
+++ b/java/tests/src/com/android/intentresolver/v2/ChooserWrapperActivity.java
@@ -19,7 +19,6 @@ package com.android.intentresolver.v2;
import android.annotation.Nullable;
import android.app.prediction.AppPredictor;
import android.app.usage.UsageStatsManager;
-import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -35,7 +34,6 @@ import android.os.UserHandle;
import androidx.lifecycle.ViewModelProvider;
import com.android.intentresolver.AnnotatedUserHandles;
-import com.android.intentresolver.ChooserIntegratedDeviceComponents;
import com.android.intentresolver.ChooserListAdapter;
import com.android.intentresolver.ChooserRequestParameters;
import com.android.intentresolver.IChooserWrapper;
@@ -128,16 +126,6 @@ public class ChooserWrapperActivity extends ChooserActivity implements IChooserW
}
@Override
- protected ChooserIntegratedDeviceComponents getIntegratedDeviceComponents() {
- return new ChooserIntegratedDeviceComponents(
- /* editSharingComponent=*/ null,
- // An arbitrary pre-installed activity that handles this type of intent:
- /* nearbySharingComponent=*/ new ComponentName(
- "com.google.android.apps.messaging",
- ".ui.conversationlist.ShareIntentActivity"));
- }
-
- @Override
public UsageStatsManager getUsageStatsManager() {
if (mUsm == null) {
mUsm = getSystemService(UsageStatsManager.class);
diff --git a/java/tests/src/com/android/intentresolver/v2/UnbundledChooserActivityTest.java b/java/tests/src/com/android/intentresolver/v2/UnbundledChooserActivityTest.java
index 1e74c7a5..4a8a5568 100644
--- a/java/tests/src/com/android/intentresolver/v2/UnbundledChooserActivityTest.java
+++ b/java/tests/src/com/android/intentresolver/v2/UnbundledChooserActivityTest.java
@@ -17,6 +17,7 @@
package com.android.intentresolver.v2;
import static android.app.Activity.RESULT_OK;
+
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.longClick;
@@ -29,16 +30,20 @@ import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
+
+import static com.android.intentresolver.ChooserActivity.TARGET_TYPE_CHOOSER_TARGET;
+import static com.android.intentresolver.ChooserActivity.TARGET_TYPE_DEFAULT;
+import static com.android.intentresolver.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE;
+import static com.android.intentresolver.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER;
import static com.android.intentresolver.ChooserListAdapter.CALLER_TARGET_SCORE_BOOST;
import static com.android.intentresolver.ChooserListAdapter.SHORTCUT_TARGET_SCORE_BOOST;
import static com.android.intentresolver.MatcherUtils.first;
-import static com.android.intentresolver.v2.ChooserActivity.TARGET_TYPE_CHOOSER_TARGET;
-import static com.android.intentresolver.v2.ChooserActivity.TARGET_TYPE_DEFAULT;
-import static com.android.intentresolver.v2.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE;
-import static com.android.intentresolver.v2.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER;
+
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+
import static junit.framework.Assert.assertNull;
+
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
@@ -126,9 +131,16 @@ import com.android.intentresolver.contentpreview.ImageLoader;
import com.android.intentresolver.logging.EventLog;
import com.android.intentresolver.logging.FakeEventLog;
import com.android.intentresolver.shortcuts.ShortcutLoader;
+import com.android.intentresolver.v2.platform.ImageEditor;
+import com.android.intentresolver.v2.platform.ImageEditorModule;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import dagger.hilt.android.testing.BindValue;
+import dagger.hilt.android.testing.HiltAndroidRule;
+import dagger.hilt.android.testing.HiltAndroidTest;
+import dagger.hilt.android.testing.UninstallModules;
+
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
@@ -148,6 +160,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -157,17 +170,14 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Function;
-import dagger.hilt.android.testing.HiltAndroidRule;
-import dagger.hilt.android.testing.HiltAndroidTest;
-
/**
* Instrumentation tests for ChooserActivity.
* <p>
* Legacy test suite migrated from framework CoreTests.
- * <p>
*/
@RunWith(Parameterized.class)
@HiltAndroidTest
+@UninstallModules(ImageEditorModule.class)
public class UnbundledChooserActivityTest {
private static FakeEventLog getEventLog(ChooserWrapperActivity activity) {
@@ -228,6 +238,13 @@ public class UnbundledChooserActivityTest {
private final Function<PackageManager, PackageManager> mPackageManagerOverride;
+ /** An arbitrary pre-installed activity that handles this type of intent. */
+ @BindValue
+ @ImageEditor
+ final Optional<ComponentName> mImageEditor = Optional.ofNullable(
+ ComponentName.unflattenFromString("com.google.android.apps.messaging/"
+ + ".ui.conversationlist.ShareIntentActivity"));
+
public UnbundledChooserActivityTest(
Function<PackageManager, PackageManager> packageManagerOverride) {
mPackageManagerOverride = packageManagerOverride;
@@ -897,10 +914,9 @@ public class UnbundledChooserActivityTest {
// TODO(b/211669337): Determine the expected SHARESHEET_DIRECT_LOAD_COMPLETE events.
}
-
-
@Test @Ignore
public void testEditImageLogs() {
+
Uri uri = createTestContentProviderUri("image/png", null);
Intent sendIntent = createSendImageIntent(uri);
ChooserActivityOverrideData.getInstance().imageLoader =
@@ -2195,17 +2211,17 @@ public class UnbundledChooserActivityTest {
mActivityRule.launchActivity(Intent.createChooser(sendIntent, "Scrollable preview test"));
waitForIdle();
- onView(withId(R.id.scrollable_image_preview))
+ onView(withId(com.android.intentresolver.R.id.scrollable_image_preview))
.check(matches(isDisplayed()));
onView(withId(com.android.internal.R.id.contentPanel)).perform(swipeUp());
waitForIdle();
- onView(withId(R.id.chooser_headline_row_container))
+ onView(withId(com.android.intentresolver.R.id.chooser_headline_row_container))
.check(matches(isCompletelyDisplayed()));
- onView(withId(R.id.headline))
+ onView(withId(com.android.intentresolver.R.id.headline))
.check(matches(isDisplayed()));
- onView(withId(R.id.scrollable_image_preview))
+ onView(withId(com.android.intentresolver.R.id.scrollable_image_preview))
.check(matches(not(isDisplayed())));
}
diff --git a/java/tests/src/com/android/intentresolver/v2/platform/FakeSecureSettings.kt b/java/tests/src/com/android/intentresolver/v2/platform/FakeSecureSettings.kt
new file mode 100644
index 00000000..4e279623
--- /dev/null
+++ b/java/tests/src/com/android/intentresolver/v2/platform/FakeSecureSettings.kt
@@ -0,0 +1,44 @@
+package com.android.intentresolver.v2.platform
+
+/**
+ * Creates a SecureSettings instance with predefined values:
+ *
+ * val settings = fakeSecureSettings {
+ * putString("stringValue", "example")
+ * putInt("intValue", 42)
+ * }
+ */
+fun fakeSecureSettings(block: FakeSecureSettings.Builder.() -> Unit): SecureSettings {
+ return FakeSecureSettings.Builder().apply(block).build()
+}
+
+/** An in memory implementation of [SecureSettings]. */
+class FakeSecureSettings private constructor(private val map: Map<String, String>) :
+ SecureSettings {
+
+ override fun getString(name: String): String? = map[name]
+ override fun getInt(name: String): Int? = getString(name)?.toIntOrNull()
+ override fun getLong(name: String): Long? = getString(name)?.toLongOrNull()
+ override fun getFloat(name: String): Float? = getString(name)?.toFloatOrNull()
+
+ class Builder {
+ private val map = mutableMapOf<String, String>()
+
+ fun putString(name: String, value: String) {
+ map[name] = value
+ }
+ fun putInt(name: String, value: Int) {
+ map[name] = value.toString()
+ }
+ fun putLong(name: String, value: Long) {
+ map[name] = value.toString()
+ }
+ fun putFloat(name: String, value: Float) {
+ map[name] = value.toString()
+ }
+
+ fun build(): SecureSettings {
+ return FakeSecureSettings(map.toMap())
+ }
+ }
+}
diff --git a/java/tests/src/com/android/intentresolver/v2/platform/FakeSecureSettingsTest.kt b/java/tests/src/com/android/intentresolver/v2/platform/FakeSecureSettingsTest.kt
new file mode 100644
index 00000000..04c7093d
--- /dev/null
+++ b/java/tests/src/com/android/intentresolver/v2/platform/FakeSecureSettingsTest.kt
@@ -0,0 +1,61 @@
+package com.android.intentresolver.v2.platform
+
+import com.google.common.truth.Truth.assertThat
+
+class FakeSecureSettingsTest {
+
+ private val secureSettings = fakeSecureSettings {
+ putInt(intKey, intVal)
+ putString(stringKey, stringVal)
+ putFloat(floatKey, floatVal)
+ putLong(longKey, longVal)
+ }
+
+ fun testExpectedValues_returned() {
+ assertThat(secureSettings.getInt(intKey)).isEqualTo(intVal)
+ assertThat(secureSettings.getString(stringKey)).isEqualTo(stringVal)
+ assertThat(secureSettings.getFloat(floatKey)).isEqualTo(floatVal)
+ assertThat(secureSettings.getLong(longKey)).isEqualTo(longVal)
+ }
+
+ fun testUndefinedValues_returnNull() {
+ assertThat(secureSettings.getInt("unknown")).isNull()
+ assertThat(secureSettings.getString("unknown")).isNull()
+ assertThat(secureSettings.getFloat("unknown")).isNull()
+ assertThat(secureSettings.getLong("unknown")).isNull()
+ }
+
+ /**
+ * FakeSecureSettings models the real secure settings by storing values in String form. The
+ * value is returned if/when it can be parsed from the string value, otherwise null.
+ */
+ fun testMismatchedTypes() {
+ assertThat(secureSettings.getString(intKey)).isEqualTo(intVal.toString())
+ assertThat(secureSettings.getString(floatKey)).isEqualTo(floatVal.toString())
+ assertThat(secureSettings.getString(longKey)).isEqualTo(longVal.toString())
+
+ assertThat(secureSettings.getInt(stringKey)).isNull()
+ assertThat(secureSettings.getLong(stringKey)).isNull()
+ assertThat(secureSettings.getFloat(stringKey)).isNull()
+
+ assertThat(secureSettings.getInt(longKey)).isNull()
+ assertThat(secureSettings.getFloat(longKey)).isNull() // TODO: verify Long.MAX > Float.MAX ?
+
+ assertThat(secureSettings.getLong(floatKey)).isNull() // TODO: or is Float.MAX > Long.MAX?
+ assertThat(secureSettings.getInt(floatKey)).isNull()
+ }
+
+ companion object Data {
+ const val intKey = "int"
+ const val intVal = Int.MAX_VALUE
+
+ const val stringKey = "string"
+ const val stringVal = "String"
+
+ const val floatKey = "float"
+ const val floatVal = Float.MAX_VALUE
+
+ const val longKey = "long"
+ const val longVal = Long.MAX_VALUE
+ }
+}
diff --git a/java/tests/src/com/android/intentresolver/v2/platform/NearbyShareModuleTest.kt b/java/tests/src/com/android/intentresolver/v2/platform/NearbyShareModuleTest.kt
new file mode 100644
index 00000000..fd5c8b3f
--- /dev/null
+++ b/java/tests/src/com/android/intentresolver/v2/platform/NearbyShareModuleTest.kt
@@ -0,0 +1,83 @@
+package com.android.intentresolver.v2.platform
+
+import android.content.ComponentName
+import android.content.Context
+import android.content.res.Configuration
+import android.provider.Settings
+import android.testing.TestableResources
+
+import androidx.test.platform.app.InstrumentationRegistry
+
+import com.android.intentresolver.R
+
+import com.google.common.truth.Truth8.assertThat
+
+import org.junit.Before
+import org.junit.Test
+
+class NearbyShareModuleTest {
+
+ lateinit var context: Context
+
+ /** Create Resources with overridden values. */
+ private fun Context.fakeResources(
+ config: Configuration? = null,
+ block: TestableResources.() -> Unit
+ ) =
+ TestableResources(resources)
+ .apply { config?.let { overrideConfiguration(it) } }
+ .apply(block)
+ .resources
+
+ @Before
+ fun setup() {
+ val instr = InstrumentationRegistry.getInstrumentation()
+ context = instr.context
+ }
+
+ @Test
+ fun valueIsAbsent_whenUnset() {
+ val secureSettings = fakeSecureSettings {}
+ val resources =
+ context.fakeResources { addOverride(R.string.config_defaultNearbySharingComponent, "") }
+
+ val componentName = NearbyShareModule.nearbyShareComponent(resources, secureSettings)
+ assertThat(componentName).isEmpty()
+ }
+
+ @Test
+ fun defaultValue_readFromResources() {
+ val secureSettings = fakeSecureSettings {}
+ val resources =
+ context.fakeResources {
+ addOverride(
+ R.string.config_defaultNearbySharingComponent,
+ "com.example/.ComponentName"
+ )
+ }
+
+ val nearbyShareComponent = NearbyShareModule.nearbyShareComponent(resources, secureSettings)
+
+ assertThat(nearbyShareComponent).hasValue(
+ ComponentName.unflattenFromString("com.example/.ComponentName"))
+ }
+
+ @Test
+ fun secureSettings_overridesDefault() {
+ val secureSettings = fakeSecureSettings {
+ putString(Settings.Secure.NEARBY_SHARING_COMPONENT, "com.example/.BComponent")
+ }
+ val resources =
+ context.fakeResources {
+ addOverride(
+ R.string.config_defaultNearbySharingComponent,
+ "com.example/.AComponent"
+ )
+ }
+
+ val nearbyShareComponent = NearbyShareModule.nearbyShareComponent(resources, secureSettings)
+
+ assertThat(nearbyShareComponent).hasValue(
+ ComponentName.unflattenFromString("com.example/.BComponent"))
+ }
+}