You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
891 lines
39 KiB
Kotlin
891 lines
39 KiB
Kotlin
/* 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.search.toolbar
|
|
|
|
import android.content.Context
|
|
import android.graphics.Bitmap
|
|
import androidx.appcompat.view.ContextThemeWrapper
|
|
import androidx.core.graphics.drawable.toBitmap
|
|
import io.mockk.MockKAnnotations
|
|
import io.mockk.every
|
|
import io.mockk.impl.annotations.MockK
|
|
import io.mockk.mockk
|
|
import io.mockk.mockkConstructor
|
|
import io.mockk.mockkObject
|
|
import io.mockk.spyk
|
|
import io.mockk.verify
|
|
import mozilla.components.browser.domains.autocomplete.BaseDomainAutocompleteProvider
|
|
import mozilla.components.browser.state.search.SearchEngine
|
|
import mozilla.components.browser.state.state.SearchState
|
|
import mozilla.components.browser.state.state.searchEngines
|
|
import mozilla.components.browser.storage.sync.PlacesBookmarksStorage
|
|
import mozilla.components.browser.storage.sync.PlacesHistoryStorage
|
|
import mozilla.components.browser.toolbar.BrowserToolbar
|
|
import mozilla.components.concept.toolbar.Toolbar
|
|
import mozilla.components.feature.awesomebar.provider.SessionAutocompleteProvider
|
|
import mozilla.components.feature.syncedtabs.SyncedTabsAutocompleteProvider
|
|
import mozilla.components.feature.toolbar.ToolbarAutocompleteFeature
|
|
import mozilla.components.support.test.robolectric.testContext
|
|
import mozilla.components.ui.autocomplete.InlineAutocompleteEditText
|
|
import org.junit.Assert.assertEquals
|
|
import org.junit.Assert.assertFalse
|
|
import org.junit.Assert.assertNotNull
|
|
import org.junit.Assert.assertNull
|
|
import org.junit.Assert.assertTrue
|
|
import org.junit.Before
|
|
import org.junit.Test
|
|
import org.junit.runner.RunWith
|
|
import org.mozilla.fenix.FeatureFlags
|
|
import org.mozilla.fenix.R
|
|
import org.mozilla.fenix.components.Components
|
|
import org.mozilla.fenix.components.Core
|
|
import org.mozilla.fenix.components.metrics.MetricsUtils
|
|
import org.mozilla.fenix.ext.requireComponents
|
|
import org.mozilla.fenix.ext.settings
|
|
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
|
import org.mozilla.fenix.search.SearchDialogFragment
|
|
import org.mozilla.fenix.search.SearchEngineSource
|
|
import org.mozilla.fenix.search.SearchFragmentState
|
|
import org.mozilla.fenix.utils.Settings
|
|
import java.util.UUID
|
|
|
|
@RunWith(FenixRobolectricTestRunner::class)
|
|
class ToolbarViewTest {
|
|
@MockK(relaxed = true)
|
|
private lateinit var interactor: ToolbarInteractor
|
|
|
|
private lateinit var context: Context
|
|
private lateinit var toolbar: BrowserToolbar
|
|
private val defaultState: SearchFragmentState = SearchFragmentState(
|
|
tabId = null,
|
|
url = "",
|
|
searchTerms = "",
|
|
query = "",
|
|
searchEngineSource = SearchEngineSource.Default(
|
|
mockk {
|
|
every { name } returns "Search Engine"
|
|
every { icon } returns testContext.getDrawable(R.drawable.ic_search)!!.toBitmap()
|
|
every { type } returns SearchEngine.Type.BUNDLED
|
|
every { isGeneral } returns true
|
|
},
|
|
),
|
|
defaultEngine = null,
|
|
showSearchTermHistory = true,
|
|
showSearchShortcutsSetting = false,
|
|
showSearchSuggestionsHint = false,
|
|
showSearchSuggestions = false,
|
|
showSearchShortcuts = false,
|
|
areShortcutsAvailable = true,
|
|
showClipboardSuggestions = false,
|
|
showHistorySuggestionsForCurrentEngine = true,
|
|
showAllHistorySuggestions = false,
|
|
showBookmarksSuggestionsForCurrentEngine = false,
|
|
showAllBookmarkSuggestions = false,
|
|
showSyncedTabsSuggestionsForCurrentEngine = false,
|
|
showAllSyncedTabsSuggestions = false,
|
|
showSessionSuggestionsForCurrentEngine = false,
|
|
showAllSessionSuggestions = false,
|
|
showSponsoredSuggestions = false,
|
|
showNonSponsoredSuggestions = false,
|
|
searchAccessPoint = MetricsUtils.Source.NONE,
|
|
)
|
|
|
|
@Before
|
|
fun setup() {
|
|
MockKAnnotations.init(this)
|
|
context = ContextThemeWrapper(testContext, R.style.NormalTheme)
|
|
every { context.settings() } returns mockk(relaxed = true)
|
|
toolbar = spyk(BrowserToolbar(context))
|
|
}
|
|
|
|
@Test
|
|
fun `sets toolbar to normal mode`() {
|
|
buildToolbarView(isPrivate = false)
|
|
assertFalse(toolbar.private)
|
|
}
|
|
|
|
@Test
|
|
fun `sets toolbar to private mode`() {
|
|
buildToolbarView(isPrivate = true)
|
|
assertTrue(toolbar.private)
|
|
}
|
|
|
|
@Test
|
|
fun `View gets initialized only once`() {
|
|
val view = buildToolbarView(false)
|
|
assertFalse(view.isInitialized)
|
|
|
|
view.update(defaultState)
|
|
view.update(defaultState)
|
|
view.update(defaultState)
|
|
|
|
verify(exactly = 1) { toolbar.setSearchTerms(any()) }
|
|
|
|
assertTrue(view.isInitialized)
|
|
}
|
|
|
|
@Test
|
|
fun `search term updates the url`() {
|
|
val view = buildToolbarView(false)
|
|
|
|
view.update(defaultState)
|
|
view.update(defaultState)
|
|
view.update(defaultState)
|
|
|
|
// editMode gets called when the view is initialized.
|
|
verify(exactly = 2) { toolbar.editMode() }
|
|
// search term changes update the url and invoke the interactor.
|
|
verify(exactly = 2) { toolbar.url = any() }
|
|
verify(exactly = 2) { interactor.onTextChanged(any()) }
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN search term is set WHEN switching to edit mode THEN the cursor is set at the end of the search term`() {
|
|
every { context.settings().showUnifiedSearchFeature } returns true
|
|
every { context.settings().shouldShowHistorySuggestions } returns true
|
|
every { context.settings().shouldShowBookmarkSuggestions } returns true
|
|
every { context.settings().isTabletAndTabStripEnabled } returns false
|
|
every { context.settings().enableIncompleteToolbarRedesign } returns false
|
|
val view = buildToolbarView(false)
|
|
mockkObject(FeatureFlags)
|
|
|
|
view.update(defaultState.copy(searchTerms = "search terms"))
|
|
|
|
// editMode gets called when the view is initialized.
|
|
verify(exactly = 1) { toolbar.editMode(Toolbar.CursorPlacement.ALL) }
|
|
verify(exactly = 1) { toolbar.editMode(Toolbar.CursorPlacement.END) }
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN no search term is set WHEN switching to edit mode THEN the cursor is set at the end of the search term`() {
|
|
every { context.settings().showUnifiedSearchFeature } returns true
|
|
every { context.settings().shouldShowHistorySuggestions } returns true
|
|
every { context.settings().shouldShowBookmarkSuggestions } returns true
|
|
every { context.settings().isTabletAndTabStripEnabled } returns false
|
|
every { context.settings().enableIncompleteToolbarRedesign } returns false
|
|
val view = buildToolbarView(false)
|
|
mockkObject(FeatureFlags)
|
|
|
|
view.update(defaultState)
|
|
|
|
// editMode gets called when the view is initialized.
|
|
verify(exactly = 2) { toolbar.editMode(Toolbar.CursorPlacement.ALL) }
|
|
}
|
|
|
|
@Test
|
|
fun `URL gets set to the states query`() {
|
|
val toolbarView = buildToolbarView(false)
|
|
toolbarView.update(defaultState.copy(query = "Query"))
|
|
|
|
assertEquals("Query", toolbarView.view.url)
|
|
}
|
|
|
|
@Test
|
|
fun `URL gets set to the states pastedText if exists`() {
|
|
val toolbarView = buildToolbarView(false)
|
|
toolbarView.update(defaultState.copy(query = "Query", pastedText = "Pasted"))
|
|
|
|
assertEquals("Pasted", toolbarView.view.url)
|
|
}
|
|
|
|
@Test
|
|
fun `searchTerms get set if pastedText is null or empty`() {
|
|
val toolbarView = buildToolbarView(false)
|
|
toolbarView.update(defaultState.copy(query = "Query", pastedText = "", searchTerms = "Search Terms"))
|
|
|
|
verify { toolbar.setSearchTerms("Search Terms") }
|
|
}
|
|
|
|
@Test
|
|
fun `searchTerms don't get set if pastedText has a value`() {
|
|
val toolbarView = buildToolbarView(false)
|
|
toolbarView.update(
|
|
defaultState.copy(query = "Query", pastedText = "PastedText", searchTerms = "Search Terms"),
|
|
)
|
|
|
|
verify(exactly = 0) { toolbar.setSearchTerms("Search Terms") }
|
|
}
|
|
|
|
@Test
|
|
fun `WHEN the default general search engine is selected THEN show text for default engine`() {
|
|
val toolbarView = buildToolbarView(false)
|
|
val defaultEngine = buildSearchEngine(SearchEngine.Type.BUNDLED, true)
|
|
val fragment = spyk(SearchDialogFragment())
|
|
fragment.inlineAutocompleteEditText = InlineAutocompleteEditText(context)
|
|
val searchState = mockk<SearchState>()
|
|
val expectedHint = context.getString(R.string.search_hint)
|
|
val expectedContentDescription = defaultEngine.name + ", " + context.getString(R.string.search_hint)
|
|
|
|
every { fragment.requireContext().getString(R.string.search_hint) } returns expectedHint
|
|
every { searchState.userSelectedSearchEngineId } returns defaultEngine.id
|
|
every { searchState.searchEngines } returns listOf(defaultEngine)
|
|
every { fragment.toolbarView } returns toolbarView
|
|
every { fragment.requireComponents.core.store.state.search } returns searchState
|
|
|
|
fragment.updateToolbarContentDescription(defaultEngine, true)
|
|
|
|
assertEquals(expectedHint, fragment.inlineAutocompleteEditText.hint)
|
|
assertEquals(expectedContentDescription, toolbarView.view.contentDescription)
|
|
}
|
|
|
|
@Test
|
|
fun `WHEN a general search engine is selected THEN show hint for general engine`() {
|
|
val toolbarView = buildToolbarView(false)
|
|
val generalEngine = buildSearchEngine(SearchEngine.Type.BUNDLED, true)
|
|
val fragment = spyk(SearchDialogFragment())
|
|
fragment.inlineAutocompleteEditText = InlineAutocompleteEditText(context)
|
|
val searchState = mockk<SearchState>()
|
|
val expectedHint = context.getString(R.string.search_hint_general_engine)
|
|
val expectedContentDescription = generalEngine.name + ", " + context.getString(R.string.search_hint_general_engine)
|
|
|
|
every { fragment.requireContext().getString(R.string.search_hint_general_engine) } returns expectedHint
|
|
every { searchState.userSelectedSearchEngineId } returns generalEngine.id
|
|
every { searchState.searchEngines } returns listOf(generalEngine)
|
|
every { fragment.toolbarView } returns toolbarView
|
|
every { fragment.requireComponents.core.store.state.search } returns searchState
|
|
|
|
fragment.updateToolbarContentDescription(generalEngine, false)
|
|
|
|
assertEquals(expectedHint, fragment.inlineAutocompleteEditText.hint)
|
|
assertEquals(expectedContentDescription, toolbarView.view.contentDescription)
|
|
}
|
|
|
|
@Test
|
|
fun `WHEN a topic specific search engine is selected THEN show hint for topic specific engine`() {
|
|
val toolbarView = buildToolbarView(false)
|
|
val topicSpecificEngine = buildSearchEngine(SearchEngine.Type.BUNDLED, false)
|
|
val fragment = spyk(SearchDialogFragment())
|
|
fragment.inlineAutocompleteEditText = InlineAutocompleteEditText(context)
|
|
val searchState = mockk<SearchState>()
|
|
val expectedHint = context.getString(R.string.application_search_hint)
|
|
val expectedContentDescription = topicSpecificEngine.name + ", " + context.getString(R.string.application_search_hint)
|
|
|
|
every { fragment.requireContext().getString(R.string.application_search_hint) } returns expectedHint
|
|
every { searchState.userSelectedSearchEngineId } returns topicSpecificEngine.id
|
|
every { searchState.searchEngines } returns listOf(topicSpecificEngine)
|
|
every { fragment.toolbarView } returns toolbarView
|
|
every { fragment.requireComponents.core.store.state.search } returns searchState
|
|
|
|
fragment.updateToolbarContentDescription(topicSpecificEngine, false)
|
|
|
|
assertEquals(expectedHint, fragment.inlineAutocompleteEditText.hint)
|
|
assertEquals(expectedContentDescription, toolbarView.view.contentDescription)
|
|
}
|
|
|
|
@Test
|
|
fun `WHEN the default additional general search engine is selected THEN show hint for default engine`() {
|
|
val toolbarView = buildToolbarView(false)
|
|
val defaultEngine = buildSearchEngine(SearchEngine.Type.BUNDLED_ADDITIONAL, true)
|
|
val fragment = spyk(SearchDialogFragment())
|
|
fragment.inlineAutocompleteEditText = InlineAutocompleteEditText(context)
|
|
val searchState = mockk<SearchState>()
|
|
val expectedHint = context.getString(R.string.search_hint)
|
|
val expectedContentDescription = defaultEngine.name + ", " + context.getString(R.string.search_hint)
|
|
|
|
every { fragment.requireContext().getString(R.string.search_hint) } returns expectedHint
|
|
every { searchState.userSelectedSearchEngineId } returns defaultEngine.id
|
|
every { searchState.searchEngines } returns listOf(defaultEngine)
|
|
every { fragment.toolbarView } returns toolbarView
|
|
every { fragment.requireComponents.core.store.state.search } returns searchState
|
|
|
|
fragment.updateToolbarContentDescription(defaultEngine, true)
|
|
|
|
assertEquals(expectedHint, fragment.inlineAutocompleteEditText.hint)
|
|
assertEquals(expectedContentDescription, toolbarView.view.contentDescription)
|
|
}
|
|
|
|
@Test
|
|
fun `WHEN a general additional search engine is selected THEN show hint for general engine`() {
|
|
val toolbarView = buildToolbarView(false)
|
|
val generalEngine = buildSearchEngine(SearchEngine.Type.BUNDLED_ADDITIONAL, true)
|
|
val fragment = spyk(SearchDialogFragment())
|
|
fragment.inlineAutocompleteEditText = InlineAutocompleteEditText(context)
|
|
val searchState = mockk<SearchState>()
|
|
val expectedHint = context.getString(R.string.search_hint_general_engine)
|
|
val expectedContentDescription = generalEngine.name + ", " + context.getString(R.string.search_hint_general_engine)
|
|
|
|
every { fragment.requireContext().getString(R.string.search_hint_general_engine) } returns expectedHint
|
|
every { searchState.userSelectedSearchEngineId } returns generalEngine.id
|
|
every { searchState.searchEngines } returns listOf(generalEngine)
|
|
every { fragment.toolbarView } returns toolbarView
|
|
every { fragment.requireComponents.core.store.state.search } returns searchState
|
|
|
|
fragment.updateToolbarContentDescription(generalEngine, false)
|
|
|
|
assertEquals(expectedHint, fragment.inlineAutocompleteEditText.hint)
|
|
assertEquals(expectedContentDescription, toolbarView.view.contentDescription)
|
|
}
|
|
|
|
@Test
|
|
fun `WHEN the default custom search engine is selected THEN show hint for default engine`() {
|
|
val toolbarView = buildToolbarView(false)
|
|
val customEngine = buildSearchEngine(SearchEngine.Type.CUSTOM, true)
|
|
val fragment = spyk(SearchDialogFragment())
|
|
fragment.inlineAutocompleteEditText = InlineAutocompleteEditText(context)
|
|
val searchState = mockk<SearchState>()
|
|
val expectedHint = context.getString(R.string.search_hint)
|
|
val expectedContentDescription = customEngine.name + ", " + context.getString(R.string.search_hint)
|
|
|
|
every { fragment.requireContext().getString(R.string.search_hint) } returns expectedHint
|
|
every { searchState.userSelectedSearchEngineId } returns customEngine.id
|
|
every { searchState.searchEngines } returns listOf(customEngine)
|
|
every { fragment.toolbarView } returns toolbarView
|
|
every { fragment.requireComponents.core.store.state.search } returns searchState
|
|
|
|
fragment.updateToolbarContentDescription(customEngine, true)
|
|
|
|
assertEquals(expectedHint, fragment.inlineAutocompleteEditText.hint)
|
|
assertEquals(expectedContentDescription, toolbarView.view.contentDescription)
|
|
}
|
|
|
|
@Test
|
|
fun `WHEN a custom search engine is selected THEN show hint for general engine`() {
|
|
val toolbarView = buildToolbarView(false)
|
|
val customEngine = buildSearchEngine(SearchEngine.Type.CUSTOM, true)
|
|
val fragment = spyk(SearchDialogFragment())
|
|
fragment.inlineAutocompleteEditText = InlineAutocompleteEditText(context)
|
|
val searchState = mockk<SearchState>()
|
|
val expectedHint = context.getString(R.string.search_hint_general_engine)
|
|
val expectedContentDescription = customEngine.name + ", " + context.getString(R.string.search_hint_general_engine)
|
|
|
|
every { fragment.requireContext().getString(R.string.search_hint_general_engine) } returns expectedHint
|
|
every { searchState.userSelectedSearchEngineId } returns customEngine.id
|
|
every { searchState.searchEngines } returns listOf(customEngine)
|
|
every { fragment.toolbarView } returns toolbarView
|
|
every { fragment.requireComponents.core.store.state.search } returns searchState
|
|
|
|
fragment.updateToolbarContentDescription(customEngine, false)
|
|
|
|
assertEquals(expectedHint, fragment.inlineAutocompleteEditText.hint)
|
|
assertEquals(expectedContentDescription, toolbarView.view.contentDescription)
|
|
}
|
|
|
|
@Test
|
|
fun `WHEN history is selected as engine THEN show hint specific for history`() {
|
|
val toolbarView = buildToolbarView(false)
|
|
val historyEngine = buildSearchEngine(SearchEngine.Type.APPLICATION, false, Core.HISTORY_SEARCH_ENGINE_ID)
|
|
val fragment = spyk(SearchDialogFragment())
|
|
fragment.inlineAutocompleteEditText = InlineAutocompleteEditText(context)
|
|
val searchState = mockk<SearchState>()
|
|
val expectedHint = context.getString(R.string.history_search_hint)
|
|
val expectedContentDescription = historyEngine.name + ", " + context.getString(R.string.history_search_hint)
|
|
|
|
every { fragment.requireContext().getString(R.string.history_search_hint) } returns expectedHint
|
|
every { searchState.userSelectedSearchEngineId } returns historyEngine.id
|
|
every { searchState.searchEngines } returns listOf(historyEngine)
|
|
every { fragment.toolbarView } returns toolbarView
|
|
every { fragment.requireComponents.core.store.state.search } returns searchState
|
|
|
|
fragment.updateToolbarContentDescription(historyEngine, false)
|
|
|
|
assertEquals(expectedHint, fragment.inlineAutocompleteEditText.hint)
|
|
assertEquals(expectedContentDescription, toolbarView.view.contentDescription)
|
|
}
|
|
|
|
@Test
|
|
fun `WHEN bookmarks is selected as engine THEN show hint specific for bookmarks`() {
|
|
val toolbarView = buildToolbarView(false)
|
|
val bookmarksEngine = buildSearchEngine(SearchEngine.Type.APPLICATION, false, Core.BOOKMARKS_SEARCH_ENGINE_ID)
|
|
val fragment = spyk(SearchDialogFragment())
|
|
fragment.inlineAutocompleteEditText = InlineAutocompleteEditText(context)
|
|
val searchState = mockk<SearchState>()
|
|
val expectedHint = context.getString(R.string.bookmark_search_hint)
|
|
val expectedContentDescription = bookmarksEngine.name + ", " + context.getString(R.string.bookmark_search_hint)
|
|
|
|
every { fragment.requireContext().getString(R.string.bookmark_search_hint) } returns expectedHint
|
|
every { searchState.userSelectedSearchEngineId } returns bookmarksEngine.id
|
|
every { searchState.searchEngines } returns listOf(bookmarksEngine)
|
|
every { fragment.toolbarView } returns toolbarView
|
|
every { fragment.requireComponents.core.store.state.search } returns searchState
|
|
|
|
fragment.updateToolbarContentDescription(bookmarksEngine, false)
|
|
|
|
assertEquals(expectedHint, fragment.inlineAutocompleteEditText.hint)
|
|
assertEquals(expectedContentDescription, toolbarView.view.contentDescription)
|
|
}
|
|
|
|
@Test
|
|
fun `WHEN tabs is selected as engine THEN show hint specific for tabs`() {
|
|
val toolbarView = buildToolbarView(false)
|
|
val tabsEngine = buildSearchEngine(SearchEngine.Type.APPLICATION, false, Core.TABS_SEARCH_ENGINE_ID)
|
|
val fragment = spyk(SearchDialogFragment())
|
|
fragment.inlineAutocompleteEditText = InlineAutocompleteEditText(context)
|
|
val searchState = mockk<SearchState>()
|
|
val expectedHint = context.getString(R.string.tab_search_hint)
|
|
val expectedContentDescription = tabsEngine.name + ", " + context.getString(R.string.tab_search_hint)
|
|
|
|
every { fragment.requireContext().getString(R.string.tab_search_hint) } returns expectedHint
|
|
every { searchState.userSelectedSearchEngineId } returns tabsEngine.id
|
|
every { searchState.searchEngines } returns listOf(tabsEngine)
|
|
every { fragment.toolbarView } returns toolbarView
|
|
every { fragment.requireComponents.core.store.state.search } returns searchState
|
|
|
|
fragment.updateToolbarContentDescription(tabsEngine, false)
|
|
|
|
assertEquals(expectedHint, fragment.inlineAutocompleteEditText.hint)
|
|
assertEquals(expectedContentDescription, toolbarView.view.contentDescription)
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN normal browsing mode WHEN the toolbar view is initialized THEN create an autocomplete feature with valid engine`() {
|
|
val toolbarView = buildToolbarView(false)
|
|
|
|
val autocompleteFeature = toolbarView.autocompleteFeature
|
|
|
|
assertNotNull(autocompleteFeature.engine)
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN normal private mode WHEN the toolbar view is initialized THEN create an autocomplete feature with null engine`() {
|
|
val toolbarView = buildToolbarView(true)
|
|
|
|
val autocompleteFeature = toolbarView.autocompleteFeature
|
|
|
|
assertNull(autocompleteFeature.engine)
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN autocomplete disabled WHEN the toolbar view is initialized THEN create an autocomplete with disabled functionality`() {
|
|
val settings: Settings = mockk {
|
|
every { shouldAutocompleteInAwesomebar } returns false
|
|
every { isTabletAndTabStripEnabled } returns false
|
|
}
|
|
val toolbarView = buildToolbarView(true, settings)
|
|
|
|
val autocompleteFeature = toolbarView.autocompleteFeature
|
|
|
|
assertFalse(autocompleteFeature.shouldAutocomplete())
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN autocomplete enabled WHEN the toolbar view is initialized THEN create an autocomplete with enabled functionality`() {
|
|
val settings: Settings = mockk {
|
|
every { shouldAutocompleteInAwesomebar } returns true
|
|
every { isTabletAndTabStripEnabled } returns false
|
|
}
|
|
val toolbarView = buildToolbarView(true, settings)
|
|
|
|
val autocompleteFeature = toolbarView.autocompleteFeature
|
|
|
|
assertTrue(autocompleteFeature.shouldAutocomplete())
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN unified search is disabled and history suggestions enabled a new search state with the default search engine source selected WHEN updating the toolbar THEN reconfigure autocomplete suggestions`() {
|
|
mockkConstructor(ToolbarAutocompleteFeature::class) {
|
|
val historyProvider: PlacesHistoryStorage = mockk(relaxed = true)
|
|
val domainsProvider: BaseDomainAutocompleteProvider = mockk(relaxed = true)
|
|
val components: Components = mockk(relaxed = true) {
|
|
every { core.historyStorage } returns historyProvider
|
|
every { core.domainsAutocompleteProvider } returns domainsProvider
|
|
}
|
|
|
|
val settings: Settings = mockk(relaxed = true) {
|
|
every { showUnifiedSearchFeature } returns false
|
|
every { shouldShowHistorySuggestions } returns true
|
|
}
|
|
val toolbarView = buildToolbarView(
|
|
isPrivate = false,
|
|
settings = settings,
|
|
components = components,
|
|
)
|
|
|
|
toolbarView.update(defaultState)
|
|
|
|
verify {
|
|
toolbarView.autocompleteFeature.updateAutocompleteProviders(
|
|
providers = listOf(historyProvider, domainsProvider),
|
|
refreshAutocomplete = true,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN unified search is disabled, history suggestions disabled and a new search state with the default search engine source selected WHEN updating the toolbar THEN reconfigure autocomplete suggestions`() {
|
|
mockkConstructor(ToolbarAutocompleteFeature::class) {
|
|
val historyProvider: PlacesHistoryStorage = mockk(relaxed = true)
|
|
val domainsProvider: BaseDomainAutocompleteProvider = mockk(relaxed = true)
|
|
val components: Components = mockk(relaxed = true) {
|
|
every { core.historyStorage } returns historyProvider
|
|
every { core.domainsAutocompleteProvider } returns domainsProvider
|
|
}
|
|
|
|
val settings: Settings = mockk(relaxed = true) {
|
|
every { showUnifiedSearchFeature } returns false
|
|
every { shouldShowHistorySuggestions } returns false
|
|
}
|
|
val toolbarView = buildToolbarView(
|
|
isPrivate = false,
|
|
settings = settings,
|
|
components = components,
|
|
)
|
|
|
|
toolbarView.update(defaultState)
|
|
|
|
verify {
|
|
toolbarView.autocompleteFeature.updateAutocompleteProviders(
|
|
providers = listOf(domainsProvider),
|
|
refreshAutocomplete = true,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN unified search is disabled and a new search state with other than the default search engine source selected WHEN updating the toolbar THEN reconfigure autocomplete suggestions`() {
|
|
mockkConstructor(ToolbarAutocompleteFeature::class) {
|
|
val historyProvider: PlacesHistoryStorage = mockk(relaxed = true)
|
|
val domainsProvider: BaseDomainAutocompleteProvider = mockk(relaxed = true)
|
|
val components: Components = mockk(relaxed = true) {
|
|
every { core.historyStorage } returns historyProvider
|
|
every { core.domainsAutocompleteProvider } returns domainsProvider
|
|
}
|
|
|
|
val settings: Settings = mockk(relaxed = true) {
|
|
every { showUnifiedSearchFeature } returns false
|
|
every { shouldShowHistorySuggestions } returns true
|
|
}
|
|
val toolbarView = buildToolbarView(
|
|
isPrivate = false,
|
|
settings = settings,
|
|
components = components,
|
|
)
|
|
|
|
toolbarView.update(defaultState.copy(searchEngineSource = SearchEngineSource.Tabs(fakeSearchEngine)))
|
|
verify {
|
|
toolbarView.autocompleteFeature.updateAutocompleteProviders(
|
|
providers = emptyList(),
|
|
refreshAutocomplete = true,
|
|
)
|
|
}
|
|
|
|
toolbarView.update(defaultState.copy(searchEngineSource = SearchEngineSource.Bookmarks(fakeSearchEngine)))
|
|
verify {
|
|
toolbarView.autocompleteFeature.updateAutocompleteProviders(
|
|
providers = emptyList(),
|
|
refreshAutocomplete = true,
|
|
)
|
|
}
|
|
|
|
toolbarView.update(defaultState.copy(searchEngineSource = SearchEngineSource.History(fakeSearchEngine)))
|
|
verify {
|
|
toolbarView.autocompleteFeature.updateAutocompleteProviders(
|
|
providers = emptyList(),
|
|
refreshAutocomplete = true,
|
|
)
|
|
}
|
|
|
|
toolbarView.update(defaultState.copy(searchEngineSource = SearchEngineSource.Shortcut(fakeSearchEngine)))
|
|
verify {
|
|
toolbarView.autocompleteFeature.updateAutocompleteProviders(
|
|
providers = emptyList(),
|
|
refreshAutocomplete = true,
|
|
)
|
|
}
|
|
|
|
toolbarView.update(defaultState.copy(searchEngineSource = SearchEngineSource.None))
|
|
verify {
|
|
toolbarView.autocompleteFeature.updateAutocompleteProviders(
|
|
providers = emptyList(),
|
|
refreshAutocomplete = true,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN history suggestions enabled and a new search state with the default search engine source selected WHEN updating the toolbar THEN reconfigure autocomplete suggestions`() {
|
|
mockkConstructor(ToolbarAutocompleteFeature::class) {
|
|
val historyProvider: PlacesHistoryStorage = mockk(relaxed = true)
|
|
val domainsProvider: BaseDomainAutocompleteProvider = mockk(relaxed = true)
|
|
val components: Components = mockk(relaxed = true) {
|
|
every { core.historyStorage } returns historyProvider
|
|
every { core.domainsAutocompleteProvider } returns domainsProvider
|
|
}
|
|
|
|
val settings: Settings = mockk(relaxed = true) {
|
|
every { showUnifiedSearchFeature } returns true
|
|
every { shouldShowHistorySuggestions } returns true
|
|
}
|
|
val toolbarView = buildToolbarView(
|
|
isPrivate = false,
|
|
settings = settings,
|
|
components = components,
|
|
)
|
|
|
|
toolbarView.update(defaultState)
|
|
|
|
verify {
|
|
toolbarView.autocompleteFeature.updateAutocompleteProviders(
|
|
providers = listOf(historyProvider, domainsProvider),
|
|
refreshAutocomplete = true,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN history suggestions disabled and a new search state with the default search engine source selected WHEN updating the toolbar THEN reconfigure autocomplete suggestions`() {
|
|
mockkConstructor(ToolbarAutocompleteFeature::class) {
|
|
val historyProvider: PlacesHistoryStorage = mockk(relaxed = true)
|
|
val domainsProvider: BaseDomainAutocompleteProvider = mockk(relaxed = true)
|
|
val components: Components = mockk(relaxed = true) {
|
|
every { core.historyStorage } returns historyProvider
|
|
every { core.domainsAutocompleteProvider } returns domainsProvider
|
|
}
|
|
val settings: Settings = mockk(relaxed = true) {
|
|
every { showUnifiedSearchFeature } returns true
|
|
every { shouldShowHistorySuggestions } returns false
|
|
}
|
|
val toolbarView = buildToolbarView(
|
|
isPrivate = false,
|
|
settings = settings,
|
|
components = components,
|
|
)
|
|
|
|
toolbarView.update(defaultState)
|
|
|
|
verify {
|
|
toolbarView.autocompleteFeature.updateAutocompleteProviders(
|
|
providers = listOf(domainsProvider),
|
|
refreshAutocomplete = true,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN a new search state with the tabs engine source selected WHEN updating the toolbar THEN reconfigure autocomplete suggestions`() {
|
|
mockkConstructor(ToolbarAutocompleteFeature::class) {
|
|
val localSessionProvider: SessionAutocompleteProvider = mockk(relaxed = true)
|
|
val syncedSessionsProvider: SyncedTabsAutocompleteProvider = mockk(relaxed = true)
|
|
val components: Components = mockk(relaxed = true) {
|
|
every { core.sessionAutocompleteProvider } returns localSessionProvider
|
|
every { backgroundServices.syncedTabsAutocompleteProvider } returns syncedSessionsProvider
|
|
}
|
|
val settings: Settings = mockk(relaxed = true) {
|
|
every { showUnifiedSearchFeature } returns true
|
|
}
|
|
val toolbarView = buildToolbarView(
|
|
isPrivate = false,
|
|
settings = settings,
|
|
components = components,
|
|
)
|
|
|
|
toolbarView.update(defaultState.copy(searchEngineSource = SearchEngineSource.Tabs(fakeSearchEngine)))
|
|
|
|
verify {
|
|
toolbarView.autocompleteFeature.updateAutocompleteProviders(
|
|
providers = listOf(localSessionProvider, syncedSessionsProvider),
|
|
refreshAutocomplete = true,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN a new search state with the bookmarks engine source selected WHEN updating the toolbar THEN reconfigure autocomplete suggestions`() {
|
|
mockkConstructor(ToolbarAutocompleteFeature::class) {
|
|
val bookmarksProvider: PlacesBookmarksStorage = mockk(relaxed = true)
|
|
val components: Components = mockk(relaxed = true) {
|
|
every { core.bookmarksStorage } returns bookmarksProvider
|
|
}
|
|
val settings: Settings = mockk(relaxed = true) {
|
|
every { showUnifiedSearchFeature } returns true
|
|
}
|
|
val toolbarView = buildToolbarView(
|
|
isPrivate = false,
|
|
settings = settings,
|
|
components = components,
|
|
)
|
|
|
|
toolbarView.update(defaultState.copy(searchEngineSource = SearchEngineSource.Bookmarks(fakeSearchEngine)))
|
|
|
|
verify {
|
|
toolbarView.autocompleteFeature.updateAutocompleteProviders(
|
|
providers = listOf(bookmarksProvider),
|
|
refreshAutocomplete = true,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN a new search state with the history engine source selected WHEN updating the toolbar THEN reconfigure autocomplete suggestions`() {
|
|
mockkConstructor(ToolbarAutocompleteFeature::class) {
|
|
val historyProvider: PlacesHistoryStorage = mockk(relaxed = true)
|
|
val components: Components = mockk(relaxed = true) {
|
|
every { core.historyStorage } returns historyProvider
|
|
}
|
|
val settings: Settings = mockk(relaxed = true) {
|
|
every { showUnifiedSearchFeature } returns true
|
|
}
|
|
val toolbarView = buildToolbarView(
|
|
isPrivate = false,
|
|
settings = settings,
|
|
components = components,
|
|
)
|
|
|
|
toolbarView.update(defaultState.copy(searchEngineSource = SearchEngineSource.History(fakeSearchEngine)))
|
|
|
|
verify {
|
|
toolbarView.autocompleteFeature.updateAutocompleteProviders(
|
|
providers = listOf(historyProvider),
|
|
refreshAutocomplete = true,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN a new search state with no engine source selected WHEN updating the toolbar THEN reconfigure autocomplete suggestions`() {
|
|
mockkConstructor(ToolbarAutocompleteFeature::class) {
|
|
val settings: Settings = mockk(relaxed = true) {
|
|
every { showUnifiedSearchFeature } returns true
|
|
}
|
|
val toolbarView = buildToolbarView(
|
|
false,
|
|
settings = settings,
|
|
)
|
|
|
|
toolbarView.update(defaultState.copy(searchEngineSource = SearchEngineSource.None))
|
|
|
|
verify {
|
|
toolbarView.autocompleteFeature.updateAutocompleteProviders(
|
|
providers = emptyList(),
|
|
refreshAutocomplete = true,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN a new search state with a shortcut engine source selected WHEN updating the toolbar THEN reconfigure autocomplete suggestions`() {
|
|
mockkConstructor(ToolbarAutocompleteFeature::class) {
|
|
val settings: Settings = mockk(relaxed = true) {
|
|
every { showUnifiedSearchFeature } returns true
|
|
}
|
|
val toolbarView = buildToolbarView(
|
|
isPrivate = false,
|
|
settings = settings,
|
|
)
|
|
|
|
toolbarView.update(defaultState.copy(searchEngineSource = SearchEngineSource.Shortcut(fakeSearchEngine)))
|
|
|
|
verify {
|
|
toolbarView.autocompleteFeature.updateAutocompleteProviders(
|
|
providers = emptyList(),
|
|
refreshAutocomplete = true,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN show bookmark suggestions and unified search are both enabled WHEN the toolbar view is initialized THEN add bookmark storage to autocomplete providers`() {
|
|
mockkConstructor(ToolbarAutocompleteFeature::class) {
|
|
val historyProvider: PlacesHistoryStorage = mockk(relaxed = true)
|
|
val bookmarksStorage: PlacesBookmarksStorage = mockk(relaxed = true)
|
|
val domainsProvider: BaseDomainAutocompleteProvider = mockk(relaxed = true)
|
|
val components: Components = mockk(relaxed = true) {
|
|
every { core.historyStorage } returns historyProvider
|
|
every { core.domainsAutocompleteProvider } returns domainsProvider
|
|
every { core.bookmarksStorage } returns bookmarksStorage
|
|
}
|
|
|
|
val settings: Settings = mockk(relaxed = true) {
|
|
every { showUnifiedSearchFeature } returns true
|
|
every { shouldShowHistorySuggestions } returns true
|
|
every { shouldShowBookmarkSuggestions } returns true
|
|
}
|
|
val toolbarView = buildToolbarView(
|
|
isPrivate = false,
|
|
settings = settings,
|
|
components = components,
|
|
)
|
|
|
|
toolbarView.update(defaultState)
|
|
|
|
verify {
|
|
toolbarView.autocompleteFeature.updateAutocompleteProviders(
|
|
providers = listOf(historyProvider, bookmarksStorage, domainsProvider),
|
|
refreshAutocomplete = true,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun `GIVEN show bookmark suggestions is disabled and unified search is enabled WHEN the toolbar view is initialized THEN don't add bookmark storage to autocomplete providers`() {
|
|
mockkConstructor(ToolbarAutocompleteFeature::class) {
|
|
val historyProvider: PlacesHistoryStorage = mockk(relaxed = true)
|
|
val bookmarksStorage: PlacesBookmarksStorage = mockk(relaxed = true)
|
|
val domainsProvider: BaseDomainAutocompleteProvider = mockk(relaxed = true)
|
|
val components: Components = mockk(relaxed = true) {
|
|
every { core.historyStorage } returns historyProvider
|
|
every { core.domainsAutocompleteProvider } returns domainsProvider
|
|
every { core.bookmarksStorage } returns bookmarksStorage
|
|
}
|
|
|
|
val settings: Settings = mockk(relaxed = true) {
|
|
every { showUnifiedSearchFeature } returns true
|
|
every { shouldShowHistorySuggestions } returns true
|
|
every { shouldShowBookmarkSuggestions } returns false
|
|
}
|
|
val toolbarView = buildToolbarView(
|
|
isPrivate = false,
|
|
settings = settings,
|
|
components = components,
|
|
)
|
|
|
|
toolbarView.update(defaultState)
|
|
|
|
verify {
|
|
toolbarView.autocompleteFeature.updateAutocompleteProviders(
|
|
providers = listOf(historyProvider, domainsProvider),
|
|
refreshAutocomplete = true,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun buildToolbarView(
|
|
isPrivate: Boolean,
|
|
settings: Settings = context.settings(),
|
|
components: Components = mockk(relaxed = true),
|
|
) = ToolbarView(
|
|
settings = settings,
|
|
components = components,
|
|
interactor = interactor,
|
|
isPrivate = isPrivate,
|
|
view = toolbar,
|
|
fromHomeFragment = false,
|
|
)
|
|
|
|
private fun buildSearchEngine(
|
|
type: SearchEngine.Type,
|
|
isGeneral: Boolean,
|
|
id: String = UUID.randomUUID().toString(),
|
|
) = SearchEngine(
|
|
id = id,
|
|
name = UUID.randomUUID().toString(),
|
|
icon = testContext.getDrawable(R.drawable.ic_search)!!.toBitmap(),
|
|
type = type,
|
|
isGeneral = isGeneral,
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Get a fake [SearchEngine] to use where a simple mock won't suffice.
|
|
*/
|
|
private val fakeSearchEngine = SearchEngine(
|
|
id = "fakeId",
|
|
name = "fakeName",
|
|
icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8),
|
|
type = SearchEngine.Type.CUSTOM,
|
|
resultUrls = emptyList(),
|
|
)
|