parent
447b134fe9
commit
96b68948b5
|
@ -73,6 +73,7 @@ android {
|
||||||
|
|
||||||
testOptions {
|
testOptions {
|
||||||
execution 'ANDROIDX_TEST_ORCHESTRATOR'
|
execution 'ANDROIDX_TEST_ORCHESTRATOR'
|
||||||
|
unitTests.includeAndroidResources = true
|
||||||
}
|
}
|
||||||
|
|
||||||
flavorDimensions "abi"
|
flavorDimensions "abi"
|
||||||
|
@ -122,7 +123,7 @@ android.applicationVariants.all { variant ->
|
||||||
if (hasTest) {
|
if (hasTest) {
|
||||||
apply plugin: 'kotlin-allopen'
|
apply plugin: 'kotlin-allopen'
|
||||||
allOpen {
|
allOpen {
|
||||||
annotation("org.mozilla.fenix.test.Mockable")
|
annotation("org.mozilla.fenix.test.OpenClass")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,9 +374,11 @@ dependencies {
|
||||||
exclude group: 'com.android.support', module: 'support-annotations'
|
exclude group: 'com.android.support', module: 'support-annotations'
|
||||||
}
|
}
|
||||||
|
|
||||||
testImplementation Deps.junit_jupiter_api
|
testImplementation Deps.junit
|
||||||
testImplementation Deps.junit_jupiter_params
|
testImplementation Deps.robolectric
|
||||||
testImplementation Deps.junit_jupiter_engine
|
debugImplementation Deps.fragment_testing
|
||||||
|
testImplementation Deps.megazord_forUnitTests
|
||||||
|
testImplementation Deps.places_forUnitTests
|
||||||
|
|
||||||
testImplementation Deps.mockito_core
|
testImplementation Deps.mockito_core
|
||||||
androidTestImplementation Deps.mockito_android
|
androidTestImplementation Deps.mockito_android
|
||||||
|
|
|
@ -28,16 +28,20 @@ import org.mozilla.fenix.utils.Settings
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@SuppressLint("Registered")
|
@SuppressLint("Registered")
|
||||||
|
@Suppress("TooManyFunctions")
|
||||||
open class FenixApplication : Application() {
|
open class FenixApplication : Application() {
|
||||||
lateinit var fretboard: Fretboard
|
lateinit var fretboard: Fretboard
|
||||||
lateinit var experimentLoader: Deferred<Boolean>
|
lateinit var experimentLoader: Deferred<Boolean>
|
||||||
var experimentLoaderComplete: Boolean = false
|
var experimentLoaderComplete: Boolean = false
|
||||||
|
|
||||||
val components by lazy { Components(this) }
|
open val components by lazy { Components(this) }
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
|
setupApplication()
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun setupApplication() {
|
||||||
// loadExperiments does things that run in parallel with the rest of setup.
|
// loadExperiments does things that run in parallel with the rest of setup.
|
||||||
// Call the function as early as possible so there's maximum overlap.
|
// Call the function as early as possible so there's maximum overlap.
|
||||||
experimentLoader = loadExperiments()
|
experimentLoader = loadExperiments()
|
||||||
|
|
|
@ -19,6 +19,7 @@ import org.mozilla.fenix.components.metrics.AdjustMetricsService
|
||||||
import org.mozilla.fenix.components.metrics.GleanMetricsService
|
import org.mozilla.fenix.components.metrics.GleanMetricsService
|
||||||
import org.mozilla.fenix.components.metrics.LeanplumMetricsService
|
import org.mozilla.fenix.components.metrics.LeanplumMetricsService
|
||||||
import org.mozilla.fenix.components.metrics.MetricController
|
import org.mozilla.fenix.components.metrics.MetricController
|
||||||
|
import org.mozilla.fenix.test.Mockable
|
||||||
import org.mozilla.fenix.utils.Settings
|
import org.mozilla.fenix.utils.Settings
|
||||||
import org.mozilla.geckoview.BuildConfig.MOZ_APP_BUILDID
|
import org.mozilla.geckoview.BuildConfig.MOZ_APP_BUILDID
|
||||||
import org.mozilla.geckoview.BuildConfig.MOZ_APP_VERSION
|
import org.mozilla.geckoview.BuildConfig.MOZ_APP_VERSION
|
||||||
|
@ -26,6 +27,7 @@ import org.mozilla.geckoview.BuildConfig.MOZ_APP_VERSION
|
||||||
/**
|
/**
|
||||||
* Component group for all functionality related to analytics e.g. crash reporting and telemetry.
|
* Component group for all functionality related to analytics e.g. crash reporting and telemetry.
|
||||||
*/
|
*/
|
||||||
|
@Mockable
|
||||||
class Analytics(
|
class Analytics(
|
||||||
private val context: Context
|
private val context: Context
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -14,11 +14,13 @@ import mozilla.components.feature.sync.BackgroundSyncManager
|
||||||
import mozilla.components.feature.sync.GlobalSyncableStoreProvider
|
import mozilla.components.feature.sync.GlobalSyncableStoreProvider
|
||||||
import mozilla.components.service.fxa.Config
|
import mozilla.components.service.fxa.Config
|
||||||
import mozilla.components.service.fxa.FxaAccountManager
|
import mozilla.components.service.fxa.FxaAccountManager
|
||||||
|
import org.mozilla.fenix.test.Mockable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component group for background services. These are the components that need to be accessed from within a
|
* Component group for background services. These are the components that need to be accessed from within a
|
||||||
* background worker.
|
* background worker.
|
||||||
*/
|
*/
|
||||||
|
@Mockable
|
||||||
class BackgroundServices(
|
class BackgroundServices(
|
||||||
context: Context,
|
context: Context,
|
||||||
historyStorage: PlacesHistoryStorage,
|
historyStorage: PlacesHistoryStorage,
|
||||||
|
|
|
@ -5,10 +5,12 @@
|
||||||
package org.mozilla.fenix.components
|
package org.mozilla.fenix.components
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import org.mozilla.fenix.test.Mockable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to all components.
|
* Provides access to all components.
|
||||||
*/
|
*/
|
||||||
|
@Mockable
|
||||||
class Components(private val context: Context) {
|
class Components(private val context: Context) {
|
||||||
val backgroundServices by lazy { BackgroundServices(context, core.historyStorage, core.bookmarksStorage) }
|
val backgroundServices by lazy { BackgroundServices(context, core.historyStorage, core.bookmarksStorage) }
|
||||||
val services by lazy { Services(backgroundServices.accountManager, useCases.tabsUseCases) }
|
val services by lazy { Services(backgroundServices.accountManager, useCases.tabsUseCases) }
|
||||||
|
|
|
@ -25,6 +25,7 @@ import mozilla.components.concept.fetch.Client
|
||||||
import mozilla.components.feature.session.HistoryDelegate
|
import mozilla.components.feature.session.HistoryDelegate
|
||||||
import mozilla.components.lib.crash.handler.CrashHandlerService
|
import mozilla.components.lib.crash.handler.CrashHandlerService
|
||||||
import org.mozilla.fenix.AppRequestInterceptor
|
import org.mozilla.fenix.AppRequestInterceptor
|
||||||
|
import org.mozilla.fenix.test.Mockable
|
||||||
import org.mozilla.fenix.utils.Settings
|
import org.mozilla.fenix.utils.Settings
|
||||||
import org.mozilla.geckoview.GeckoRuntime
|
import org.mozilla.geckoview.GeckoRuntime
|
||||||
import org.mozilla.geckoview.GeckoRuntimeSettings
|
import org.mozilla.geckoview.GeckoRuntimeSettings
|
||||||
|
@ -33,9 +34,10 @@ import java.util.concurrent.TimeUnit
|
||||||
/**
|
/**
|
||||||
* Component group for all core browser functionality.
|
* Component group for all core browser functionality.
|
||||||
*/
|
*/
|
||||||
|
@Mockable
|
||||||
class Core(private val context: Context) {
|
class Core(private val context: Context) {
|
||||||
|
|
||||||
private val runtime by lazy {
|
protected val runtime by lazy {
|
||||||
val builder = GeckoRuntimeSettings.Builder()
|
val builder = GeckoRuntimeSettings.Builder()
|
||||||
|
|
||||||
testConfig?.let {
|
testConfig?.let {
|
||||||
|
|
|
@ -5,18 +5,20 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
package org.mozilla.fenix.components
|
package org.mozilla.fenix.components
|
||||||
|
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import com.google.android.material.snackbar.BaseTransientBottomBar
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import androidx.core.widget.TextViewCompat
|
import androidx.core.widget.TextViewCompat
|
||||||
|
import com.google.android.material.snackbar.BaseTransientBottomBar
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import kotlinx.android.synthetic.main.fenix_snackbar.view.*
|
import kotlinx.android.synthetic.main.fenix_snackbar.view.*
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.ext.increaseTapArea
|
import org.mozilla.fenix.ext.increaseTapArea
|
||||||
|
import org.mozilla.fenix.test.Mockable
|
||||||
|
|
||||||
|
@Mockable
|
||||||
class FenixSnackbar private constructor(
|
class FenixSnackbar private constructor(
|
||||||
parent: ViewGroup,
|
parent: ViewGroup,
|
||||||
content: View,
|
content: View,
|
||||||
|
|
|
@ -16,7 +16,9 @@ import mozilla.components.feature.findinpage.view.FindInPageBar
|
||||||
import mozilla.components.feature.findinpage.view.FindInPageView
|
import mozilla.components.feature.findinpage.view.FindInPageView
|
||||||
import mozilla.components.support.base.feature.BackHandler
|
import mozilla.components.support.base.feature.BackHandler
|
||||||
import mozilla.components.support.base.feature.LifecycleAwareFeature
|
import mozilla.components.support.base.feature.LifecycleAwareFeature
|
||||||
|
import org.mozilla.fenix.test.Mockable
|
||||||
|
|
||||||
|
@Mockable
|
||||||
class FindInPageIntegration(
|
class FindInPageIntegration(
|
||||||
private val sessionManager: SessionManager,
|
private val sessionManager: SessionManager,
|
||||||
private val view: FindInPageView,
|
private val view: FindInPageView,
|
||||||
|
|
|
@ -8,11 +8,13 @@ import android.content.Context
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import mozilla.components.browser.search.SearchEngineManager
|
import mozilla.components.browser.search.SearchEngineManager
|
||||||
|
import org.mozilla.fenix.test.Mockable
|
||||||
import org.mozilla.fenix.utils.Settings
|
import org.mozilla.fenix.utils.Settings
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component group for all search engine integration related functionality.
|
* Component group for all search engine integration related functionality.
|
||||||
*/
|
*/
|
||||||
|
@Mockable
|
||||||
class Search(private val context: Context) {
|
class Search(private val context: Context) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -7,10 +7,12 @@ package org.mozilla.fenix.components
|
||||||
import mozilla.components.feature.accounts.FirefoxAccountsAuthFeature
|
import mozilla.components.feature.accounts.FirefoxAccountsAuthFeature
|
||||||
import mozilla.components.feature.tabs.TabsUseCases
|
import mozilla.components.feature.tabs.TabsUseCases
|
||||||
import mozilla.components.service.fxa.FxaAccountManager
|
import mozilla.components.service.fxa.FxaAccountManager
|
||||||
|
import org.mozilla.fenix.test.Mockable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component group which encapsulates foreground-friendly services.
|
* Component group which encapsulates foreground-friendly services.
|
||||||
*/
|
*/
|
||||||
|
@Mockable
|
||||||
class Services(
|
class Services(
|
||||||
private val accountManager: FxaAccountManager,
|
private val accountManager: FxaAccountManager,
|
||||||
private val tabsUseCases: TabsUseCases
|
private val tabsUseCases: TabsUseCases
|
||||||
|
|
|
@ -9,7 +9,9 @@ import androidx.paging.DataSource
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissions
|
import mozilla.components.feature.sitepermissions.SitePermissions
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissions.Status
|
import mozilla.components.feature.sitepermissions.SitePermissions.Status
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissionsStorage
|
import mozilla.components.feature.sitepermissions.SitePermissionsStorage
|
||||||
|
import org.mozilla.fenix.test.Mockable
|
||||||
|
|
||||||
|
@Mockable
|
||||||
class Storage(private val context: Context) {
|
class Storage(private val context: Context) {
|
||||||
|
|
||||||
private val permissionsStorage by lazy {
|
private val permissionsStorage by lazy {
|
||||||
|
|
|
@ -10,11 +10,13 @@ import mozilla.components.browser.session.SessionManager
|
||||||
import mozilla.components.feature.search.SearchUseCases
|
import mozilla.components.feature.search.SearchUseCases
|
||||||
import mozilla.components.feature.session.SessionUseCases
|
import mozilla.components.feature.session.SessionUseCases
|
||||||
import mozilla.components.feature.tabs.TabsUseCases
|
import mozilla.components.feature.tabs.TabsUseCases
|
||||||
|
import org.mozilla.fenix.test.Mockable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component group for all use cases. Use cases are provided by feature
|
* Component group for all use cases. Use cases are provided by feature
|
||||||
* modules and can be triggered by UI interactions.
|
* modules and can be triggered by UI interactions.
|
||||||
*/
|
*/
|
||||||
|
@Mockable
|
||||||
class UseCases(
|
class UseCases(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val sessionManager: SessionManager,
|
private val sessionManager: SessionManager,
|
||||||
|
|
|
@ -11,10 +11,12 @@ import mozilla.components.feature.intent.IntentProcessor
|
||||||
import mozilla.components.feature.search.SearchUseCases
|
import mozilla.components.feature.search.SearchUseCases
|
||||||
import mozilla.components.feature.session.SessionUseCases
|
import mozilla.components.feature.session.SessionUseCases
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
|
import org.mozilla.fenix.test.Mockable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component group for miscellaneous components.
|
* Component group for miscellaneous components.
|
||||||
*/
|
*/
|
||||||
|
@Mockable
|
||||||
class Utilities(
|
class Utilities(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val sessionManager: SessionManager,
|
private val sessionManager: SessionManager,
|
||||||
|
|
|
@ -58,8 +58,8 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
|
||||||
private lateinit var job: Job
|
private lateinit var job: Job
|
||||||
private lateinit var bookmarkComponent: BookmarkComponent
|
private lateinit var bookmarkComponent: BookmarkComponent
|
||||||
private lateinit var signInComponent: SignInComponent
|
private lateinit var signInComponent: SignInComponent
|
||||||
private var currentRoot: BookmarkNode? = null
|
var currentRoot: BookmarkNode? = null
|
||||||
private val navigation by lazy { Navigation.findNavController(requireActivity(), R.id.container) }
|
private val navigation by lazy { Navigation.findNavController(requireView()) }
|
||||||
private val onDestinationChangedListener =
|
private val onDestinationChangedListener =
|
||||||
NavController.OnDestinationChangedListener { _, destination, args ->
|
NavController.OnDestinationChangedListener { _, destination, args ->
|
||||||
if (destination.id != R.id.bookmarkFragment ||
|
if (destination.id != R.id.bookmarkFragment ||
|
||||||
|
@ -67,6 +67,7 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
|
||||||
)
|
)
|
||||||
getManagedEmitter<BookmarkChange>().onNext(BookmarkChange.ClearSelection)
|
getManagedEmitter<BookmarkChange>().onNext(BookmarkChange.ClearSelection)
|
||||||
}
|
}
|
||||||
|
lateinit var initialJob: Job
|
||||||
|
|
||||||
override val coroutineContext: CoroutineContext
|
override val coroutineContext: CoroutineContext
|
||||||
get() = Main + job
|
get() = Main + job
|
||||||
|
@ -81,19 +82,23 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
job = Job()
|
job = Job()
|
||||||
(activity as AppCompatActivity).title = getString(R.string.library_bookmarks)
|
activity?.title = getString(R.string.library_bookmarks)
|
||||||
setHasOptionsMenu(true)
|
setHasOptionsMenu(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
(activity as AppCompatActivity).supportActionBar?.show()
|
(activity as? AppCompatActivity)?.supportActionBar?.show()
|
||||||
checkIfSignedIn()
|
checkIfSignedIn()
|
||||||
|
|
||||||
navigation.addOnDestinationChangedListener(onDestinationChangedListener)
|
navigation.addOnDestinationChangedListener(onDestinationChangedListener)
|
||||||
val currentGuid = BookmarkFragmentArgs.fromBundle(arguments!!).currentRoot.ifEmpty { BookmarkRoot.Mobile.id }
|
val currentGuid = BookmarkFragmentArgs.fromBundle(arguments!!).currentRoot.ifEmpty { BookmarkRoot.Mobile.id }
|
||||||
|
|
||||||
launch(IO) {
|
initialJob = loadInitialBookmarkFolder(currentGuid)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadInitialBookmarkFolder(currentGuid: String): Job {
|
||||||
|
return launch(IO) {
|
||||||
currentRoot = requireComponents.core.bookmarksStorage.getTree(currentGuid) as BookmarkNode
|
currentRoot = requireComponents.core.bookmarksStorage.getTree(currentGuid) as BookmarkNode
|
||||||
|
|
||||||
launch(Main) {
|
launch(Main) {
|
||||||
|
@ -322,7 +327,8 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
|
||||||
override fun onProfileUpdated(profile: Profile) {
|
override fun onProfileUpdated(profile: Profile) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSelectedBookmarks() = (bookmarkComponent.uiView as BookmarkUIView).getSelected()
|
fun getBookmarks() = (bookmarkComponent.uiView as BookmarkUIView).tree?.children
|
||||||
|
fun getSelectedBookmarks() = (bookmarkComponent.uiView as BookmarkUIView).getSelected()
|
||||||
|
|
||||||
private suspend fun deleteSelectedBookmarks(
|
private suspend fun deleteSelectedBookmarks(
|
||||||
selected: Set<BookmarkNode> = getSelectedBookmarks(),
|
selected: Set<BookmarkNode> = getSelectedBookmarks(),
|
||||||
|
|
|
@ -92,23 +92,24 @@ class BookmarkUIView(
|
||||||
fun getSelected(): Set<BookmarkNode> = bookmarkAdapter.selected
|
fun getSelected(): Set<BookmarkNode> = bookmarkAdapter.selected
|
||||||
|
|
||||||
private fun setToolbarColors(foreground: Int, background: Int) {
|
private fun setToolbarColors(foreground: Int, background: Int) {
|
||||||
val toolbar = (activity as AppCompatActivity).findViewById<Toolbar>(R.id.navigationToolbar)
|
val toolbar = activity?.findViewById<Toolbar>(R.id.navigationToolbar)
|
||||||
val colorFilter = PorterDuffColorFilter(
|
val colorFilter = PorterDuffColorFilter(
|
||||||
ContextCompat.getColor(context, foreground), PorterDuff.Mode.SRC_IN
|
ContextCompat.getColor(context, foreground), PorterDuff.Mode.SRC_IN
|
||||||
)
|
)
|
||||||
toolbar.setBackgroundColor(ContextCompat.getColor(context, background))
|
toolbar?.run {
|
||||||
toolbar.setTitleTextColor(ContextCompat.getColor(context, foreground))
|
setBackgroundColor(ContextCompat.getColor(context, background))
|
||||||
|
setTitleTextColor(ContextCompat.getColor(context, foreground))
|
||||||
themeToolbar(
|
themeToolbar(
|
||||||
toolbar, foreground,
|
toolbar, foreground,
|
||||||
background, colorFilter
|
background, colorFilter
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setUIForSelectingMode(
|
private fun setUIForSelectingMode(
|
||||||
mode: BookmarkState.Mode.Selecting
|
mode: BookmarkState.Mode.Selecting
|
||||||
) {
|
) {
|
||||||
(activity as? AppCompatActivity)?.title =
|
activity?.title =
|
||||||
context.getString(R.string.bookmarks_multi_select_title, mode.selectedItems.size)
|
context.getString(R.string.bookmarks_multi_select_title, mode.selectedItems.size)
|
||||||
setToolbarColors(
|
setToolbarColors(
|
||||||
R.color.white_color,
|
R.color.white_color,
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
import org.mozilla.fenix.components.Components
|
||||||
|
import org.mozilla.fenix.components.TestComponents
|
||||||
|
|
||||||
|
class TestApplication : FenixApplication() {
|
||||||
|
|
||||||
|
override val components: Components
|
||||||
|
get() = TestComponents(this)
|
||||||
|
|
||||||
|
override fun setupApplication() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
/* 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.components
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import mozilla.components.browser.storage.sync.PlacesBookmarksStorage
|
||||||
|
import mozilla.components.browser.storage.sync.PlacesHistoryStorage
|
||||||
|
import mozilla.components.feature.sync.BackgroundSyncManager
|
||||||
|
|
||||||
|
class TestBackgroundServices(
|
||||||
|
context: Context,
|
||||||
|
historyStorage: PlacesHistoryStorage,
|
||||||
|
bookmarksStorage: PlacesBookmarksStorage
|
||||||
|
) : BackgroundServices(context, historyStorage, bookmarksStorage) {
|
||||||
|
override val syncManager = BackgroundSyncManager("")
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package org.mozilla.fenix.components
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import io.mockk.mockk
|
||||||
|
|
||||||
|
class TestComponents(private val context: Context) : Components(context) {
|
||||||
|
override val backgroundServices by lazy {
|
||||||
|
mockk<BackgroundServices>(relaxed = true)
|
||||||
|
}
|
||||||
|
override val services by lazy { Services(backgroundServices.accountManager, useCases.tabsUseCases) }
|
||||||
|
override val core by lazy { TestCore(context) }
|
||||||
|
override val search by lazy { Search(context) }
|
||||||
|
override val useCases by lazy { UseCases(context, core.sessionManager, search.searchEngineManager) }
|
||||||
|
override val utils by lazy {
|
||||||
|
Utilities(
|
||||||
|
context,
|
||||||
|
core.sessionManager,
|
||||||
|
useCases.sessionUseCases,
|
||||||
|
useCases.searchUseCases
|
||||||
|
)
|
||||||
|
}
|
||||||
|
override val analytics by lazy { Analytics(context) }
|
||||||
|
override val storage by lazy { Storage(context) }
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
/* 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.components
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import io.mockk.mockk
|
||||||
|
import kotlinx.coroutines.ObsoleteCoroutinesApi
|
||||||
|
import mozilla.components.browser.engine.gecko.GeckoEngine
|
||||||
|
import mozilla.components.browser.session.SessionManager
|
||||||
|
import org.mozilla.geckoview.GeckoRuntime
|
||||||
|
|
||||||
|
@ObsoleteCoroutinesApi
|
||||||
|
class TestCore(private val context: Context) : Core(context) {
|
||||||
|
|
||||||
|
override val runtime = mockk<GeckoRuntime>(relaxed = true)
|
||||||
|
override val engine = mockk<GeckoEngine>(relaxed = true)
|
||||||
|
override val sessionManager = SessionManager(engine)
|
||||||
|
}
|
|
@ -16,11 +16,11 @@ import io.mockk.mockkStatic
|
||||||
import io.mockk.slot
|
import io.mockk.slot
|
||||||
import io.mockk.spyk
|
import io.mockk.spyk
|
||||||
import io.mockk.verify
|
import io.mockk.verify
|
||||||
import org.junit.jupiter.api.Test
|
import junit.framework.Assert.assertEquals
|
||||||
|
import junit.framework.Assert.assertNull
|
||||||
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.junit.jupiter.api.Assertions.assertEquals
|
import org.junit.Test
|
||||||
import org.junit.jupiter.api.Assertions.assertNull
|
|
||||||
import org.mockito.ArgumentMatchers.any
|
import org.mockito.ArgumentMatchers.any
|
||||||
import org.mockito.ArgumentMatchers.anyString
|
import org.mockito.ArgumentMatchers.anyString
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
|
@ -14,8 +14,8 @@ import io.reactivex.Observer
|
||||||
import io.reactivex.observers.TestObserver
|
import io.reactivex.observers.TestObserver
|
||||||
import mozilla.components.concept.storage.BookmarkNode
|
import mozilla.components.concept.storage.BookmarkNode
|
||||||
import mozilla.components.concept.storage.BookmarkNodeType
|
import mozilla.components.concept.storage.BookmarkNodeType
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.Before
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.Test
|
||||||
import org.mozilla.fenix.TestUtils.setRxSchedulers
|
import org.mozilla.fenix.TestUtils.setRxSchedulers
|
||||||
|
|
||||||
internal class BookmarkAdapterTest {
|
internal class BookmarkAdapterTest {
|
||||||
|
@ -23,7 +23,7 @@ internal class BookmarkAdapterTest {
|
||||||
private lateinit var bookmarkAdapter: BookmarkAdapter
|
private lateinit var bookmarkAdapter: BookmarkAdapter
|
||||||
private lateinit var emitter: Observer<BookmarkAction>
|
private lateinit var emitter: Observer<BookmarkAction>
|
||||||
|
|
||||||
@BeforeEach
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
setRxSchedulers()
|
setRxSchedulers()
|
||||||
emitter = TestObserver<BookmarkAction>()
|
emitter = TestObserver<BookmarkAction>()
|
||||||
|
|
|
@ -13,8 +13,8 @@ import io.reactivex.observers.TestObserver
|
||||||
import mozilla.appservices.places.BookmarkRoot
|
import mozilla.appservices.places.BookmarkRoot
|
||||||
import mozilla.components.concept.storage.BookmarkNode
|
import mozilla.components.concept.storage.BookmarkNode
|
||||||
import mozilla.components.concept.storage.BookmarkNodeType
|
import mozilla.components.concept.storage.BookmarkNodeType
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.Before
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.Test
|
||||||
import org.mozilla.fenix.TestUtils
|
import org.mozilla.fenix.TestUtils
|
||||||
import org.mozilla.fenix.mvi.ActionBusFactory
|
import org.mozilla.fenix.mvi.ActionBusFactory
|
||||||
import org.mozilla.fenix.mvi.UIView
|
import org.mozilla.fenix.mvi.UIView
|
||||||
|
@ -26,7 +26,7 @@ class BookmarkComponentTest {
|
||||||
private lateinit var bookmarkObserver: TestObserver<BookmarkState>
|
private lateinit var bookmarkObserver: TestObserver<BookmarkState>
|
||||||
private lateinit var emitter: Observer<BookmarkChange>
|
private lateinit var emitter: Observer<BookmarkChange>
|
||||||
|
|
||||||
@BeforeEach
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
MockKAnnotations.init(this)
|
MockKAnnotations.init(this)
|
||||||
TestUtils.setRxSchedulers()
|
TestUtils.setRxSchedulers()
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
/* 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.library.bookmarks
|
||||||
|
|
||||||
|
import androidx.fragment.app.testing.FragmentScenario
|
||||||
|
import androidx.fragment.app.testing.launchFragmentInContainer
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import androidx.navigation.Navigation
|
||||||
|
import io.mockk.Runs
|
||||||
|
import io.mockk.every
|
||||||
|
import io.mockk.just
|
||||||
|
import io.mockk.mockk
|
||||||
|
import kotlinx.coroutines.ObsoleteCoroutinesApi
|
||||||
|
import mozilla.appservices.places.BookmarkRoot
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.TestApplication
|
||||||
|
import org.mozilla.fenix.TestUtils
|
||||||
|
import org.robolectric.RobolectricTestRunner
|
||||||
|
import org.robolectric.annotation.Config
|
||||||
|
|
||||||
|
@ObsoleteCoroutinesApi
|
||||||
|
@RunWith(RobolectricTestRunner::class)
|
||||||
|
@Config(application = TestApplication::class)
|
||||||
|
class BookmarkFragmentTest {
|
||||||
|
|
||||||
|
private lateinit var scenario: FragmentScenario<BookmarkFragment>
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
TestUtils.setRxSchedulers()
|
||||||
|
|
||||||
|
val mockNavController = mockk<NavController>()
|
||||||
|
every { mockNavController.addOnDestinationChangedListener(any()) } just Runs
|
||||||
|
|
||||||
|
val args = BookmarkFragmentArgs(BookmarkRoot.Mobile.id).toBundle()
|
||||||
|
scenario =
|
||||||
|
launchFragmentInContainer<BookmarkFragment>(fragmentArgs = args, themeResId = R.style.NormalTheme) {
|
||||||
|
BookmarkFragment().also { fragment ->
|
||||||
|
fragment.viewLifecycleOwnerLiveData.observeForever {
|
||||||
|
if (it != null) {
|
||||||
|
Navigation.setViewNavController(fragment.requireView(), mockNavController)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test initial bookmarks fragment ui`() {
|
||||||
|
scenario.onFragment { fragment ->
|
||||||
|
assertEquals(fragment.getString(R.string.library_bookmarks), fragment.activity?.title)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,8 +10,8 @@ import io.mockk.mockk
|
||||||
import io.mockk.spyk
|
import io.mockk.spyk
|
||||||
import io.reactivex.Observer
|
import io.reactivex.Observer
|
||||||
import io.reactivex.observers.TestObserver
|
import io.reactivex.observers.TestObserver
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.Before
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.Test
|
||||||
import org.mozilla.fenix.TestUtils.bus
|
import org.mozilla.fenix.TestUtils.bus
|
||||||
import org.mozilla.fenix.TestUtils.owner
|
import org.mozilla.fenix.TestUtils.owner
|
||||||
import org.mozilla.fenix.TestUtils.setRxSchedulers
|
import org.mozilla.fenix.TestUtils.setRxSchedulers
|
||||||
|
@ -25,7 +25,7 @@ class HistoryComponentTest {
|
||||||
private lateinit var historyObserver: TestObserver<HistoryState>
|
private lateinit var historyObserver: TestObserver<HistoryState>
|
||||||
private lateinit var emitter: Observer<HistoryChange>
|
private lateinit var emitter: Observer<HistoryChange>
|
||||||
|
|
||||||
@BeforeEach
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
MockKAnnotations.init(this)
|
MockKAnnotations.init(this)
|
||||||
setRxSchedulers()
|
setRxSchedulers()
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
/* 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.test
|
|
||||||
|
|
||||||
annotation class Mockable
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
/* 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.test
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotate a class with [OpenClass] to open a class for mocking purposes while keeping it final in release builds
|
||||||
|
*/
|
||||||
|
@Target(AnnotationTarget.ANNOTATION_CLASS)
|
||||||
|
annotation class OpenClass
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotate a class with [Mockable] to make it extensible in debug builds
|
||||||
|
*/
|
||||||
|
@OpenClass
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
annotation class Mockable
|
|
@ -23,15 +23,17 @@ private object Versions {
|
||||||
const val androidx_fragment = "1.1.0-alpha07"
|
const val androidx_fragment = "1.1.0-alpha07"
|
||||||
const val androidx_navigation = "2.1.0-alpha02"
|
const val androidx_navigation = "2.1.0-alpha02"
|
||||||
const val androidx_recyclerview = "1.1.0-alpha04"
|
const val androidx_recyclerview = "1.1.0-alpha04"
|
||||||
|
const val androidx_testing = "1.1.0-alpha07"
|
||||||
|
|
||||||
const val appservices_gradle_plugin = "0.4.4"
|
const val appservices_gradle_plugin = "0.4.4"
|
||||||
const val mozilla_android_components = "0.52.0-SNAPSHOT"
|
const val mozilla_android_components = "0.52.0-SNAPSHOT"
|
||||||
|
const val mozilla_appservices = "0.27.0"
|
||||||
|
|
||||||
const val autodispose = "1.1.0"
|
const val autodispose = "1.1.0"
|
||||||
const val adjust = "4.11.4"
|
const val adjust = "4.11.4"
|
||||||
const val installreferrer = "1.0"
|
const val installreferrer = "1.0"
|
||||||
|
|
||||||
const val junit_jupiter = "5.3.2"
|
const val junit = "4.12"
|
||||||
const val mockito = "2.23.0"
|
const val mockito = "2.23.0"
|
||||||
const val mockk = "1.9.kotlin12"
|
const val mockk = "1.9.kotlin12"
|
||||||
const val glide = "4.9.0"
|
const val glide = "4.9.0"
|
||||||
|
@ -44,7 +46,7 @@ private object Versions {
|
||||||
const val tools_test_rules = "1.1.1"
|
const val tools_test_rules = "1.1.1"
|
||||||
const val tools_test_runner = "1.1.1"
|
const val tools_test_runner = "1.1.1"
|
||||||
const val uiautomator = "2.1.3"
|
const val uiautomator = "2.1.3"
|
||||||
const val test_tools = "1.0.2"
|
const val robolectric = "4.2"
|
||||||
|
|
||||||
const val google_ads_id_version = "16.0.0"
|
const val google_ads_id_version = "16.0.0"
|
||||||
}
|
}
|
||||||
|
@ -146,10 +148,7 @@ object Deps {
|
||||||
const val adjust = "com.adjust.sdk:adjust-android:${Versions.adjust}"
|
const val adjust = "com.adjust.sdk:adjust-android:${Versions.adjust}"
|
||||||
const val installreferrer = "com.android.installreferrer:installreferrer:${Versions.installreferrer}"
|
const val installreferrer = "com.android.installreferrer:installreferrer:${Versions.installreferrer}"
|
||||||
|
|
||||||
const val junit_jupiter_api = "org.junit.jupiter:junit-jupiter-api:${Versions.junit_jupiter}"
|
const val junit = "junit:junit:${Versions.junit}"
|
||||||
const val junit_jupiter_params = "org.junit.jupiter:junit-jupiter-params:${Versions.junit_jupiter}"
|
|
||||||
const val junit_jupiter_engine = "org.junit.jupiter:junit-jupiter-engine:${Versions.junit_jupiter}"
|
|
||||||
|
|
||||||
const val mockito_core = "org.mockito:mockito-core:${Versions.mockito}"
|
const val mockito_core = "org.mockito:mockito-core:${Versions.mockito}"
|
||||||
const val mockito_android = "org.mockito:mockito-android:${Versions.mockito}"
|
const val mockito_android = "org.mockito:mockito-android:${Versions.mockito}"
|
||||||
const val mockk = "io.mockk:mockk:${Versions.mockk}"
|
const val mockk = "io.mockk:mockk:${Versions.mockk}"
|
||||||
|
@ -167,6 +166,10 @@ object Deps {
|
||||||
const val tools_test_rules = "com.android.support.test:rules:${Versions.tools_test_rules}"
|
const val tools_test_rules = "com.android.support.test:rules:${Versions.tools_test_rules}"
|
||||||
const val tools_test_runner = "com.android.support.test:runner:${Versions.tools_test_runner}"
|
const val tools_test_runner = "com.android.support.test:runner:${Versions.tools_test_runner}"
|
||||||
const val uiautomator = "com.android.support.test.uiautomator:uiautomator-v18:${Versions.uiautomator}"
|
const val uiautomator = "com.android.support.test.uiautomator:uiautomator-v18:${Versions.uiautomator}"
|
||||||
|
const val robolectric = "org.robolectric:robolectric:${Versions.robolectric}"
|
||||||
|
const val fragment_testing = "androidx.fragment:fragment-testing:${Versions.androidx_testing}"
|
||||||
|
const val megazord_forUnitTests = "org.mozilla.appservices:fenix-megazord-forUnitTests:${Versions.mozilla_appservices}"
|
||||||
|
const val places_forUnitTests = "org.mozilla.appservices:places-forUnitTests:${Versions.mozilla_appservices}"
|
||||||
|
|
||||||
const val google_ads_id = "com.google.android.gms:play-services-ads-identifier:${Versions.google_ads_id_version}"
|
const val google_ads_id = "com.google.android.gms:play-services-ads-identifier:${Versions.google_ads_id_version}"
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,4 +16,5 @@ kotlin.code.style=official
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
android.enableR8=true
|
android.enableR8=true
|
||||||
android.enableR8.fullMode=true
|
android.enableR8.fullMode=true
|
||||||
|
android.enableUnitTestBinaryResources=true
|
Loading…
Reference in New Issue