1
0
Fork 0

Add tests for search (#12437)

master
Tiger Oakes 2020-07-14 10:32:04 -07:00 committed by GitHub
parent e9fb1a61c7
commit 1ff64cab67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 257 additions and 21 deletions

View File

@ -96,9 +96,7 @@ private fun searchStateReducer(state: SearchFragmentState, action: SearchFragmen
is SearchFragmentAction.UpdateQuery ->
state.copy(query = action.query)
is SearchFragmentAction.SelectNewDefaultSearchEngine ->
state.copy(
searchEngineSource = SearchEngineSource.Default(action.engine)
)
state.copy(searchEngineSource = SearchEngineSource.Default(action.engine))
is SearchFragmentAction.AllowSearchSuggestionsInPrivateModePrompt ->
state.copy(showSearchSuggestionsHint = action.show)
is SearchFragmentAction.SetShowSearchSuggestions ->

View File

@ -34,16 +34,15 @@ class ShortcutsSuggestionProvider(
override suspend fun onInputChanged(text: String): List<AwesomeBar.Suggestion> {
val suggestions = mutableListOf<AwesomeBar.Suggestion>()
searchEngineProvider.installedSearchEngines(context).list.forEach {
suggestions.add(
AwesomeBar.Suggestion(
provider = this,
id = it.identifier,
icon = it.icon,
title = it.name,
onSuggestionClicked = {
selectShortcutEngine(it)
})
searchEngineProvider.installedSearchEngines(context).list.mapTo(suggestions) {
AwesomeBar.Suggestion(
provider = this,
id = it.identifier,
icon = it.icon,
title = it.name,
onSuggestionClicked = {
selectShortcutEngine(it)
}
)
}
@ -55,7 +54,8 @@ class ShortcutsSuggestionProvider(
title = context.getString(R.string.search_shortcuts_engine_settings),
onSuggestionClicked = {
selectShortcutEngineSettings()
})
}
)
)
return suggestions
}

View File

@ -22,24 +22,24 @@ import org.mozilla.fenix.theme.ThemeManager
/**
* Interface for the Toolbar Interactor. This interface is implemented by objects that want
* to respond to user interaction on the [BrowserToolbarView]
* to respond to user interaction on the [ToolbarView]
*/
interface ToolbarInteractor {
/**
* Called when a user hits the return key while [BrowserToolbarView] has focus.
* @param url the text inside the [BrowserToolbarView] when committed
* Called when a user hits the return key while [ToolbarView] has focus.
* @param url the text inside the [ToolbarView] when committed
*/
fun onUrlCommitted(url: String)
/**
* Called when a user removes focus from the [BrowserToolbarView]
* Called when a user removes focus from the [ToolbarView]
*/
fun onEditingCanceled()
/**
* Called whenever the text inside the [BrowserToolbarView] changes
* @param text the current text displayed by [BrowserToolbarView]
* Called whenever the text inside the [ToolbarView] changes
* @param text the current text displayed by [ToolbarView]
*/
fun onTextChanged(text: String)
}
@ -103,7 +103,7 @@ class ToolbarView(
override fun onTextChanged(text: String) {
url = text
this@ToolbarView.interactor.onTextChanged(text)
interactor.onTextChanged(text)
}
})
}

View File

@ -5,13 +5,17 @@
package org.mozilla.fenix.search
import io.mockk.mockk
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import mozilla.components.browser.search.SearchEngine
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotSame
import org.junit.Assert.assertTrue
import org.junit.Test
import org.mozilla.fenix.components.metrics.Event
@ExperimentalCoroutinesApi
class SearchFragmentStoreTest {
@Test
@ -57,6 +61,43 @@ class SearchFragmentStoreTest {
assertEquals(false, store.state.showSearchShortcuts)
}
@Test
fun showSearchSuggestions() = runBlocking {
val initialState = emptyDefaultState()
val store = SearchFragmentStore(initialState)
store.dispatch(SearchFragmentAction.SetShowSearchSuggestions(true)).join()
assertNotSame(initialState, store.state)
assertTrue(store.state.showSearchSuggestions)
store.dispatch(SearchFragmentAction.SetShowSearchSuggestions(false)).join()
assertFalse(store.state.showSearchSuggestions)
}
@Test
fun allowSearchInPrivateMode() = runBlocking {
val initialState = emptyDefaultState()
val store = SearchFragmentStore(initialState)
store.dispatch(SearchFragmentAction.AllowSearchSuggestionsInPrivateModePrompt(true)).join()
assertNotSame(initialState, store.state)
assertTrue(store.state.showSearchSuggestionsHint)
store.dispatch(SearchFragmentAction.AllowSearchSuggestionsInPrivateModePrompt(false)).join()
assertFalse(store.state.showSearchSuggestionsHint)
}
@Test
fun selectNewDefaultEngine() = runBlocking {
val initialState = emptyDefaultState()
val store = SearchFragmentStore(initialState)
val engine = mockk<SearchEngine>()
store.dispatch(SearchFragmentAction.SelectNewDefaultSearchEngine(engine)).join()
assertNotSame(initialState, store.state)
assertEquals(SearchEngineSource.Default(engine), store.state.searchEngineSource)
}
private fun emptyDefaultState(): SearchFragmentState = SearchFragmentState(
tabId = null,
url = "",

View File

@ -0,0 +1,119 @@
/* 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.awesomebar
import android.content.Context
import androidx.appcompat.content.res.AppCompatResources
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.unmockkStatic
import io.mockk.verifySequence
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runBlockingTest
import mozilla.components.browser.search.SearchEngine
import mozilla.components.browser.search.provider.SearchEngineList
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Before
import org.junit.Test
import org.mozilla.fenix.R
import org.mozilla.fenix.components.searchengine.FenixSearchEngineProvider
@ExperimentalCoroutinesApi
class ShortcutsSuggestionProviderTest {
private lateinit var context: Context
@Before
fun setup() {
mockkStatic(AppCompatResources::class)
context = mockk {
every { getString(R.string.search_shortcuts_engine_settings) } returns "Search engine settings"
}
every { AppCompatResources.getDrawable(context, R.drawable.ic_settings) } returns null
}
@After
fun teardown() {
unmockkStatic(AppCompatResources::class)
}
@Test
fun `should clear is always false`() {
val provider = ShortcutsSuggestionProvider(mockk(), mockk(), mockk(), mockk())
assertFalse(provider.shouldClearSuggestions)
}
@Test
fun `returns suggestions from search engine provider`() = runBlockingTest {
val engineOne = mockk<SearchEngine> {
every { identifier } returns "1"
every { name } returns "EngineOne"
every { icon } returns mockk()
}
val engineTwo = mockk<SearchEngine> {
every { identifier } returns "2"
every { name } returns "EngineTwo"
every { icon } returns mockk()
}
val searchEngineProvider = mockk<FenixSearchEngineProvider> {
every { installedSearchEngines(context) } returns SearchEngineList(
list = listOf(engineOne, engineTwo),
default = null
)
}
val provider = ShortcutsSuggestionProvider(searchEngineProvider, context, mockk(), mockk())
val suggestions = provider.onInputChanged("")
assertEquals(3, suggestions.size)
assertEquals(provider, suggestions[0].provider)
assertEquals(engineOne.identifier, suggestions[0].id)
assertEquals(engineOne.icon, suggestions[0].icon)
assertEquals(engineOne.name, suggestions[0].title)
assertEquals(provider, suggestions[1].provider)
assertEquals(engineTwo.identifier, suggestions[1].id)
assertEquals(engineTwo.icon, suggestions[1].icon)
assertEquals(engineTwo.name, suggestions[1].title)
assertEquals(provider, suggestions[2].provider)
assertEquals("Search engine settings", suggestions[2].id)
assertEquals("Search engine settings", suggestions[2].title)
}
@Test
fun `callbacks are triggered when suggestions are clicked`() = runBlockingTest {
val engineOne = mockk<SearchEngine>(relaxed = true)
val searchEngineProvider = mockk<FenixSearchEngineProvider> {
every { installedSearchEngines(context) } returns SearchEngineList(
list = listOf(engineOne),
default = null
)
}
val selectShortcutEngine = mockk<(SearchEngine) -> Unit>(relaxed = true)
val selectShortcutEngineSettings = mockk<() -> Unit>(relaxed = true)
val provider = ShortcutsSuggestionProvider(
searchEngineProvider,
context,
selectShortcutEngine,
selectShortcutEngineSettings
)
val suggestions = provider.onInputChanged("")
assertEquals(2, suggestions.size)
suggestions[0].onSuggestionClicked?.invoke()
suggestions[1].onSuggestionClicked?.invoke()
verifySequence {
selectShortcutEngine(engineOne)
selectShortcutEngineSettings()
}
}
}

View File

@ -0,0 +1,78 @@
/* 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 io.mockk.MockKAnnotations
import io.mockk.Runs
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.just
import io.mockk.slot
import io.mockk.spyk
import io.mockk.verify
import mozilla.components.browser.toolbar.BrowserToolbar
import mozilla.components.concept.engine.Engine
import mozilla.components.concept.toolbar.Toolbar
import mozilla.components.support.test.robolectric.testContext
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.helpers.FenixRobolectricTestRunner
@RunWith(FenixRobolectricTestRunner::class)
class ToolbarViewTest {
@MockK(relaxed = true) private lateinit var interactor: ToolbarInteractor
@MockK private lateinit var engine: Engine
private lateinit var toolbar: BrowserToolbar
@Before
fun setup() {
MockKAnnotations.init(this)
toolbar = spyk(BrowserToolbar(testContext))
}
@Test
fun `sets up interactor listeners`() {
val urlCommitListener = slot<(String) -> Boolean>()
val editListener = slot<Toolbar.OnEditListener>()
every { toolbar.setOnUrlCommitListener(capture(urlCommitListener)) } just Runs
every { toolbar.setOnEditListener(capture(editListener)) } just Runs
buildToolbarView(isPrivate = false)
assertFalse(urlCommitListener.captured("test"))
verify { interactor.onUrlCommitted("test") }
assertFalse(editListener.captured.onCancelEditing())
verify { interactor.onEditingCanceled() }
editListener.captured.onTextChanged("https://example.com")
verify { interactor.onTextChanged("https://example.com") }
}
@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)
}
private fun buildToolbarView(isPrivate: Boolean) = ToolbarView(
testContext,
interactor,
historyStorage = null,
isPrivate = isPrivate,
view = toolbar,
engine = engine
)
}