mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-19 09:25:34 +00:00
[fenix] Extract intent processors from HomeActivity (https://github.com/mozilla-mobile/fenix/pull/4884)
This commit is contained in:
parent
11a92537ce
commit
63814821eb
@ -6,8 +6,6 @@ package org.mozilla.fenix
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
@ -28,7 +26,6 @@ import mozilla.components.browser.search.SearchEngine
|
||||
import mozilla.components.browser.session.Session
|
||||
import mozilla.components.browser.session.SessionManager
|
||||
import mozilla.components.concept.engine.EngineView
|
||||
import mozilla.components.lib.crash.Crash
|
||||
import mozilla.components.support.base.feature.BackHandler
|
||||
import mozilla.components.support.ktx.kotlin.isUrl
|
||||
import mozilla.components.support.ktx.kotlin.toNormalizedUrl
|
||||
@ -44,6 +41,11 @@ import org.mozilla.fenix.components.metrics.SentryBreadcrumbsRecorder
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.getRootView
|
||||
import org.mozilla.fenix.ext.nav
|
||||
import org.mozilla.fenix.home.intent.CrashReporterIntentProcessor
|
||||
import org.mozilla.fenix.home.intent.DeepLinkIntentProcessor
|
||||
import org.mozilla.fenix.home.intent.OpenBrowserIntentProcessor
|
||||
import org.mozilla.fenix.home.intent.SpeechProcessingIntentProcessor
|
||||
import org.mozilla.fenix.home.intent.StartSearchIntentProcessor
|
||||
import org.mozilla.fenix.share.ShareFragment
|
||||
import org.mozilla.fenix.theme.DefaultThemeManager
|
||||
import org.mozilla.fenix.theme.ThemeManager
|
||||
@ -61,6 +63,15 @@ open class HomeActivity : AppCompatActivity(), ShareFragment.TabsSharedCallback
|
||||
supportFragmentManager.findFragmentById(R.id.container) as NavHostFragment
|
||||
}
|
||||
|
||||
private val externalSourceIntentProcessors by lazy {
|
||||
listOf(
|
||||
SpeechProcessingIntentProcessor(this),
|
||||
StartSearchIntentProcessor(components.analytics.metrics),
|
||||
DeepLinkIntentProcessor(this),
|
||||
OpenBrowserIntentProcessor(this, ::getIntentSessionId)
|
||||
)
|
||||
}
|
||||
|
||||
final override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
@ -105,8 +116,10 @@ open class HomeActivity : AppCompatActivity(), ShareFragment.TabsSharedCallback
|
||||
*/
|
||||
final override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
handleCrashIfNecessary(intent)
|
||||
handleOpenedFromExternalSourceIfNecessary(intent)
|
||||
intent ?: return
|
||||
|
||||
val intentProcessors = listOf(CrashReporterIntentProcessor()) + externalSourceIntentProcessors
|
||||
intentProcessors.any { it.process(intent, navHost.navController, this.intent) }
|
||||
}
|
||||
|
||||
/**
|
||||
@ -162,86 +175,7 @@ open class HomeActivity : AppCompatActivity(), ShareFragment.TabsSharedCallback
|
||||
onBackPressed()
|
||||
}
|
||||
|
||||
handleOpenedFromExternalSourceIfNecessary(intent)
|
||||
}
|
||||
|
||||
private fun handleCrashIfNecessary(intent: Intent?) {
|
||||
if (intent != null && Crash.isCrashIntent(intent)) {
|
||||
openToCrashReporter(intent)
|
||||
}
|
||||
}
|
||||
|
||||
private fun openToCrashReporter(intent: Intent) {
|
||||
val directions = NavGraphDirections.actionGlobalCrashReporter(intent)
|
||||
navHost.navController.navigate(directions)
|
||||
}
|
||||
|
||||
private fun handleOpenedFromExternalSourceIfNecessary(intent: Intent?) {
|
||||
if (intent?.extras?.getBoolean(OPEN_TO_BROWSER_AND_LOAD) == true) {
|
||||
this.intent.putExtra(OPEN_TO_BROWSER_AND_LOAD, false)
|
||||
openToBrowserAndLoad(
|
||||
intent.getStringExtra(
|
||||
IntentReceiverActivity.SPEECH_PROCESSING
|
||||
), true, BrowserDirection.FromGlobal, forceSearch = true
|
||||
)
|
||||
return
|
||||
} else if (intent?.extras?.getBoolean(OPEN_TO_SEARCH) == true) {
|
||||
this.intent.putExtra(OPEN_TO_SEARCH, false)
|
||||
components.analytics.metrics.track(Event.SearchWidgetNewTabPressed)
|
||||
navHost.navController.nav(null, NavGraphDirections.actionGlobalSearch(null, true))
|
||||
return
|
||||
} else if (intent?.scheme == "fenix") {
|
||||
intent.data?.let { handleDeepLink(it) }
|
||||
}
|
||||
|
||||
if (intent?.extras?.getBoolean(OPEN_TO_BROWSER) != true) return
|
||||
|
||||
this.intent.putExtra(OPEN_TO_BROWSER, false)
|
||||
|
||||
openToBrowser(BrowserDirection.FromGlobal, getIntentSessionId(intent.toSafeIntent()))
|
||||
}
|
||||
|
||||
@SuppressWarnings("ComplexMethod")
|
||||
private fun handleDeepLink(uri: Uri) {
|
||||
val link = uri.host
|
||||
|
||||
// Handle links that require more than just simple navigation
|
||||
when (link) {
|
||||
"enable_private_browsing" -> {
|
||||
navHost.navController.navigate(NavGraphDirections.actionGlobalHomeFragment())
|
||||
browsingModeManager.mode = BrowsingMode.Private
|
||||
}
|
||||
"make_default_browser" -> {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { return }
|
||||
val settingsIntent = Intent(
|
||||
android.provider.Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS
|
||||
)
|
||||
startActivity(settingsIntent)
|
||||
}
|
||||
"open" -> {
|
||||
uri.getQueryParameter("url")?.let {
|
||||
load(
|
||||
searchTermOrURL = it,
|
||||
newTab = true,
|
||||
engine = null,
|
||||
forceSearch = false
|
||||
)
|
||||
navHost.navController.navigate(NavGraphDirections.actionGlobalBrowser(null))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val directions = when (link) {
|
||||
"home" -> NavGraphDirections.actionGlobalHomeFragment()
|
||||
"settings" -> NavGraphDirections.actionGlobalSettingsFragment()
|
||||
"turn_on_sync" -> NavGraphDirections.actionGlobalTurnOnSync()
|
||||
"settings_search_engine" -> NavGraphDirections.actionGlobalSearchEngineFragment()
|
||||
"settings_accessibility" -> NavGraphDirections.actionGlobalAccessibilityFragment()
|
||||
"settings_delete_browsing_data" -> NavGraphDirections.actionGlobalDeleteBrowsingDataFragment()
|
||||
else -> return
|
||||
}
|
||||
|
||||
navHost.navController.navigate(directions)
|
||||
externalSourceIntentProcessors.any { it.process(intent, navHost.navController, this.intent) }
|
||||
}
|
||||
|
||||
protected open fun getIntentSessionId(intent: SafeIntent): String? = null
|
||||
@ -264,11 +198,7 @@ open class HomeActivity : AppCompatActivity(), ShareFragment.TabsSharedCallback
|
||||
sessionObserver = subscribeToSessions()
|
||||
|
||||
with(navHost.navController) {
|
||||
if (currentDestination?.id == R.id.browserFragment || popBackStack(
|
||||
R.id.browserFragment,
|
||||
false
|
||||
)
|
||||
) return
|
||||
if (currentDestination?.id == R.id.browserFragment || popBackStack(R.id.browserFragment, false)) return
|
||||
}
|
||||
|
||||
@IdRes val fragmentId = if (from.fragmentId != 0) from.fragmentId else null
|
||||
|
@ -0,0 +1,31 @@
|
||||
/* 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.home.intent
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.navigation.NavController
|
||||
import mozilla.components.lib.crash.Crash
|
||||
import org.mozilla.fenix.NavGraphDirections
|
||||
|
||||
/**
|
||||
* When the app crashes, the user has the option to report it.
|
||||
* Reporting fires an intent to the main activity which is handled here.
|
||||
*/
|
||||
class CrashReporterIntentProcessor : HomeIntentProcessor {
|
||||
|
||||
override fun process(intent: Intent, navController: NavController, out: Intent): Boolean {
|
||||
return if (Crash.isCrashIntent(intent)) {
|
||||
openToCrashReporter(intent, navController)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
private fun openToCrashReporter(intent: Intent, navController: NavController) {
|
||||
val directions = NavGraphDirections.actionGlobalCrashReporter(intent)
|
||||
navController.navigate(directions)
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/* 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.home.intent
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Build.VERSION.SDK_INT
|
||||
import android.provider.Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS
|
||||
import androidx.navigation.NavController
|
||||
import org.mozilla.fenix.BrowserDirection
|
||||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.NavGraphDirections
|
||||
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
||||
|
||||
/**
|
||||
* Deep links in the form of `fenix://host` open different parts of the app.
|
||||
*/
|
||||
class DeepLinkIntentProcessor(
|
||||
private val activity: HomeActivity
|
||||
) : HomeIntentProcessor {
|
||||
|
||||
override fun process(intent: Intent, navController: NavController, out: Intent): Boolean {
|
||||
return if (intent.scheme == "fenix") {
|
||||
intent.data?.let { handleDeepLink(it, navController) }
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleDeepLink(deepLink: Uri, navController: NavController) {
|
||||
handleDeepLinkSideEffects(deepLink)
|
||||
|
||||
val directions = when (deepLink.host) {
|
||||
"home", "enable_private_browsing" -> NavGraphDirections.actionGlobalHomeFragment()
|
||||
"settings" -> NavGraphDirections.actionGlobalSettingsFragment()
|
||||
"turn_on_sync" -> NavGraphDirections.actionGlobalTurnOnSync()
|
||||
"settings_search_engine" -> NavGraphDirections.actionGlobalSearchEngineFragment()
|
||||
"settings_accessibility" -> NavGraphDirections.actionGlobalAccessibilityFragment()
|
||||
"settings_delete_browsing_data" -> NavGraphDirections.actionGlobalDeleteBrowsingDataFragment()
|
||||
else -> return
|
||||
}
|
||||
|
||||
navController.navigate(directions)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle links that require more than just simple navigation.
|
||||
*/
|
||||
private fun handleDeepLinkSideEffects(deepLink: Uri) {
|
||||
when (deepLink.host) {
|
||||
"enable_private_browsing" -> {
|
||||
activity.browsingModeManager.mode = BrowsingMode.Private
|
||||
}
|
||||
"make_default_browser" -> {
|
||||
if (SDK_INT >= Build.VERSION_CODES.N) {
|
||||
val settingsIntent = Intent(ACTION_MANAGE_DEFAULT_APPS_SETTINGS)
|
||||
activity.startActivity(settingsIntent)
|
||||
}
|
||||
}
|
||||
"open" -> {
|
||||
deepLink.getQueryParameter("url")?.let { searchTermOrUrl ->
|
||||
activity.openToBrowserAndLoad(
|
||||
searchTermOrUrl,
|
||||
newTab = true,
|
||||
from = BrowserDirection.FromGlobal
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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.home.intent
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.navigation.NavController
|
||||
|
||||
/**
|
||||
* Processor for Android intents received in [org.mozilla.fenix.HomeActivity].
|
||||
*/
|
||||
interface HomeIntentProcessor {
|
||||
|
||||
/**
|
||||
* Processes the given [intent]. May add properties to [out].
|
||||
*
|
||||
* @param intent The intent to process.
|
||||
* @param navController Controller to navigate between fragments.
|
||||
* @param out Intent to mutate.
|
||||
* @return True if the intent was processed, otherwise false.
|
||||
*/
|
||||
fun process(intent: Intent, navController: NavController, out: Intent): Boolean
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/* 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.home.intent
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.navigation.NavController
|
||||
import mozilla.components.support.utils.SafeIntent
|
||||
import mozilla.components.support.utils.toSafeIntent
|
||||
import org.mozilla.fenix.BrowserDirection
|
||||
import org.mozilla.fenix.HomeActivity
|
||||
|
||||
/**
|
||||
* The [org.mozilla.fenix.IntentReceiverActivity] may set the [HomeActivity.OPEN_TO_BROWSER] flag
|
||||
* when the browser should be opened in response to an intent.
|
||||
*/
|
||||
class OpenBrowserIntentProcessor(
|
||||
private val activity: HomeActivity,
|
||||
private val getIntentSessionId: (SafeIntent) -> String?
|
||||
) : HomeIntentProcessor {
|
||||
|
||||
override fun process(intent: Intent, navController: NavController, out: Intent): Boolean {
|
||||
return if (intent.extras?.getBoolean(HomeActivity.OPEN_TO_BROWSER) == true) {
|
||||
out.putExtra(HomeActivity.OPEN_TO_BROWSER, false)
|
||||
|
||||
activity.openToBrowser(BrowserDirection.FromGlobal, getIntentSessionId(intent.toSafeIntent()))
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/* 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.home.intent
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.navigation.NavController
|
||||
import org.mozilla.fenix.BrowserDirection
|
||||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.IntentReceiverActivity
|
||||
|
||||
/**
|
||||
* The search widget has a microphone button to let users search with their voice.
|
||||
* Once the search is complete then a new search should be started.
|
||||
*/
|
||||
class SpeechProcessingIntentProcessor(
|
||||
private val activity: HomeActivity
|
||||
) : HomeIntentProcessor {
|
||||
|
||||
override fun process(intent: Intent, navController: NavController, out: Intent): Boolean {
|
||||
return if (intent.extras?.getBoolean(HomeActivity.OPEN_TO_BROWSER_AND_LOAD) == true) {
|
||||
out.putExtra(HomeActivity.OPEN_TO_BROWSER_AND_LOAD, false)
|
||||
activity.openToBrowserAndLoad(
|
||||
searchTermOrURL = intent.getStringExtra(IntentReceiverActivity.SPEECH_PROCESSING).orEmpty(),
|
||||
newTab = true,
|
||||
from = BrowserDirection.FromGlobal,
|
||||
forceSearch = true
|
||||
)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/* 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.home.intent
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.navigation.NavController
|
||||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.NavGraphDirections
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.components.metrics.MetricController
|
||||
import org.mozilla.fenix.ext.nav
|
||||
|
||||
/**
|
||||
* When the search widget is tapped, Fenix should open to the search fragment.
|
||||
*/
|
||||
class StartSearchIntentProcessor(
|
||||
private val metrics: MetricController
|
||||
) : HomeIntentProcessor {
|
||||
|
||||
override fun process(intent: Intent, navController: NavController, out: Intent): Boolean {
|
||||
return if (intent.extras?.getBoolean(HomeActivity.OPEN_TO_SEARCH) == true) {
|
||||
out.putExtra(HomeActivity.OPEN_TO_SEARCH, false)
|
||||
metrics.track(Event.SearchWidgetNewTabPressed)
|
||||
|
||||
val directions = NavGraphDirections.actionGlobalSearch(sessionId = null, showShortcutEnginePicker = true)
|
||||
navController.nav(null, directions)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/* 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.home.intent
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.navigation.NavController
|
||||
import io.mockk.Called
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.ObsoleteCoroutinesApi
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.NavGraphDirections
|
||||
import org.mozilla.fenix.TestApplication
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@ObsoleteCoroutinesApi
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(application = TestApplication::class)
|
||||
class CrashReporterIntentProcessorTest {
|
||||
|
||||
@Test
|
||||
fun `do not process blank intents`() {
|
||||
val navController: NavController = mockk()
|
||||
val out: Intent = mockk()
|
||||
CrashReporterIntentProcessor().process(Intent(), navController, out)
|
||||
|
||||
verify { navController wasNot Called }
|
||||
verify { out wasNot Called }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `process crash intents`() {
|
||||
val navController: NavController = mockk(relaxed = true)
|
||||
val out: Intent = mockk()
|
||||
val intent = Intent().apply {
|
||||
putExtra("mozilla.components.lib.crash.CRASH", mockk<Bundle>())
|
||||
}
|
||||
CrashReporterIntentProcessor().process(intent, navController, out)
|
||||
|
||||
verify { navController.navigate(NavGraphDirections.actionGlobalCrashReporter(intent)) }
|
||||
verify { out wasNot Called }
|
||||
}
|
||||
}
|
@ -0,0 +1,156 @@
|
||||
/* 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.home.intent
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.core.net.toUri
|
||||
import androidx.navigation.NavController
|
||||
import io.mockk.Called
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.ObsoleteCoroutinesApi
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.BrowserDirection
|
||||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.NavGraphDirections
|
||||
import org.mozilla.fenix.TestApplication
|
||||
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@ObsoleteCoroutinesApi
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(application = TestApplication::class)
|
||||
class DeepLinkIntentProcessorTest {
|
||||
|
||||
private lateinit var activity: HomeActivity
|
||||
private lateinit var navController: NavController
|
||||
private lateinit var out: Intent
|
||||
private lateinit var processor: DeepLinkIntentProcessor
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
activity = mockk(relaxed = true)
|
||||
navController = mockk(relaxed = true)
|
||||
out = mockk()
|
||||
processor = DeepLinkIntentProcessor(activity)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `do not process blank intents`() {
|
||||
assertFalse(processor.process(Intent(), navController, out))
|
||||
|
||||
verify { activity wasNot Called }
|
||||
verify { navController wasNot Called }
|
||||
verify { out wasNot Called }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `return true if scheme is fenix`() {
|
||||
assertTrue(processor.process(testIntent("fenix://test"), navController, out))
|
||||
|
||||
verify { activity wasNot Called }
|
||||
verify { navController wasNot Called }
|
||||
verify { out wasNot Called }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `process home deep link`() {
|
||||
assertTrue(processor.process(testIntent("fenix://home"), navController, out))
|
||||
|
||||
verify { activity wasNot Called }
|
||||
verify { navController.navigate(NavGraphDirections.actionGlobalHomeFragment()) }
|
||||
verify { out wasNot Called }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `process settings deep link`() {
|
||||
assertTrue(processor.process(testIntent("fenix://settings"), navController, out))
|
||||
|
||||
verify { activity wasNot Called }
|
||||
verify { navController.navigate(NavGraphDirections.actionGlobalSettingsFragment()) }
|
||||
verify { out wasNot Called }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `process turn_on_sync deep link`() {
|
||||
assertTrue(processor.process(testIntent("fenix://turn_on_sync"), navController, out))
|
||||
|
||||
verify { activity wasNot Called }
|
||||
verify { navController.navigate(NavGraphDirections.actionGlobalTurnOnSync()) }
|
||||
verify { out wasNot Called }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `process settings_search_engine deep link`() {
|
||||
assertTrue(processor.process(testIntent("fenix://settings_search_engine"), navController, out))
|
||||
|
||||
verify { activity wasNot Called }
|
||||
verify { navController.navigate(NavGraphDirections.actionGlobalSearchEngineFragment()) }
|
||||
verify { out wasNot Called }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `process settings_accessibility deep link`() {
|
||||
assertTrue(processor.process(testIntent("fenix://settings_accessibility"), navController, out))
|
||||
|
||||
verify { activity wasNot Called }
|
||||
verify { navController.navigate(NavGraphDirections.actionGlobalAccessibilityFragment()) }
|
||||
verify { out wasNot Called }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `process settings_delete_browsing_data deep link`() {
|
||||
assertTrue(processor.process(testIntent("fenix://settings_delete_browsing_data"), navController, out))
|
||||
|
||||
verify { activity wasNot Called }
|
||||
verify { navController.navigate(NavGraphDirections.actionGlobalDeleteBrowsingDataFragment()) }
|
||||
verify { out wasNot Called }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `process enable_private_browsing deep link`() {
|
||||
assertTrue(processor.process(testIntent("fenix://enable_private_browsing"), navController, out))
|
||||
|
||||
verify { activity.browsingModeManager.mode = BrowsingMode.Private }
|
||||
verify { navController.navigate(NavGraphDirections.actionGlobalHomeFragment()) }
|
||||
verify { out wasNot Called }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `process open deep link`() {
|
||||
assertTrue(processor.process(testIntent("fenix://open"), navController, out))
|
||||
|
||||
verify { activity wasNot Called }
|
||||
verify { navController wasNot Called }
|
||||
verify { out wasNot Called }
|
||||
|
||||
assertTrue(processor.process(testIntent("fenix://open?url=test"), navController, out))
|
||||
|
||||
verify {
|
||||
activity.openToBrowserAndLoad(
|
||||
"test",
|
||||
newTab = true,
|
||||
from = BrowserDirection.FromGlobal
|
||||
)
|
||||
}
|
||||
verify { navController wasNot Called }
|
||||
verify { out wasNot Called }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `process make_default_browser deep link`() {
|
||||
assertTrue(processor.process(testIntent("fenix://make_default_browser"), navController, out))
|
||||
|
||||
verify { navController wasNot Called }
|
||||
verify { out wasNot Called }
|
||||
}
|
||||
|
||||
private fun testIntent(uri: String) = Intent("", uri.toUri())
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/* 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.home.intent
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.navigation.NavController
|
||||
import io.mockk.Called
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.ObsoleteCoroutinesApi
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.BrowserDirection
|
||||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.TestApplication
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@ObsoleteCoroutinesApi
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(application = TestApplication::class)
|
||||
class OpenBrowserIntentProcessorTest {
|
||||
|
||||
@Test
|
||||
fun `do not process blank intents`() {
|
||||
val activity: HomeActivity = mockk()
|
||||
val navController: NavController = mockk()
|
||||
val out: Intent = mockk()
|
||||
val processor = OpenBrowserIntentProcessor(activity) { null }
|
||||
processor.process(Intent(), navController, out)
|
||||
|
||||
verify { activity wasNot Called }
|
||||
verify { navController wasNot Called }
|
||||
verify { out wasNot Called }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `do not process when open extra is false`() {
|
||||
val activity: HomeActivity = mockk()
|
||||
val navController: NavController = mockk()
|
||||
val out: Intent = mockk()
|
||||
val intent = Intent().apply {
|
||||
putExtra(HomeActivity.OPEN_TO_BROWSER, false)
|
||||
}
|
||||
val processor = OpenBrowserIntentProcessor(activity) { null }
|
||||
processor.process(intent, navController, out)
|
||||
|
||||
verify { activity wasNot Called }
|
||||
verify { navController wasNot Called }
|
||||
verify { out wasNot Called }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `process when open extra is true`() {
|
||||
val activity: HomeActivity = mockk(relaxed = true)
|
||||
val navController: NavController = mockk()
|
||||
val out: Intent = mockk(relaxed = true)
|
||||
val intent = Intent().apply {
|
||||
putExtra(HomeActivity.OPEN_TO_BROWSER, true)
|
||||
}
|
||||
val processor = OpenBrowserIntentProcessor(activity) { "session-id" }
|
||||
processor.process(intent, navController, out)
|
||||
|
||||
verify { activity.openToBrowser(BrowserDirection.FromGlobal, "session-id") }
|
||||
verify { navController wasNot Called }
|
||||
verify { out.putExtra(HomeActivity.OPEN_TO_BROWSER, false) }
|
||||
}
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
/* 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.home.intent
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.navigation.NavController
|
||||
import io.mockk.Called
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.ObsoleteCoroutinesApi
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.BrowserDirection
|
||||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.IntentReceiverActivity
|
||||
import org.mozilla.fenix.TestApplication
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@ObsoleteCoroutinesApi
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(application = TestApplication::class)
|
||||
class SpeechProcessingIntentProcessorTest {
|
||||
|
||||
@Test
|
||||
fun `do not process blank intents`() {
|
||||
val activity: HomeActivity = mockk()
|
||||
val navController: NavController = mockk()
|
||||
val out: Intent = mockk()
|
||||
val processor = SpeechProcessingIntentProcessor(activity)
|
||||
processor.process(Intent(), navController, out)
|
||||
|
||||
verify { activity wasNot Called }
|
||||
verify { navController wasNot Called }
|
||||
verify { out wasNot Called }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `do not process when open extra is false`() {
|
||||
val activity: HomeActivity = mockk()
|
||||
val navController: NavController = mockk()
|
||||
val out: Intent = mockk()
|
||||
val intent = Intent().apply {
|
||||
putExtra(HomeActivity.OPEN_TO_BROWSER_AND_LOAD, false)
|
||||
}
|
||||
val processor = SpeechProcessingIntentProcessor(activity)
|
||||
processor.process(intent, navController, out)
|
||||
|
||||
verify { activity wasNot Called }
|
||||
verify { navController wasNot Called }
|
||||
verify { out wasNot Called }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `process when open extra is true`() {
|
||||
val activity: HomeActivity = mockk(relaxed = true)
|
||||
val navController: NavController = mockk()
|
||||
val out: Intent = mockk(relaxed = true)
|
||||
val intent = Intent().apply {
|
||||
putExtra(HomeActivity.OPEN_TO_BROWSER_AND_LOAD, true)
|
||||
}
|
||||
val processor = SpeechProcessingIntentProcessor(activity)
|
||||
processor.process(intent, navController, out)
|
||||
|
||||
verify {
|
||||
activity.openToBrowserAndLoad(
|
||||
searchTermOrURL = "",
|
||||
newTab = true,
|
||||
from = BrowserDirection.FromGlobal,
|
||||
forceSearch = true
|
||||
)
|
||||
}
|
||||
verify { navController wasNot Called }
|
||||
verify { out.putExtra(HomeActivity.OPEN_TO_BROWSER_AND_LOAD, false) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `reads the speech processing extra`() {
|
||||
val activity: HomeActivity = mockk(relaxed = true)
|
||||
val intent = Intent().apply {
|
||||
putExtra(HomeActivity.OPEN_TO_BROWSER_AND_LOAD, true)
|
||||
putExtra(IntentReceiverActivity.SPEECH_PROCESSING, "hello world")
|
||||
}
|
||||
val processor = SpeechProcessingIntentProcessor(activity)
|
||||
processor.process(intent, mockk(), mockk(relaxed = true))
|
||||
|
||||
verify {
|
||||
activity.openToBrowserAndLoad(
|
||||
searchTermOrURL = "hello world",
|
||||
newTab = true,
|
||||
from = BrowserDirection.FromGlobal,
|
||||
forceSearch = true
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/* 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.home.intent
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.navigation.NavController
|
||||
import io.mockk.Called
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.ObsoleteCoroutinesApi
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.NavGraphDirections
|
||||
import org.mozilla.fenix.TestApplication
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.components.metrics.MetricController
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@ObsoleteCoroutinesApi
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(application = TestApplication::class)
|
||||
class StartSearchIntentProcessorTest {
|
||||
|
||||
@Test
|
||||
fun `do not process blank intents`() {
|
||||
val metrics: MetricController = mockk()
|
||||
val navController: NavController = mockk()
|
||||
val out: Intent = mockk()
|
||||
StartSearchIntentProcessor(metrics).process(Intent(), navController, out)
|
||||
|
||||
verify { metrics wasNot Called }
|
||||
verify { navController wasNot Called }
|
||||
verify { out wasNot Called }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `do not process when search extra is false`() {
|
||||
val metrics: MetricController = mockk()
|
||||
val navController: NavController = mockk()
|
||||
val out: Intent = mockk()
|
||||
val intent = Intent().apply {
|
||||
putExtra(HomeActivity.OPEN_TO_SEARCH, false)
|
||||
}
|
||||
StartSearchIntentProcessor(metrics).process(intent, navController, out)
|
||||
|
||||
verify { metrics wasNot Called }
|
||||
verify { navController wasNot Called }
|
||||
verify { out wasNot Called }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `process search intents`() {
|
||||
val metrics: MetricController = mockk(relaxed = true)
|
||||
val navController: NavController = mockk(relaxed = true)
|
||||
val out: Intent = mockk(relaxed = true)
|
||||
val intent = Intent().apply {
|
||||
putExtra(HomeActivity.OPEN_TO_SEARCH, true)
|
||||
}
|
||||
StartSearchIntentProcessor(metrics).process(intent, navController, out)
|
||||
|
||||
verify { metrics.track(Event.SearchWidgetNewTabPressed) }
|
||||
verify {
|
||||
navController.navigate(
|
||||
NavGraphDirections.actionGlobalSearch(sessionId = null, showShortcutEnginePicker = true)
|
||||
)
|
||||
}
|
||||
verify { out.putExtra(HomeActivity.OPEN_TO_SEARCH, false) }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user