diff --git a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt index 321a62481..9e5826def 100644 --- a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt +++ b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt @@ -112,7 +112,7 @@ open class FenixApplication : Application() { components.core.sessionManager.register(NotificationSessionObserver(this)) - if ((System.currentTimeMillis() - this.settings().lastPlacesStorageMaintenance) > ONE_DAY_MILLIS) { + if ((System.currentTimeMillis() - settings().lastPlacesStorageMaintenance) > ONE_DAY_MILLIS) { runStorageMaintenance() } } @@ -123,7 +123,7 @@ open class FenixApplication : Application() { // run maintenance on one - arbitrarily using bookmarks. components.core.bookmarksStorage.runMaintenance() } - this.settings().lastPlacesStorageMaintenance = System.currentTimeMillis() + settings().lastPlacesStorageMaintenance = System.currentTimeMillis() } private fun registerRxExceptionHandling() { diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkFragment.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkFragment.kt index 57262be16..270460583 100644 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkFragment.kt @@ -13,7 +13,6 @@ import android.view.View import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.activityViewModels -import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import androidx.navigation.NavDirections @@ -29,6 +28,7 @@ import kotlinx.coroutines.ObsoleteCoroutinesApi import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.withContext import mozilla.appservices.places.BookmarkRoot import mozilla.components.concept.storage.BookmarkNode import mozilla.components.concept.storage.BookmarkNodeType @@ -49,12 +49,11 @@ import org.mozilla.fenix.ext.urlToTrimmedHost import org.mozilla.fenix.library.LibraryPageFragment import org.mozilla.fenix.utils.allowUndo -@SuppressWarnings("TooManyFunctions", "LargeClass") -class BookmarkFragment : LibraryPageFragment(), BackHandler, AccountObserver { +@Suppress("TooManyFunctions", "LargeClass") +class BookmarkFragment : LibraryPageFragment(), BackHandler { private lateinit var bookmarkStore: BookmarkFragmentStore private lateinit var bookmarkView: BookmarkView - private lateinit var signInView: SignInView private lateinit var bookmarkInteractor: BookmarkFragmentInteractor private val sharedViewModel: BookmarksSharedViewModel by activityViewModels { @@ -62,10 +61,14 @@ class BookmarkFragment : LibraryPageFragment(), BackHandler, Accou } private val desktopFolders by lazy { DesktopFolders(context!!, showMobileRoot = false) } - var currentRoot: BookmarkNode? = null lateinit var initialJob: Job private var pendingBookmarkDeletionJob: (suspend () -> Unit)? = null private var pendingBookmarksToDelete: MutableSet = mutableSetOf() + private val refreshOnSignInListener = object : AccountObserver { + override fun onAuthenticated(account: OAuthAccount, authType: AuthType) { + lifecycleScope.launch { refreshBookmarks() } + } + } private val metrics get() = context?.components?.analytics?.metrics @@ -92,7 +95,9 @@ class BookmarkFragment : LibraryPageFragment(), BackHandler, Accou ) bookmarkView = BookmarkView(view.bookmarkLayout, bookmarkInteractor) - signInView = SignInView(view.bookmarkLayout, bookmarkInteractor) + + val signInView = SignInView(view.bookmarkLayout, findNavController()) + sharedViewModel.signedIn.observe(viewLifecycleOwner, signInView) lifecycle.addObserver( BookmarkDeselectNavigationListener( @@ -112,11 +117,6 @@ class BookmarkFragment : LibraryPageFragment(), BackHandler, Accou consumeFrom(bookmarkStore) { bookmarkView.update(it) } - sharedViewModel.apply { - signedIn.observe(this@BookmarkFragment, Observer { - signInView.update(it) - }) - } } override fun onCreate(savedInstanceState: Bundle?) { @@ -129,7 +129,10 @@ class BookmarkFragment : LibraryPageFragment(), BackHandler, Accou super.onResume() (activity as? AppCompatActivity)?.supportActionBar?.show() - checkIfSignedIn() + context?.components?.backgroundServices?.accountManager?.let { accountManager -> + sharedViewModel.observeAccountManager(accountManager, owner = this) + accountManager.register(refreshOnSignInListener, owner = this) + } val currentGuid = BookmarkFragmentArgs.fromBundle(arguments!!).currentRoot.ifEmpty { BookmarkRoot.Mobile.id } @@ -137,26 +140,20 @@ class BookmarkFragment : LibraryPageFragment(), BackHandler, Accou } private fun loadInitialBookmarkFolder(currentGuid: String): Job { - return viewLifecycleOwner.lifecycleScope.launch(IO) { - currentRoot = requireContext().bookmarkStorage - .getTree(currentGuid)?.let { desktopFolders.withOptionalDesktopFolders(it) }!! + return viewLifecycleOwner.lifecycleScope.launch(Main) { + val currentRoot = withContext(IO) { + requireContext().bookmarkStorage + .getTree(currentGuid) + ?.let { desktopFolders.withOptionalDesktopFolders(it) }!! + } - if (!isActive) return@launch - launch(Main) { - bookmarkInteractor.onBookmarksChanged(currentRoot!!) + if (isActive) { + bookmarkInteractor.onBookmarksChanged(currentRoot) sharedViewModel.selectedFolder = currentRoot } } } - private fun checkIfSignedIn() { - context?.components?.backgroundServices?.accountManager?.let { - it.register(this, owner = this) - it.authenticatedAccount()?.let { bookmarkInteractor.onSignedIn() } - ?: bookmarkInteractor.onSignedOut() - } - } - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { when (val mode = bookmarkStore.state.mode) { BookmarkFragmentState.Mode.Normal -> { @@ -229,17 +226,6 @@ class BookmarkFragment : LibraryPageFragment(), BackHandler, Accou return bookmarkView.onBackPressed() } - override fun onAuthenticated(account: OAuthAccount, authType: AuthType) { - bookmarkInteractor.onSignedIn() - lifecycleScope.launch { - refreshBookmarks() - } - } - - override fun onLoggedOut() { - bookmarkInteractor.onSignedOut() - } - private suspend fun refreshBookmarks() { // The bookmark tree in our 'state' can be null - meaning, no bookmark tree has been selected. // If that's the case, we don't know what node to refresh, and so we bail out. @@ -274,7 +260,7 @@ class BookmarkFragment : LibraryPageFragment(), BackHandler, Accou private fun deleteMulti(selected: Set, eventType: Event = Event.RemoveBookmarks) { pendingBookmarksToDelete.addAll(selected) - val bookmarkTree = currentRoot!! - pendingBookmarksToDelete + val bookmarkTree = sharedViewModel.selectedFolder!! - pendingBookmarksToDelete bookmarkInteractor.onBookmarksChanged(bookmarkTree) val deleteOperation: (suspend () -> Unit) = { diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkFragmentInteractor.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkFragmentInteractor.kt index c8382707b..0257b88ba 100644 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkFragmentInteractor.kt +++ b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkFragmentInteractor.kt @@ -26,7 +26,7 @@ class BookmarkFragmentInteractor( private val viewModel: BookmarksSharedViewModel, private val bookmarksController: BookmarkController, private val metrics: MetricController -) : BookmarkViewInteractor, SignInInteractor { +) : BookmarkViewInteractor { override fun onBookmarksChanged(node: BookmarkNode) { bookmarkStore.dispatch(BookmarkFragmentAction.Change(node)) @@ -96,18 +96,6 @@ class BookmarkFragmentInteractor( bookmarksController.handleBackPressed() } - override fun onSignInPressed() { - bookmarksController.handleSigningIn() - } - - override fun onSignedIn() { - viewModel.signedIn.postValue(true) - } - - override fun onSignedOut() { - viewModel.signedIn.postValue(false) - } - override fun open(item: BookmarkNode) { Do exhaustive when (item.type) { BookmarkNodeType.ITEM -> { diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarksSharedViewModel.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarksSharedViewModel.kt index 4cf1fd500..9eeaafcab 100644 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarksSharedViewModel.kt +++ b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarksSharedViewModel.kt @@ -4,11 +4,53 @@ package org.mozilla.fenix.library.bookmarks +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import mozilla.components.concept.storage.BookmarkNode +import mozilla.components.concept.sync.AccountObserver +import mozilla.components.concept.sync.AuthType +import mozilla.components.concept.sync.OAuthAccount +import mozilla.components.service.fxa.manager.FxaAccountManager -class BookmarksSharedViewModel : ViewModel() { - var signedIn = MutableLiveData().apply { postValue(true) } +/** + * [ViewModel] that shares data between various bookmarks fragments. + */ +class BookmarksSharedViewModel : ViewModel(), AccountObserver { + + private val signedInMutable = MutableLiveData(true) + + /** + * Whether or not the user is signed in. + */ + val signedIn: LiveData get() = signedInMutable + + /** + * The currently selected bookmark root. + */ var selectedFolder: BookmarkNode? = null + + /** + * Updates the [signedIn] boolean once the account observer sees that the user logged in. + */ + override fun onAuthenticated(account: OAuthAccount, authType: AuthType) { + signedInMutable.postValue(true) + } + + /** + * Updates the [signedIn] boolean once the account observer sees that the user logged out. + */ + override fun onLoggedOut() { + signedInMutable.postValue(false) + } + + fun observeAccountManager(accountManager: FxaAccountManager, owner: LifecycleOwner) { + accountManager.register(this, owner = owner) + if (accountManager.authenticatedAccount() != null) { + signedInMutable.postValue(true) + } else { + signedInMutable.postValue(false) + } + } } diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/SignInView.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/SignInView.kt index 80693a1f7..f135e174b 100644 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/SignInView.kt +++ b/app/src/main/java/org/mozilla/fenix/library/bookmarks/SignInView.kt @@ -7,20 +7,18 @@ package org.mozilla.fenix.library.bookmarks import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.view.isGone +import androidx.lifecycle.Observer +import androidx.navigation.NavController import com.google.android.material.button.MaterialButton import kotlinx.android.extensions.LayoutContainer import org.mozilla.fenix.R - -interface SignInInteractor { - fun onSignInPressed() - fun onSignedIn() - fun onSignedOut() -} +import org.mozilla.fenix.ext.components class SignInView( private val container: ViewGroup, - private val interactor: SignInInteractor -) : LayoutContainer { + private val navController: NavController +) : LayoutContainer, Observer { override val containerView: View? get() = container @@ -31,11 +29,14 @@ class SignInView( init { view.setOnClickListener { - interactor.onSignInPressed() + view.context.components.services.launchPairingSignIn(view.context, navController) } } - fun update(signedIn: Boolean) { - view.visibility = if (signedIn) View.GONE else View.VISIBLE + /** + * Hides or shows the sign-in button. Should be called whenever the sign-in state changes. + */ + override fun onChanged(signedIn: Boolean) { + view.isGone = signedIn } } diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/edit/EditBookmarkFragment.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/edit/EditBookmarkFragment.kt index 99534ce4d..34a1058e3 100644 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/edit/EditBookmarkFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/library/bookmarks/edit/EditBookmarkFragment.kt @@ -32,6 +32,7 @@ import kotlinx.android.synthetic.main.fragment_edit_bookmark.* import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import mozilla.appservices.places.UrlParseFailed import mozilla.components.concept.storage.BookmarkInfo import mozilla.components.concept.storage.BookmarkNode @@ -75,40 +76,40 @@ class EditBookmarkFragment : Fragment() { activity?.supportActionBar?.show() guidToEdit = EditBookmarkFragmentArgs.fromBundle(arguments!!).guidToEdit - lifecycleScope.launch(IO) { + lifecycleScope.launch(Main) { val context = requireContext() - bookmarkNode = context.components.core.bookmarksStorage.getTree(guidToEdit) - bookmarkParent = sharedViewModel.selectedFolder - ?: bookmarkNode?.parentGuid - ?.let { context.components.core.bookmarksStorage.getTree(it) } - ?.let { DesktopFolders(context, showMobileRoot = true).withRootTitle(it) } - launch(Main) { - when (bookmarkNode?.type) { - BookmarkNodeType.FOLDER -> { - activity?.title = getString(R.string.edit_bookmark_folder_fragment_title) - bookmarkUrlEdit.visibility = View.GONE - bookmarkUrlLabel.visibility = View.GONE - } - BookmarkNodeType.ITEM -> { - activity?.title = getString(R.string.edit_bookmark_fragment_title) - } - else -> throw IllegalArgumentException() + withContext(IO) { + val bookmarksStorage = context.components.core.bookmarksStorage + bookmarkNode = bookmarksStorage.getTree(guidToEdit) + bookmarkParent = sharedViewModel.selectedFolder + ?: bookmarkNode?.parentGuid + ?.let { bookmarksStorage.getTree(it) } + ?.let { DesktopFolders(context, showMobileRoot = true).withRootTitle(it) } + } + + when (bookmarkNode?.type) { + BookmarkNodeType.FOLDER -> { + activity?.title = getString(R.string.edit_bookmark_folder_fragment_title) + bookmarkUrlEdit.visibility = View.GONE + bookmarkUrlLabel.visibility = View.GONE } + BookmarkNodeType.ITEM -> { + activity?.title = getString(R.string.edit_bookmark_fragment_title) + } + else -> throw IllegalArgumentException() + } - if (bookmarkNode != null) { - bookmarkNameEdit.setText(bookmarkNode!!.title) - bookmarkUrlEdit.setText(bookmarkNode!!.url) + bookmarkNode?.let { bookmarkNode -> + bookmarkNameEdit.setText(bookmarkNode.title) + bookmarkUrlEdit.setText(bookmarkNode.url) - if (sharedViewModel.selectedFolder != null && bookmarkNode?.title != null) { - val bookmarkPair = Pair(bookmarkNode?.title, bookmarkNode?.url) - updateBookmarkNode(bookmarkPair) - } + if (sharedViewModel.selectedFolder != null && bookmarkNode.title != null) { + updateBookmarkNode(bookmarkNode.title to bookmarkNode.url) } } bookmarkParent?.let { node -> - launch(Main) { bookmarkFolderSelector.text = node.title bookmarkFolderSelector.setOnClickListener { sharedViewModel.selectedFolder = null @@ -120,7 +121,6 @@ class EditBookmarkFragment : Fragment() { } } } - } updateBookmarkFromObservableInput() } diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/selectfolder/SelectBookmarkFolderFragment.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/selectfolder/SelectBookmarkFolderFragment.kt index 795fa5282..929fef153 100644 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/selectfolder/SelectBookmarkFolderFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/library/bookmarks/selectfolder/SelectBookmarkFolderFragment.kt @@ -14,7 +14,6 @@ import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels -import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController @@ -27,9 +26,6 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import mozilla.appservices.places.BookmarkRoot import mozilla.components.concept.storage.BookmarkNode -import mozilla.components.concept.sync.AccountObserver -import mozilla.components.concept.sync.AuthType -import mozilla.components.concept.sync.OAuthAccount import org.mozilla.fenix.R import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.nav @@ -38,16 +34,12 @@ import org.mozilla.fenix.library.bookmarks.BookmarksSharedViewModel import org.mozilla.fenix.library.bookmarks.DesktopFolders import org.mozilla.fenix.library.bookmarks.SignInView -@SuppressWarnings("TooManyFunctions") -class SelectBookmarkFolderFragment : Fragment(), AccountObserver { +class SelectBookmarkFolderFragment : Fragment() { private val sharedViewModel: BookmarksSharedViewModel by activityViewModels { ViewModelProvider.NewInstanceFactory() // this is a workaround for #4652 } - private var folderGuid: String? = null private var bookmarkNode: BookmarkNode? = null - private lateinit var signInView: SignInView - private lateinit var bookmarkInteractor: SelectBookmarkFolderInteractor override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -57,30 +49,19 @@ class SelectBookmarkFolderFragment : Fragment(), AccountObserver { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { val view = inflater.inflate(R.layout.fragment_select_bookmark_folder, container, false) - bookmarkInteractor = SelectBookmarkFolderInteractor( - context!!, - findNavController(), - sharedViewModel - ) - signInView = SignInView(view.selectBookmarkLayout, bookmarkInteractor) + val signInView = SignInView(view.selectBookmarkLayout, findNavController()) + sharedViewModel.signedIn.observe(viewLifecycleOwner, signInView) return view } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - sharedViewModel.signedIn.observe(this@SelectBookmarkFolderFragment, Observer { - signInView.update(it) - }) - } - override fun onResume() { super.onResume() activity?.title = getString(R.string.bookmark_select_folder_fragment_label) (activity as? AppCompatActivity)?.supportActionBar?.show() - folderGuid = SelectBookmarkFolderFragmentArgs.fromBundle(arguments!!).folderGuid ?: BookmarkRoot.Root.id - checkIfSignedIn() + val accountManager = requireComponents.backgroundServices.accountManager + sharedViewModel.observeAccountManager(accountManager, owner = this) lifecycleScope.launch(Main) { bookmarkNode = withContext(IO) { @@ -96,13 +77,6 @@ class SelectBookmarkFolderFragment : Fragment(), AccountObserver { } } - private fun checkIfSignedIn() { - val accountManager = requireComponents.backgroundServices.accountManager - accountManager.register(this, owner = this) - accountManager.authenticatedAccount()?.let { bookmarkInteractor.onSignedIn() } - ?: bookmarkInteractor.onSignedOut() - } - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { val args: SelectBookmarkFolderFragmentArgs by navArgs() if (!args.visitedAddBookmark) { @@ -125,11 +99,4 @@ class SelectBookmarkFolderFragment : Fragment(), AccountObserver { else -> super.onOptionsItemSelected(item) } } - override fun onAuthenticated(account: OAuthAccount, authType: AuthType) { - bookmarkInteractor.onSignedIn() - } - - override fun onLoggedOut() { - bookmarkInteractor.onSignedOut() - } } diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/selectfolder/SelectBookmarkFolderInteractor.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/selectfolder/SelectBookmarkFolderInteractor.kt deleted file mode 100644 index fecec4567..000000000 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/selectfolder/SelectBookmarkFolderInteractor.kt +++ /dev/null @@ -1,30 +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.library.bookmarks.selectfolder - -import android.content.Context -import androidx.navigation.NavController -import org.mozilla.fenix.ext.components -import org.mozilla.fenix.library.bookmarks.BookmarksSharedViewModel -import org.mozilla.fenix.library.bookmarks.SignInInteractor - -class SelectBookmarkFolderInteractor( - private val context: Context, - private val navController: NavController, - private val sharedViewModel: BookmarksSharedViewModel -) : SignInInteractor { - - override fun onSignInPressed() { - context.components.services.launchPairingSignIn(context, navController) - } - - override fun onSignedIn() { - sharedViewModel.signedIn.postValue(true) - } - - override fun onSignedOut() { - sharedViewModel.signedIn.postValue(false) - } -} diff --git a/app/src/test/java/org/mozilla/fenix/library/bookmarks/BookmarkFragmentInteractorTest.kt b/app/src/test/java/org/mozilla/fenix/library/bookmarks/BookmarkFragmentInteractorTest.kt index 5d3b5edb9..2fb7a8cb2 100644 --- a/app/src/test/java/org/mozilla/fenix/library/bookmarks/BookmarkFragmentInteractorTest.kt +++ b/app/src/test/java/org/mozilla/fenix/library/bookmarks/BookmarkFragmentInteractorTest.kt @@ -217,31 +217,4 @@ class BookmarkFragmentInteractorTest { bookmarkController.handleBackPressed() } } - - @Test - fun `clicked sign in on bookmarks screen`() { - interactor.onSignInPressed() - - verify { - bookmarkController.handleSigningIn() - } - } - - @Test - fun `got signed in signal on bookmarks screen`() { - interactor.onSignedIn() - - verify { - sharedViewModel.signedIn.postValue(true) - } - } - - @Test - fun `got signed out signal on bookmarks screen`() { - interactor.onSignedOut() - - verify { - sharedViewModel.signedIn.postValue(false) - } - } } diff --git a/app/src/test/java/org/mozilla/fenix/library/bookmarks/BookmarksSharedViewModelTest.kt b/app/src/test/java/org/mozilla/fenix/library/bookmarks/BookmarksSharedViewModelTest.kt new file mode 100644 index 000000000..f68061325 --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/library/bookmarks/BookmarksSharedViewModelTest.kt @@ -0,0 +1,63 @@ +/* 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.lifecycle.LifecycleOwner +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.ObsoleteCoroutinesApi +import mozilla.components.concept.sync.AuthType +import mozilla.components.service.fxa.manager.FxaAccountManager +import mozilla.components.support.test.mock +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.TestApplication +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config + +@ObsoleteCoroutinesApi +@RunWith(RobolectricTestRunner::class) +@Config(application = TestApplication::class) +internal class BookmarksSharedViewModelTest { + + private lateinit var viewModel: BookmarksSharedViewModel + + @Before + fun setup() { + viewModel = BookmarksSharedViewModel() + viewModel.signedIn.observeForever { } + } + + @Test + fun `onAuthenticated and onLoggedOut modify signedIn value`() { + viewModel.onLoggedOut() + assertFalse(viewModel.signedIn.value!!) + + viewModel.onAuthenticated(mock(), AuthType.Existing) + assertTrue(viewModel.signedIn.value!!) + } + + @Test + fun `observeAccountManager registers observer`() { + val accountManager: FxaAccountManager = mockk(relaxed = true) + val lifecycleOwner: LifecycleOwner = mockk() + + every { accountManager.authenticatedAccount() } returns null + viewModel.observeAccountManager(accountManager, lifecycleOwner) + + verify { accountManager.register(viewModel, lifecycleOwner) } + assertFalse(viewModel.signedIn.value!!) + + every { accountManager.authenticatedAccount() } returns mockk() + viewModel.observeAccountManager(accountManager, lifecycleOwner) + + verify { accountManager.register(viewModel, lifecycleOwner) } + assertTrue(viewModel.signedIn.value!!) + } +}