diff --git a/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt b/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt index d4bc4de14..10fc1f360 100644 --- a/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt @@ -44,27 +44,30 @@ class IntentReceiverActivity : Activity() { // assumes it is not. If it's null, then we make a new one and open // the HomeActivity. val intent = intent?.let { Intent(intent) } ?: Intent() + processIntent(intent) + } + } - val tabIntentProcessor = if (settings().alwaysOpenInPrivateMode) { - components.intentProcessors.privateIntentProcessor - } else { - components.intentProcessors.intentProcessor - } + suspend fun processIntent(intent: Intent) { + val tabIntentProcessor = if (settings().alwaysOpenInPrivateMode) { + components.intentProcessors.privateIntentProcessor + } else { + components.intentProcessors.intentProcessor + } - val intentProcessors = - components.intentProcessors.externalAppIntentProcessors + tabIntentProcessor + val intentProcessors = + components.intentProcessors.externalAppIntentProcessors + tabIntentProcessor - if (intent.getBooleanExtra(SPEECH_PROCESSING, false)) { - previousIntent = intent - displaySpeechRecognizer() - } else { - intentProcessors.any { it.process(intent) } - setIntentActivity(intent, tabIntentProcessor) + if (intent.getBooleanExtra(SPEECH_PROCESSING, false)) { + previousIntent = intent + displaySpeechRecognizer() + } else { + intentProcessors.any { it.process(intent) } + setIntentActivity(intent, tabIntentProcessor) - startActivity(intent) + startActivity(intent) - finish() - } + finish() } } @@ -151,7 +154,7 @@ class IntentReceiverActivity : Activity() { } companion object { - private const val SPEECH_REQUEST_CODE = 0 + const val SPEECH_REQUEST_CODE = 0 const val SPEECH_PROCESSING = "speech_processing" const val PREVIOUS_INTENT = "previous_intent" const val ACTION_OPEN_TAB = "org.mozilla.fenix.OPEN_TAB" diff --git a/app/src/test/java/org/mozilla/fenix/IntentReceiverActivityTest.kt b/app/src/test/java/org/mozilla/fenix/IntentReceiverActivityTest.kt new file mode 100644 index 000000000..a8d36edaa --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/IntentReceiverActivityTest.kt @@ -0,0 +1,89 @@ +/* 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 + +import android.content.Intent +import android.speech.RecognizerIntent.ACTION_RECOGNIZE_SPEECH +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.ObsoleteCoroutinesApi +import kotlinx.coroutines.test.runBlockingTest +import mozilla.components.support.test.argumentCaptor +import mozilla.components.support.test.robolectric.testContext +import org.junit.Assert.assertEquals + +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.eq +import org.mockito.Mockito.never +import org.mockito.Mockito.spy +import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` +import org.robolectric.annotation.Config +import org.mozilla.fenix.ext.components +import org.mozilla.fenix.ext.settings +import org.robolectric.Robolectric +import org.robolectric.RobolectricTestRunner + +@ObsoleteCoroutinesApi +@ExperimentalCoroutinesApi +@RunWith(RobolectricTestRunner::class) +@Config(application = TestApplication::class) +class IntentReceiverActivityTest { + + @Test + fun `process intent with alwaysOpenInPrivateMode set to true`() { + runBlockingTest { + testContext.settings.alwaysOpenInPrivateMode = true + + val intent = Intent() + `when`(testContext.components.intentProcessors.privateIntentProcessor.process(intent)).thenReturn(true) + val activity = Robolectric.buildActivity(IntentReceiverActivity::class.java, intent).get() + activity.processIntent(intent) + + // Not using mockk here because process is a suspend function + // and mockito makes this easier to read. + verify(testContext.components.intentProcessors.intentProcessor, never()).process(intent) + verify(testContext.components.intentProcessors.privateIntentProcessor).process(intent) + } + } + + @Test + fun `process intent with alwaysOpenInPrivateMode set to false`() { + runBlockingTest { + testContext.settings.alwaysOpenInPrivateMode = false + + val intent = Intent() + `when`(testContext.components.intentProcessors.intentProcessor.process(intent)).thenReturn(true) + + val activity = Robolectric.buildActivity(IntentReceiverActivity::class.java, intent).get() + activity.processIntent(intent) + + // Not using mockk here because process is a suspend function + // and mockito makes this easier to read. + verify(testContext.components.intentProcessors.privateIntentProcessor, never()).process(intent) + verify(testContext.components.intentProcessors.intentProcessor).process(intent) + } + } + + @Test + fun `process intent with speech processing set to true`() { + runBlockingTest { + val intent = Intent() + intent.putExtra(IntentReceiverActivity.SPEECH_PROCESSING, true) + + val activity = spy(Robolectric.buildActivity(IntentReceiverActivity::class.java, intent).get()) + activity.processIntent(intent) + + val speechIntent = argumentCaptor() + + // Not using mockk here because process is a suspend function + // and mockito makes this easier to read. + verify(testContext.components.intentProcessors.privateIntentProcessor, never()).process(intent) + verify(testContext.components.intentProcessors.intentProcessor, never()).process(intent) + verify(activity).startActivityForResult(speechIntent.capture(), eq(IntentReceiverActivity.SPEECH_REQUEST_CODE)) + assertEquals(ACTION_RECOGNIZE_SPEECH, speechIntent.value.action) + } + } +} diff --git a/app/src/test/java/org/mozilla/fenix/TestApplication.kt b/app/src/test/java/org/mozilla/fenix/TestApplication.kt index 9aa64f800..4827f1ad9 100644 --- a/app/src/test/java/org/mozilla/fenix/TestApplication.kt +++ b/app/src/test/java/org/mozilla/fenix/TestApplication.kt @@ -5,14 +5,12 @@ package org.mozilla.fenix import kotlinx.coroutines.ObsoleteCoroutinesApi -import org.mozilla.fenix.components.Components import org.mozilla.fenix.components.TestComponents @ObsoleteCoroutinesApi class TestApplication : FenixApplication() { - override val components: Components - get() = TestComponents(this) + override val components = TestComponents(this) override fun setupApplication() { } diff --git a/app/src/test/java/org/mozilla/fenix/components/TestComponents.kt b/app/src/test/java/org/mozilla/fenix/components/TestComponents.kt index 16922235f..ce418c7a4 100644 --- a/app/src/test/java/org/mozilla/fenix/components/TestComponents.kt +++ b/app/src/test/java/org/mozilla/fenix/components/TestComponents.kt @@ -7,6 +7,8 @@ package org.mozilla.fenix.components import android.content.Context import io.mockk.mockk import kotlinx.coroutines.ObsoleteCoroutinesApi +import mozilla.components.support.test.mock +import org.mockito.Mockito.`when` import org.mozilla.fenix.utils.ClipboardHandler @ObsoleteCoroutinesApi @@ -27,12 +29,11 @@ class TestComponents(private val context: Context) : Components(context) { ) } override val intentProcessors by lazy { - IntentProcessors( - context, - core.sessionManager, - useCases.sessionUseCases, - useCases.searchUseCases - ) + val processors: IntentProcessors = mock() + `when`(processors.externalAppIntentProcessors).thenReturn(emptyList()) + `when`(processors.privateIntentProcessor).thenReturn(mock()) + `when`(processors.intentProcessor).thenReturn(mock()) + processors } override val analytics by lazy { Analytics(context) } diff --git a/app/src/test/java/org/mozilla/fenix/components/TestCore.kt b/app/src/test/java/org/mozilla/fenix/components/TestCore.kt index f9af81f7c..95b2abff7 100644 --- a/app/src/test/java/org/mozilla/fenix/components/TestCore.kt +++ b/app/src/test/java/org/mozilla/fenix/components/TestCore.kt @@ -9,10 +9,12 @@ import io.mockk.mockk import kotlinx.coroutines.ObsoleteCoroutinesApi import mozilla.components.browser.engine.gecko.GeckoEngine import mozilla.components.browser.session.SessionManager +import mozilla.components.concept.fetch.Client @ObsoleteCoroutinesApi class TestCore(private val context: Context) : Core(context) { override val engine = mockk(relaxed = true) override val sessionManager = SessionManager(engine) + override val client = mockk() }