1
0
Fork 0

For #6846: Added quick actions for nav bar in home

master
ekager 2020-07-24 20:55:32 -04:00 committed by Emily Kager
parent 1d604d327c
commit e5e62fa79a
8 changed files with 307 additions and 97 deletions

View File

@ -4,19 +4,12 @@
package org.mozilla.fenix.components.toolbar package org.mozilla.fenix.components.toolbar
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.PopupWindow
import androidx.annotation.LayoutRes import androidx.annotation.LayoutRes
import androidx.annotation.VisibleForTesting
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
@ -24,28 +17,25 @@ import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_
import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED
import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.extensions.LayoutContainer import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.browser_toolbar_popup_window.view.*
import kotlinx.android.synthetic.main.component_browser_top_toolbar.* import kotlinx.android.synthetic.main.component_browser_top_toolbar.*
import kotlinx.android.synthetic.main.component_browser_top_toolbar.view.* import kotlinx.android.synthetic.main.component_browser_top_toolbar.view.*
import mozilla.components.browser.domains.autocomplete.ShippedDomainsProvider import mozilla.components.browser.domains.autocomplete.ShippedDomainsProvider
import mozilla.components.browser.session.Session import mozilla.components.browser.session.Session
import mozilla.components.browser.state.selector.selectedTab
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.browser.toolbar.BrowserToolbar import mozilla.components.browser.toolbar.BrowserToolbar
import mozilla.components.browser.toolbar.behavior.BrowserToolbarBottomBehavior import mozilla.components.browser.toolbar.behavior.BrowserToolbarBottomBehavior
import mozilla.components.browser.toolbar.display.DisplayToolbar import mozilla.components.browser.toolbar.display.DisplayToolbar
import mozilla.components.support.ktx.android.util.dpToFloat import mozilla.components.support.ktx.android.util.dpToFloat
import mozilla.components.support.utils.URLStringUtils import mozilla.components.support.utils.URLStringUtils
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.customtabs.CustomTabToolbarIntegration import org.mozilla.fenix.customtabs.CustomTabToolbarIntegration
import org.mozilla.fenix.customtabs.CustomTabToolbarMenu import org.mozilla.fenix.customtabs.CustomTabToolbarMenu
import org.mozilla.fenix.ext.bookmarkStorage import org.mozilla.fenix.ext.bookmarkStorage
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.theme.ThemeManager import org.mozilla.fenix.theme.ThemeManager
import org.mozilla.fenix.utils.ToolbarPopupWindow
import java.lang.ref.WeakReference
interface BrowserToolbarViewInteractor { interface BrowserToolbarViewInteractor {
fun onBrowserToolbarPaste(text: String) fun onBrowserToolbarPaste(text: String)
@ -90,56 +80,12 @@ class BrowserToolbarView(
val isCustomTabSession = customTabSession != null val isCustomTabSession = customTabSession != null
view.display.setOnUrlLongClickListener { view.display.setOnUrlLongClickListener {
val clipboard = view.context.components.clipboardHandler ToolbarPopupWindow.show(
val customView = LayoutInflater.from(view.context) WeakReference(view),
.inflate(R.layout.browser_toolbar_popup_window, null) customTabSession,
val popupWindow = PopupWindow( interactor::onBrowserToolbarPasteAndGo,
customView, interactor::onBrowserToolbarPaste
LinearLayout.LayoutParams.WRAP_CONTENT,
view.context.resources.getDimensionPixelSize(R.dimen.context_menu_height),
true
) )
popupWindow.elevation =
view.context.resources.getDimension(R.dimen.mozac_browser_menu_elevation)
// This is a workaround for SDK<23 to allow popup dismissal on outside or back button press
// See: https://github.com/mozilla-mobile/fenix/issues/10027
popupWindow.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
customView.paste.isVisible = !clipboard.text.isNullOrEmpty() && !isCustomTabSession
customView.paste_and_go.isVisible =
!clipboard.text.isNullOrEmpty() && !isCustomTabSession
customView.copy.setOnClickListener {
popupWindow.dismiss()
clipboard.text = getUrlForClipboard(it.context.components.core.store, customTabSession)
FenixSnackbar.make(
view = view,
duration = Snackbar.LENGTH_SHORT,
isDisplayedWithBrowserToolbar = true
)
.setText(view.context.getString(R.string.browser_toolbar_url_copied_to_clipboard_snackbar))
.show()
}
customView.paste.setOnClickListener {
popupWindow.dismiss()
interactor.onBrowserToolbarPaste(clipboard.text!!)
}
customView.paste_and_go.setOnClickListener {
popupWindow.dismiss()
interactor.onBrowserToolbarPasteAndGo(clipboard.text!!)
}
popupWindow.showAsDropDown(
view,
view.context.resources.getDimensionPixelSize(R.dimen.context_menu_x_offset),
0,
Gravity.START
)
true true
} }
@ -286,9 +232,9 @@ class BrowserToolbarView(
0 0
} else { } else {
SCROLL_FLAG_SCROLL or SCROLL_FLAG_SCROLL or
SCROLL_FLAG_ENTER_ALWAYS or SCROLL_FLAG_ENTER_ALWAYS or
SCROLL_FLAG_SNAP or SCROLL_FLAG_SNAP or
SCROLL_FLAG_EXIT_UNTIL_COLLAPSED SCROLL_FLAG_EXIT_UNTIL_COLLAPSED
} }
} }
} }
@ -297,15 +243,5 @@ class BrowserToolbarView(
companion object { companion object {
private const val TOOLBAR_ELEVATION = 16 private const val TOOLBAR_ELEVATION = 16
@VisibleForTesting
internal fun getUrlForClipboard(store: BrowserStore, customTabSession: Session? = null): String? {
return if (customTabSession != null) {
customTabSession.url
} else {
val selectedTab = store.state.selectedTab
selectedTab?.readerState?.activeUrl ?: selectedTab?.content?.url
}
}
} }
} }

View File

@ -103,6 +103,7 @@ import org.mozilla.fenix.settings.SupportUtils.SumoTopic.HELP
import org.mozilla.fenix.settings.deletebrowsingdata.deleteAndQuit import org.mozilla.fenix.settings.deletebrowsingdata.deleteAndQuit
import org.mozilla.fenix.theme.ThemeManager import org.mozilla.fenix.theme.ThemeManager
import org.mozilla.fenix.utils.FragmentPreDrawManager import org.mozilla.fenix.utils.FragmentPreDrawManager
import org.mozilla.fenix.utils.ToolbarPopupWindow
import org.mozilla.fenix.utils.allowUndo import org.mozilla.fenix.utils.allowUndo
import org.mozilla.fenix.whatsnew.WhatsNew import org.mozilla.fenix.whatsnew.WhatsNew
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
@ -338,6 +339,16 @@ class HomeFragment : Fragment() {
requireComponents.analytics.metrics.track(Event.SearchBarTapped(Event.SearchBarTapped.Source.HOME)) requireComponents.analytics.metrics.track(Event.SearchBarTapped(Event.SearchBarTapped.Source.HOME))
} }
view.toolbar_wrapper.setOnLongClickListener {
ToolbarPopupWindow.show(
WeakReference(view),
handlePasteAndGo = sessionControlInteractor::onPasteAndGo,
handlePaste = sessionControlInteractor::onPaste,
copyVisible = false
)
true
}
view.tab_button.setOnClickListener { view.tab_button.setOnClickListener {
openTabTray() openTabTray()
} }
@ -465,7 +476,11 @@ class HomeFragment : Fragment() {
isSelected, isSelected,
engineSessionState = state engineSessionState = state
) )
findNavController().navigate(HomeFragmentDirections.actionHomeFragmentToBrowserFragment(null)) findNavController().navigate(
HomeFragmentDirections.actionHomeFragmentToBrowserFragment(
null
)
)
}, },
operation = { }, operation = { },
anchorView = snackbarAnchorView anchorView = snackbarAnchorView

View File

@ -15,6 +15,7 @@ import mozilla.components.feature.tab.collections.TabCollection
import mozilla.components.feature.tab.collections.ext.restore import mozilla.components.feature.tab.collections.ext.restore
import mozilla.components.feature.tabs.TabsUseCases import mozilla.components.feature.tabs.TabsUseCases
import mozilla.components.feature.top.sites.TopSite import mozilla.components.feature.top.sites.TopSite
import mozilla.components.support.ktx.kotlin.isUrl
import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
@ -24,9 +25,13 @@ import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.TopSiteStorage import org.mozilla.fenix.components.TopSiteStorage
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.components.metrics.MetricsUtils
import org.mozilla.fenix.components.tips.Tip import org.mozilla.fenix.components.tips.Tip
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.metrics
import org.mozilla.fenix.ext.nav import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.sessionsOfType import org.mozilla.fenix.ext.sessionsOfType
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.home.HomeFragment import org.mozilla.fenix.home.HomeFragment
import org.mozilla.fenix.home.HomeFragmentAction import org.mozilla.fenix.home.HomeFragmentAction
import org.mozilla.fenix.home.HomeFragmentDirections import org.mozilla.fenix.home.HomeFragmentDirections
@ -120,8 +125,21 @@ interface SessionControlController {
*/ */
fun handleToggleCollectionExpanded(collection: TabCollection, expand: Boolean) fun handleToggleCollectionExpanded(collection: TabCollection, expand: Boolean)
/**
* @see [TipInteractor.onCloseTip]
*/
fun handleCloseTip(tip: Tip) fun handleCloseTip(tip: Tip)
/**
* @see [ToolbarInteractor.onPasteAndGo]
*/
fun handlePasteAndGo(clipboardText: String)
/**
* @see [ToolbarInteractor.onPaste]
*/
fun handlePaste(clipboardText: String)
/** /**
* @see [CollectionInteractor.onAddTabsToCollectionTapped] * @see [CollectionInteractor.onAddTabsToCollectionTapped]
*/ */
@ -347,4 +365,37 @@ class DefaultSessionControlController(
) )
navController.nav(R.id.homeFragment, directions) navController.nav(R.id.homeFragment, directions)
} }
override fun handlePasteAndGo(clipboardText: String) {
activity.openToBrowserAndLoad(
searchTermOrURL = clipboardText,
newTab = true,
from = BrowserDirection.FromHome,
engine = activity.components.search.provider.getDefaultEngine(activity)
)
val event = if (clipboardText.isUrl()) {
Event.EnteredUrl(false)
} else {
val searchAccessPoint = Event.PerformedSearch.SearchAccessPoint.ACTION
activity.settings().incrementActiveSearchCount()
searchAccessPoint.let { sap ->
MetricsUtils.createSearchEvent(
activity.components.search.provider.getDefaultEngine(activity),
activity,
sap
)
}
}
event?.let { activity.metrics.track(it) }
}
override fun handlePaste(clipboardText: String) {
val directions = HomeFragmentDirections.actionGlobalSearch(
sessionId = null,
pastedText = clipboardText
)
navController.nav(R.id.homeFragment, directions)
}
} }

View File

@ -95,6 +95,18 @@ interface CollectionInteractor {
fun onAddTabsToCollectionTapped() fun onAddTabsToCollectionTapped()
} }
interface ToolbarInteractor {
/**
* Navigates to browser with clipboard text.
*/
fun onPasteAndGo(clipboardText: String)
/**
* Navigates to search with clipboard text.
*/
fun onPaste(clipboardText: String)
}
/** /**
* Interface for onboarding related actions in the [SessionControlInteractor]. * Interface for onboarding related actions in the [SessionControlInteractor].
*/ */
@ -163,7 +175,8 @@ interface TopSiteInteractor {
@SuppressWarnings("TooManyFunctions") @SuppressWarnings("TooManyFunctions")
class SessionControlInteractor( class SessionControlInteractor(
private val controller: SessionControlController private val controller: SessionControlController
) : CollectionInteractor, OnboardingInteractor, TopSiteInteractor, TipInteractor, TabSessionInteractor { ) : CollectionInteractor, OnboardingInteractor, TopSiteInteractor, TipInteractor,
TabSessionInteractor, ToolbarInteractor {
override fun onCollectionAddTabTapped(collection: TabCollection) { override fun onCollectionAddTabTapped(collection: TabCollection) {
controller.handleCollectionAddTabTapped(collection) controller.handleCollectionAddTabTapped(collection)
} }
@ -235,4 +248,12 @@ class SessionControlInteractor(
override fun onPrivateBrowsingLearnMoreClicked() { override fun onPrivateBrowsingLearnMoreClicked() {
controller.handlePrivateBrowsingLearnMoreClicked() controller.handlePrivateBrowsingLearnMoreClicked()
} }
override fun onPasteAndGo(clipboardText: String) {
controller.handlePasteAndGo(clipboardText)
}
override fun onPaste(clipboardText: String) {
controller.handlePaste(clipboardText)
}
} }

View File

@ -0,0 +1,108 @@
/* 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.utils
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.widget.LinearLayout
import android.widget.PopupWindow
import androidx.annotation.VisibleForTesting
import androidx.core.view.isVisible
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.browser_toolbar_popup_window.view.*
import mozilla.components.browser.session.Session
import mozilla.components.browser.state.selector.selectedTab
import mozilla.components.browser.state.store.BrowserStore
import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.ext.components
import java.lang.ref.WeakReference
object ToolbarPopupWindow {
fun show(
view: WeakReference<View>,
customTabSession: Session? = null,
handlePasteAndGo: (String) -> Unit,
handlePaste: (String) -> Unit,
copyVisible: Boolean = true
) {
val context = view.get()?.context ?: return
val isCustomTabSession = customTabSession != null
val clipboard = context.components.clipboardHandler
val customView = LayoutInflater.from(context)
.inflate(R.layout.browser_toolbar_popup_window, null)
val popupWindow = PopupWindow(
customView,
LinearLayout.LayoutParams.WRAP_CONTENT,
context.resources.getDimensionPixelSize(R.dimen.context_menu_height),
true
)
popupWindow.elevation =
context.resources.getDimension(R.dimen.mozac_browser_menu_elevation)
// This is a workaround for SDK<23 to allow popup dismissal on outside or back button press
// See: https://github.com/mozilla-mobile/fenix/issues/10027
popupWindow.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
customView.copy.isVisible = copyVisible
customView.paste.isVisible = !clipboard.text.isNullOrEmpty() && !isCustomTabSession
customView.paste_and_go.isVisible =
!clipboard.text.isNullOrEmpty() && !isCustomTabSession
customView.copy.setOnClickListener {
popupWindow.dismiss()
clipboard.text = getUrlForClipboard(
it.context.components.core.store,
customTabSession
)
view.get()?.let {
FenixSnackbar.make(
view = it,
duration = Snackbar.LENGTH_SHORT,
isDisplayedWithBrowserToolbar = true
)
.setText(context.getString(R.string.browser_toolbar_url_copied_to_clipboard_snackbar))
.show()
}
}
customView.paste.setOnClickListener {
popupWindow.dismiss()
handlePaste(clipboard.text!!)
}
customView.paste_and_go.setOnClickListener {
popupWindow.dismiss()
handlePasteAndGo(clipboard.text!!)
}
view.get()?.let {
popupWindow.showAsDropDown(
it,
context.resources.getDimensionPixelSize(R.dimen.context_menu_x_offset),
0,
Gravity.START
)
}
}
@VisibleForTesting
internal fun getUrlForClipboard(
store: BrowserStore,
customTabSession: Session? = null
): String? {
return if (customTabSession != null) {
customTabSession.url
} else {
val selectedTab = store.state.selectedTab
selectedTab?.readerState?.activeUrl ?: selectedTab?.content?.url
}
}
}

View File

@ -12,8 +12,9 @@ import io.mockk.verify
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestCoroutineDispatcher import kotlinx.coroutines.test.TestCoroutineDispatcher
import kotlinx.coroutines.test.TestCoroutineScope import kotlinx.coroutines.test.TestCoroutineScope
import mozilla.components.browser.search.SearchEngine
import mozilla.components.browser.search.SearchEngineManager
import mozilla.components.browser.session.SessionManager import mozilla.components.browser.session.SessionManager
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.Engine import mozilla.components.concept.engine.Engine
import mozilla.components.feature.tab.collections.TabCollection import mozilla.components.feature.tab.collections.TabCollection
import mozilla.components.feature.tabs.TabsUseCases import mozilla.components.feature.tabs.TabsUseCases
@ -24,13 +25,19 @@ import org.junit.Test
import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.Analytics
import org.mozilla.fenix.components.TabCollectionStorage import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.TopSiteStorage import org.mozilla.fenix.components.TopSiteStorage
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.components.tips.Tip import org.mozilla.fenix.components.tips.Tip
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.metrics
import org.mozilla.fenix.ext.searchEngineManager
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.home.sessioncontrol.DefaultSessionControlController import org.mozilla.fenix.home.sessioncontrol.DefaultSessionControlController
import org.mozilla.fenix.settings.SupportUtils import org.mozilla.fenix.settings.SupportUtils
import org.mozilla.fenix.utils.Settings
import mozilla.components.feature.tab.collections.Tab as ComponentTab import mozilla.components.feature.tab.collections.Tab as ComponentTab
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
@ -44,7 +51,6 @@ class DefaultSessionControlControllerTest {
private val navController: NavController = mockk(relaxed = true) private val navController: NavController = mockk(relaxed = true)
private val metrics: MetricController = mockk(relaxed = true) private val metrics: MetricController = mockk(relaxed = true)
private val sessionManager: SessionManager = mockk(relaxed = true) private val sessionManager: SessionManager = mockk(relaxed = true)
private val store: BrowserStore = mockk(relaxed = true)
private val engine: Engine = mockk(relaxed = true) private val engine: Engine = mockk(relaxed = true)
private val tabCollectionStorage: TabCollectionStorage = mockk(relaxed = true) private val tabCollectionStorage: TabCollectionStorage = mockk(relaxed = true)
private val topSiteStorage: TopSiteStorage = mockk(relaxed = true) private val topSiteStorage: TopSiteStorage = mockk(relaxed = true)
@ -55,6 +61,10 @@ class DefaultSessionControlControllerTest {
private val showTabTray: () -> Unit = mockk(relaxed = true) private val showTabTray: () -> Unit = mockk(relaxed = true)
private val showDeleteCollectionPrompt: (tabCollection: TabCollection, title: String?, message: String) -> Unit = private val showDeleteCollectionPrompt: (tabCollection: TabCollection, title: String?, message: String) -> Unit =
mockk(relaxed = true) mockk(relaxed = true)
private val searchEngine = mockk<SearchEngine>(relaxed = true)
private val searchEngineManager = mockk<SearchEngineManager>(relaxed = true)
private val settings: Settings = mockk(relaxed = true)
private val analytics: Analytics = mockk(relaxed = true)
private lateinit var controller: DefaultSessionControlController private lateinit var controller: DefaultSessionControlController
@ -70,6 +80,13 @@ class DefaultSessionControlControllerTest {
every { navController.currentDestination } returns mockk { every { navController.currentDestination } returns mockk {
every { id } returns R.id.homeFragment every { id } returns R.id.homeFragment
} }
every { activity.components.settings } returns settings
every { activity.components.search.provider.getDefaultEngine(activity) } returns searchEngine
every { activity.settings() } returns settings
every { activity.searchEngineManager } returns searchEngineManager
every { searchEngineManager.defaultSearchEngine } returns searchEngine
every { activity.components.analytics } returns analytics
every { analytics.metrics } returns metrics
controller = DefaultSessionControlController( controller = DefaultSessionControlController(
activity = activity, activity = activity,
@ -155,7 +172,10 @@ class DefaultSessionControlControllerTest {
} }
val tab = mockk<ComponentTab>() val tab = mockk<ComponentTab>()
every { every {
activity.resources.getString(R.string.delete_tab_and_collection_dialog_title, "Collection") activity.resources.getString(
R.string.delete_tab_and_collection_dialog_title,
"Collection"
)
} returns "Delete Collection?" } returns "Delete Collection?"
every { every {
activity.resources.getString(R.string.delete_tab_and_collection_dialog_message) activity.resources.getString(R.string.delete_tab_and_collection_dialog_message)
@ -252,11 +272,13 @@ class DefaultSessionControlControllerTest {
controller.handleSelectTopSite(topSiteUrl, true) controller.handleSelectTopSite(topSiteUrl, true)
verify { metrics.track(Event.TopSiteOpenInNewTab) } verify { metrics.track(Event.TopSiteOpenInNewTab) }
verify { metrics.track(Event.TopSiteOpenDefault) } verify { metrics.track(Event.TopSiteOpenDefault) }
verify { tabsUseCases.addTab.invoke( verify {
topSiteUrl, tabsUseCases.addTab.invoke(
selectTab = true, topSiteUrl,
startLoading = true selectTab = true,
) } startLoading = true
)
}
verify { activity.openToBrowser(BrowserDirection.FromHome) } verify { activity.openToBrowser(BrowserDirection.FromHome) }
} }
@ -266,11 +288,13 @@ class DefaultSessionControlControllerTest {
controller.handleSelectTopSite(topSiteUrl, false) controller.handleSelectTopSite(topSiteUrl, false)
verify { metrics.track(Event.TopSiteOpenInNewTab) } verify { metrics.track(Event.TopSiteOpenInNewTab) }
verify { tabsUseCases.addTab.invoke( verify {
topSiteUrl, tabsUseCases.addTab.invoke(
selectTab = true, topSiteUrl,
startLoading = true selectTab = true,
) } startLoading = true
)
}
verify { activity.openToBrowser(BrowserDirection.FromHome) } verify { activity.openToBrowser(BrowserDirection.FromHome) }
} }
@ -341,4 +365,43 @@ class DefaultSessionControlControllerTest {
) )
} }
} }
@Test
fun handlePasteAndGo() {
controller.handlePasteAndGo("text")
verify {
activity.openToBrowserAndLoad(
searchTermOrURL = "text",
newTab = true,
from = BrowserDirection.FromHome,
engine = searchEngine
)
settings.incrementActiveSearchCount()
metrics.track(any<Event.PerformedSearch>())
}
controller.handlePasteAndGo("https://mozilla.org")
verify {
activity.openToBrowserAndLoad(
searchTermOrURL = "https://mozilla.org",
newTab = true,
from = BrowserDirection.FromHome,
engine = searchEngine
)
metrics.track(any<Event.EnteredUrl>())
}
}
@Test
fun handlePaste() {
controller.handlePaste("text")
verify {
navController.navigate(
match<NavDirections> { it.actionId == R.id.action_global_search },
null
)
}
}
} }

View File

@ -98,4 +98,16 @@ class SessionControlInteractorTest {
interactor.onAddTabsToCollectionTapped() interactor.onAddTabsToCollectionTapped()
verify { controller.handleCreateCollection() } verify { controller.handleCreateCollection() }
} }
@Test
fun onPaste() {
interactor.onPaste("text")
verify { controller.handlePaste("text") }
}
@Test
fun onPasteAndGo() {
interactor.onPasteAndGo("text")
verify { controller.handlePasteAndGo("text") }
}
} }

View File

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.components.toolbar package org.mozilla.fenix.utils
import io.mockk.every import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
@ -14,11 +14,10 @@ import mozilla.components.browser.state.store.BrowserStore
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mozilla.fenix.components.toolbar.BrowserToolbarView.Companion.getUrlForClipboard
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@RunWith(FenixRobolectricTestRunner::class) @RunWith(FenixRobolectricTestRunner::class)
class BrowserToolbarViewTest { class ToolbarPopupWindowTest {
@Test @Test
fun getUrlForClipboard() { fun getUrlForClipboard() {
@ -26,18 +25,23 @@ class BrowserToolbarViewTest {
every { customTabSession.url } returns "https://mozilla.org" every { customTabSession.url } returns "https://mozilla.org"
// Custom tab // Custom tab
assertEquals("https://mozilla.org", getUrlForClipboard(mockk(), customTabSession)) assertEquals(
"https://mozilla.org",
ToolbarPopupWindow.getUrlForClipboard(mockk(), customTabSession)
)
// Regular tab // Regular tab
val regularTab = createTab(url = "http://firefox.com") val regularTab = createTab(url = "http://firefox.com")
var store = BrowserStore(BrowserState(tabs = listOf(regularTab), selectedTabId = regularTab.id)) var store =
assertEquals(regularTab.content.url, getUrlForClipboard(store)) BrowserStore(BrowserState(tabs = listOf(regularTab), selectedTabId = regularTab.id))
assertEquals(regularTab.content.url, ToolbarPopupWindow.getUrlForClipboard(store))
// Reader Tab // Reader Tab
val readerTab = createTab(url = "moz-extension://1234", val readerTab = createTab(
url = "moz-extension://1234",
readerState = ReaderState(active = true, activeUrl = "https://blog.mozilla.org/123") readerState = ReaderState(active = true, activeUrl = "https://blog.mozilla.org/123")
) )
store = BrowserStore(BrowserState(tabs = listOf(readerTab), selectedTabId = readerTab.id)) store = BrowserStore(BrowserState(tabs = listOf(readerTab), selectedTabId = readerTab.id))
assertEquals(readerTab.readerState.activeUrl, getUrlForClipboard(store)) assertEquals(readerTab.readerState.activeUrl, ToolbarPopupWindow.getUrlForClipboard(store))
} }
} }