For #17917: Use View binding in Login Exceptions

upstream-sync
codrut.topliceanu 3 years ago committed by mergify[bot]
parent c82af0a97a
commit 34e063669a

@ -11,13 +11,13 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.asLiveData import androidx.lifecycle.asLiveData
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import kotlinx.android.synthetic.main.fragment_exceptions.view.*
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.plus import kotlinx.coroutines.plus
import mozilla.components.lib.state.ext.consumeFrom import mozilla.components.lib.state.ext.consumeFrom
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.StoreProvider import org.mozilla.fenix.components.StoreProvider
import org.mozilla.fenix.databinding.FragmentExceptionsBinding
import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.ext.showToolbar
@ -39,8 +39,12 @@ class LoginExceptionsFragment : Fragment() {
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View {
val view = inflater.inflate(R.layout.fragment_exceptions, container, false) val binding = FragmentExceptionsBinding.inflate(
inflater,
container,
false
)
exceptionsStore = StoreProvider.get(this) { exceptionsStore = StoreProvider.get(this) {
ExceptionsFragmentStore( ExceptionsFragmentStore(
ExceptionsFragmentState(items = emptyList()) ExceptionsFragmentState(items = emptyList())
@ -51,11 +55,11 @@ class LoginExceptionsFragment : Fragment() {
loginExceptionStorage = requireComponents.core.loginExceptionStorage loginExceptionStorage = requireComponents.core.loginExceptionStorage
) )
exceptionsView = LoginExceptionsView( exceptionsView = LoginExceptionsView(
view.exceptionsLayout, binding.exceptionsLayout,
exceptionsInteractor exceptionsInteractor
) )
subscribeToLoginExceptions() subscribeToLoginExceptions()
return view return binding.root
} }
private fun subscribeToLoginExceptions() { private fun subscribeToLoginExceptions() {

@ -44,7 +44,7 @@ import org.mozilla.fenix.settings.logins.controller.SavedLoginsStorageController
import org.mozilla.fenix.settings.logins.createInitialLoginsListState import org.mozilla.fenix.settings.logins.createInitialLoginsListState
import org.mozilla.fenix.settings.logins.interactor.LoginDetailInteractor import org.mozilla.fenix.settings.logins.interactor.LoginDetailInteractor
import org.mozilla.fenix.settings.logins.togglePasswordReveal import org.mozilla.fenix.settings.logins.togglePasswordReveal
import org.mozilla.fenix.settings.logins.view.LoginDetailView import org.mozilla.fenix.settings.logins.view.LoginDetailsBindingDelegate
/** /**
* Displays saved login information for a single website. * Displays saved login information for a single website.
@ -56,7 +56,7 @@ class LoginDetailFragment : Fragment(R.layout.fragment_login_detail) {
private val args by navArgs<LoginDetailFragmentArgs>() private val args by navArgs<LoginDetailFragmentArgs>()
private var login: SavedLogin? = null private var login: SavedLogin? = null
private lateinit var savedLoginsStore: LoginsFragmentStore private lateinit var savedLoginsStore: LoginsFragmentStore
private lateinit var loginDetailView: LoginDetailView private lateinit var loginDetailsBindingDelegate: LoginDetailsBindingDelegate
private lateinit var interactor: LoginDetailInteractor private lateinit var interactor: LoginDetailInteractor
private lateinit var menu: Menu private lateinit var menu: Menu
private var deleteDialog: AlertDialog? = null private var deleteDialog: AlertDialog? = null
@ -76,9 +76,7 @@ class LoginDetailFragment : Fragment(R.layout.fragment_login_detail) {
createInitialLoginsListState(requireContext().settings()) createInitialLoginsListState(requireContext().settings())
) )
} }
loginDetailView = LoginDetailView( loginDetailsBindingDelegate = LoginDetailsBindingDelegate(binding)
view.findViewById(R.id.loginDetailLayout)
)
return view return view
} }
@ -99,7 +97,7 @@ class LoginDetailFragment : Fragment(R.layout.fragment_login_detail) {
interactor.onFetchLoginList(args.savedLoginId) interactor.onFetchLoginList(args.savedLoginId)
consumeFrom(savedLoginsStore) { consumeFrom(savedLoginsStore) {
loginDetailView.update(it) loginDetailsBindingDelegate.update(it)
login = savedLoginsStore.state.currentItem login = savedLoginsStore.state.currentItem
setUpCopyButtons() setUpCopyButtons()
showToolbar( showToolbar(

@ -4,18 +4,18 @@
package org.mozilla.fenix.settings.logins.view package org.mozilla.fenix.settings.logins.view
import android.view.ViewGroup import org.mozilla.fenix.databinding.FragmentLoginDetailBinding
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.fragment_login_detail.*
import org.mozilla.fenix.settings.logins.LoginsListState import org.mozilla.fenix.settings.logins.LoginsListState
/** /**
* View that contains and configures the Login Details * View that contains and configures the Login Details
*/ */
class LoginDetailView(override val containerView: ViewGroup) : LayoutContainer { class LoginDetailsBindingDelegate(
private val binding: FragmentLoginDetailBinding
) {
fun update(login: LoginsListState) { fun update(login: LoginsListState) {
webAddressText.text = login.currentItem?.origin binding.webAddressText.text = login.currentItem?.origin
usernameText.text = login.currentItem?.username binding.usernameText.text = login.currentItem?.username
passwordText.text = login.currentItem?.password binding.passwordText.text = login.currentItem?.password
} }
} }

@ -6,15 +6,14 @@ package org.mozilla.fenix.settings.logins
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import kotlinx.android.synthetic.main.fragment_login_detail.view.*
import mozilla.components.support.test.robolectric.testContext import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mozilla.fenix.R import org.mozilla.fenix.databinding.FragmentLoginDetailBinding
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.settings.logins.view.LoginDetailView import org.mozilla.fenix.settings.logins.view.LoginDetailsBindingDelegate
@RunWith(FenixRobolectricTestRunner::class) @RunWith(FenixRobolectricTestRunner::class)
class LoginDetailViewTest { class LoginDetailViewTest {
@ -36,30 +35,31 @@ class LoginDetailViewTest {
) )
private lateinit var view: ViewGroup private lateinit var view: ViewGroup
private lateinit var detailView: LoginDetailView private lateinit var binding: FragmentLoginDetailBinding
private lateinit var detailsBindingDelegate: LoginDetailsBindingDelegate
@Before @Before
fun setup() { fun setup() {
view = LayoutInflater.from(testContext).inflate(R.layout.fragment_login_detail, null) binding = FragmentLoginDetailBinding.inflate(LayoutInflater.from(testContext))
.findViewById(R.id.loginDetailLayout) view = binding.loginDetailLayout
detailView = LoginDetailView(view) detailsBindingDelegate = LoginDetailsBindingDelegate(binding)
} }
@Test @Test
fun `bind currentItem`() { fun `bind currentItem`() {
detailView.update(state) detailsBindingDelegate.update(state)
assertEquals("mozilla.org", view.webAddressText.text) assertEquals("mozilla.org", binding.webAddressText.text)
assertEquals("admin", view.usernameText.text) assertEquals("admin", binding.usernameText.text)
assertEquals("password", view.passwordText.text) assertEquals("password", binding.passwordText.text)
} }
@Test @Test
fun `bind null currentItem`() { fun `bind null currentItem`() {
detailView.update(state.copy(currentItem = null)) detailsBindingDelegate.update(state.copy(currentItem = null))
assertEquals("", view.webAddressText.text) assertEquals("", binding.webAddressText.text)
assertEquals("", view.usernameText.text) assertEquals("", binding.usernameText.text)
assertEquals("", view.passwordText.text) assertEquals("", binding.passwordText.text)
} }
} }

@ -5,16 +5,14 @@
package org.mozilla.fenix.settings.logins package org.mozilla.fenix.settings.logins
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import io.mockk.mockk import io.mockk.mockk
import io.mockk.verify import io.mockk.verify
import kotlinx.android.synthetic.main.logins_item.view.*
import mozilla.components.support.test.robolectric.testContext import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mozilla.fenix.R import org.mozilla.fenix.databinding.LoginsItemBinding
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.settings.logins.interactor.SavedLoginsInteractor import org.mozilla.fenix.settings.logins.interactor.SavedLoginsInteractor
import org.mozilla.fenix.settings.logins.view.LoginsListViewHolder import org.mozilla.fenix.settings.logins.view.LoginsListViewHolder
@ -30,36 +28,36 @@ class LoginsListViewHolderTest {
timeLastUsed = 100L timeLastUsed = 100L
) )
private lateinit var view: View
private lateinit var interactor: SavedLoginsInteractor private lateinit var interactor: SavedLoginsInteractor
private lateinit var binding: LoginsItemBinding
@Before @Before
fun setup() { fun setup() {
view = LayoutInflater.from(testContext).inflate(R.layout.logins_item, null) binding = LoginsItemBinding.inflate(LayoutInflater.from(testContext))
interactor = mockk(relaxed = true) interactor = mockk(relaxed = true)
} }
@Test @Test
fun `bind url and username`() { fun `bind url and username`() {
val holder = LoginsListViewHolder( val holder = LoginsListViewHolder(
view, binding.root,
interactor interactor
) )
holder.bind(baseLogin) holder.bind(baseLogin)
assertEquals("mozilla.org", view.webAddressView.text) assertEquals("mozilla.org", binding.webAddressView.text)
assertEquals("admin", view.usernameView.text) assertEquals("admin", binding.usernameView.text)
} }
@Test @Test
fun `call interactor on click`() { fun `call interactor on click`() {
val holder = LoginsListViewHolder( val holder = LoginsListViewHolder(
view, binding.root,
interactor interactor
) )
holder.bind(baseLogin) holder.bind(baseLogin)
view.performClick() binding.root.performClick()
verify { interactor.onItemClicked(baseLogin) } verify { interactor.onItemClicked(baseLogin) }
} }
} }

Loading…
Cancel
Save