No issue: begin moving FenixSearchEngineProvider into a testing harness
parent
7191aec7ae
commit
d3ff98816d
|
@ -5,6 +5,7 @@
|
||||||
package org.mozilla.fenix.components.searchengine
|
package org.mozilla.fenix.components.searchengine
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import androidx.annotation.VisibleForTesting
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
|
@ -21,16 +22,15 @@ import org.mozilla.fenix.ext.settings
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
@SuppressWarnings("TooManyFunctions")
|
@SuppressWarnings("TooManyFunctions")
|
||||||
class FenixSearchEngineProvider(
|
open class FenixSearchEngineProvider(
|
||||||
private val context: Context
|
private val context: Context
|
||||||
) : SearchEngineProvider, CoroutineScope by CoroutineScope(Job() + Dispatchers.IO) {
|
) : SearchEngineProvider, CoroutineScope by CoroutineScope(Job() + Dispatchers.IO) {
|
||||||
private val baseSearchEngines = async {
|
open val baseSearchEngines = async {
|
||||||
AssetsSearchEngineProvider(LocaleSearchLocalizationProvider()).loadSearchEngines(context)
|
AssetsSearchEngineProvider(LocaleSearchLocalizationProvider()).loadSearchEngines(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val bundledSearchEngines = async {
|
open val bundledSearchEngines = async {
|
||||||
val defaultEngineIdentifiers = baseSearchEngines.await().list.map { it.identifier }.toSet()
|
val defaultEngineIdentifiers = baseSearchEngines.await().list.map { it.identifier }.toSet()
|
||||||
|
|
||||||
AssetsSearchEngineProvider(
|
AssetsSearchEngineProvider(
|
||||||
LocaleSearchLocalizationProvider(),
|
LocaleSearchLocalizationProvider(),
|
||||||
filters = listOf(object : SearchEngineFilter {
|
filters = listOf(object : SearchEngineFilter {
|
||||||
|
@ -43,7 +43,7 @@ class FenixSearchEngineProvider(
|
||||||
).loadSearchEngines(context)
|
).loadSearchEngines(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var customSearchEngines = async {
|
open var customSearchEngines = async {
|
||||||
CustomSearchEngineProvider().loadSearchEngines(context)
|
CustomSearchEngineProvider().loadSearchEngines(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +56,10 @@ class FenixSearchEngineProvider(
|
||||||
return engines.list.find { it.name == selectedName } ?: engines.default ?: engines.list.first()
|
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 {
|
fun installedSearchEngines(context: Context): SearchEngineList = runBlocking {
|
||||||
val engineList = loadedSearchEngines.await()
|
val engineList = loadedSearchEngines.await()
|
||||||
val installedIdentifiers = installedSearchEngineIdentifiers(context)
|
val installedIdentifiers = installedSearchEngineIdentifiers(context)
|
||||||
|
@ -141,16 +145,17 @@ class FenixSearchEngineProvider(
|
||||||
prefs.edit().putStringSet(INSTALLED_ENGINES_KEY, defaultSet).apply()
|
prefs.edit().putStringSet(INSTALLED_ENGINES_KEY, defaultSet).apply()
|
||||||
defaultSet
|
defaultSet
|
||||||
} else {
|
} 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()
|
val customEngineIdentifiers = customSearchEngines.await().list.map { it.identifier }.toSet()
|
||||||
return identifiers + customEngineIdentifiers
|
return identifiers + customEngineIdentifiers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||||
companion object {
|
companion object {
|
||||||
private val BUNDLED_SEARCH_ENGINES = listOf("ecosia", "reddit", "startpage", "yahoo", "youtube")
|
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"
|
private const val INSTALLED_ENGINES_KEY = "fenix-installed-search-engines"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue