1
0
Fork 0

No issue: begin moving FenixSearchEngineProvider into a testing harness

master
Severin Rudie 2019-12-04 17:51:15 -08:00 committed by Jeff Boek
parent 7191aec7ae
commit d3ff98816d
2 changed files with 121 additions and 7 deletions

View File

@ -5,6 +5,7 @@
package org.mozilla.fenix.components.searchengine
import android.content.Context
import androidx.annotation.VisibleForTesting
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@ -21,16 +22,15 @@ import org.mozilla.fenix.ext.settings
import java.util.Locale
@SuppressWarnings("TooManyFunctions")
class FenixSearchEngineProvider(
open class FenixSearchEngineProvider(
private val context: Context
) : SearchEngineProvider, CoroutineScope by CoroutineScope(Job() + Dispatchers.IO) {
private val baseSearchEngines = async {
open val baseSearchEngines = async {
AssetsSearchEngineProvider(LocaleSearchLocalizationProvider()).loadSearchEngines(context)
}
private val bundledSearchEngines = async {
open val bundledSearchEngines = async {
val defaultEngineIdentifiers = baseSearchEngines.await().list.map { it.identifier }.toSet()
AssetsSearchEngineProvider(
LocaleSearchLocalizationProvider(),
filters = listOf(object : SearchEngineFilter {
@ -43,7 +43,7 @@ class FenixSearchEngineProvider(
).loadSearchEngines(context)
}
private var customSearchEngines = async {
open var customSearchEngines = async {
CustomSearchEngineProvider().loadSearchEngines(context)
}
@ -56,6 +56,10 @@ class FenixSearchEngineProvider(
return engines.list.find { it.name == selectedName } ?: engines.default ?: engines.list.first()
}
/**
* @return a list of all SearchEngines that are currently active. These are the engines that
* are readily available throughout the app.
*/
fun installedSearchEngines(context: Context): SearchEngineList = runBlocking {
val engineList = loadedSearchEngines.await()
val installedIdentifiers = installedSearchEngineIdentifiers(context)
@ -141,16 +145,17 @@ class FenixSearchEngineProvider(
prefs.edit().putStringSet(INSTALLED_ENGINES_KEY, defaultSet).apply()
defaultSet
} else {
prefs(context).getStringSet(INSTALLED_ENGINES_KEY, setOf()) ?: setOf()
prefs.getStringSet(INSTALLED_ENGINES_KEY, setOf()) ?: setOf()
}
val customEngineIdentifiers = customSearchEngines.await().list.map { it.identifier }.toSet()
return identifiers + customEngineIdentifiers
}
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
companion object {
private val BUNDLED_SEARCH_ENGINES = listOf("ecosia", "reddit", "startpage", "yahoo", "youtube")
private const val PREF_FILE = "fenix-search-engine-provider"
const val PREF_FILE = "fenix-search-engine-provider"
private const val INSTALLED_ENGINES_KEY = "fenix-installed-search-engines"
}
}

View File

@ -0,0 +1,109 @@
package org.mozilla.fenix.components.searchengine
import android.content.Context
import android.graphics.Bitmap
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Deferred
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.Before
import org.junit.Test
import org.mockito.Mockito
import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import java.util.UUID
@ExperimentalCoroutinesApi
class FenixSearchEngineProviderTest {
private val testContext = mockk<Context>()
private lateinit var fenixSearchEngineProvider: FenixSearchEngineProvider
@Before
fun before() {
fenixSearchEngineProvider = FakeFenixSearchEngineProvider(testContext)
every {
testContext.getSharedPreferences(FenixSearchEngineProvider.PREF_FILE, Context.MODE_PRIVATE)
} returns mockk(relaxed = true)
}
/*
TODO TEST:
- public API happy path
- list ordering
- deduping
- the above after adding/removing
*/
@Test
fun `temp test class inits`() = runBlockingTest {
val t = fenixSearchEngineProvider.loadSearchEngines(testContext)
println(t)
}
}
class FakeFenixSearchEngineProvider(context: Context) : FenixSearchEngineProvider(context) {
override val defaultEngines: Deferred<SearchEngineList>
get() {
val google = mockSearchEngine(id = "google-b-1-m", n = "Google")
return CompletableDeferred(
SearchEngineList(
listOf(
google,
mockSearchEngine("bing", "Bing"),
mockSearchEngine("amazondotcom", "Amazon.com")
), default = google
)
)
}
override val bundledEngines = CompletableDeferred(
SearchEngineList(
listOf(
mockSearchEngine("ecosia", "Ecosia"),
mockSearchEngine("reddit", "Reddit"),
mockSearchEngine("startpage", "Startpage.com")
), default = null
)
)
override var customEngines: Deferred<SearchEngineList>
get() {
return CompletableDeferred(
SearchEngineList(
listOf(
mockSearchEngine("my custom site", "my custom site")
), default = null
)
)
}
set(_) = throw RuntimeException("Setting not currently supported on this fake")
private fun mockSearchEngine(
id: String,
n: String = id
// TODO this fails with `Missing calls inside every { ... } block`. Not sure why
// ) = mockk<SearchEngine> {
// every { identifier } returns id
// every { name } returns n
// every { icon } returns mockk()
// }
): SearchEngine {
return mock(SearchEngine::class.java).apply {
`when`(identifier).thenReturn(id)
`when`(name).thenReturn(n)
`when`(icon).thenReturn(mock(Bitmap::class.java))
}
}
}