[fenix] For https://github.com/mozilla-mobile/fenix/issues/18268, https://github.com/mozilla-mobile/fenix/issues/18269 - [Saved cards] Display a list of Saved cards fetched from the credit card storage (https://github.com/mozilla-mobile/fenix/pull/18808)
parent
71321acb0e
commit
ee594f885e
@ -0,0 +1,64 @@
|
|||||||
|
/* 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.settings.creditcards
|
||||||
|
|
||||||
|
import mozilla.components.concept.storage.CreditCard
|
||||||
|
import mozilla.components.lib.state.Action
|
||||||
|
import mozilla.components.lib.state.State
|
||||||
|
import mozilla.components.lib.state.Store
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The [Store] for holding the [CreditCardsListState] and applying [CreditCardsAction]s.
|
||||||
|
*/
|
||||||
|
class CreditCardsFragmentStore(initialState: CreditCardsListState) :
|
||||||
|
Store<CreditCardsListState, CreditCardsAction>(
|
||||||
|
initialState, ::creditCardsFragmentStateReducer
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The state for [CreditCardsManagementFragment].
|
||||||
|
*
|
||||||
|
* @property creditCards The list of [CreditCard]s to display in the credit card list.
|
||||||
|
* @property isLoading True if the credit cards are still being loaded from storage,
|
||||||
|
* otherwise false.
|
||||||
|
*/
|
||||||
|
data class CreditCardsListState(
|
||||||
|
val creditCards: List<CreditCard>,
|
||||||
|
val isLoading: Boolean = true
|
||||||
|
) : State
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actions to dispatch through the [CreditCardsFragmentStore] to modify the [CreditCardsListState]
|
||||||
|
* through the [creditCardsFragmentStateReducer].
|
||||||
|
*/
|
||||||
|
sealed class CreditCardsAction : Action {
|
||||||
|
/**
|
||||||
|
* Updates the list of credit cards with the provided [creditCards].
|
||||||
|
*
|
||||||
|
* @param creditCards The list of [CreditCard]s to display in the credit card list.
|
||||||
|
*/
|
||||||
|
data class UpdateCreditCards(val creditCards: List<CreditCard>) : CreditCardsAction()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reduces the credit cards state from the current state with the provided [action] to be performed.
|
||||||
|
*
|
||||||
|
* @param state The current credit cards state.
|
||||||
|
* @param action The action to be performed on the state.
|
||||||
|
* @return the new [CreditCardsListState] with the [action] executed.
|
||||||
|
*/
|
||||||
|
private fun creditCardsFragmentStateReducer(
|
||||||
|
state: CreditCardsListState,
|
||||||
|
action: CreditCardsAction
|
||||||
|
): CreditCardsListState {
|
||||||
|
return when (action) {
|
||||||
|
is CreditCardsAction.UpdateCreditCards -> {
|
||||||
|
state.copy(
|
||||||
|
creditCards = action.creditCards,
|
||||||
|
isLoading = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
/* 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.settings.creditcards
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import kotlinx.android.synthetic.main.fragment_saved_cards.view.*
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import mozilla.components.lib.state.ext.consumeFrom
|
||||||
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.components.StoreProvider
|
||||||
|
import org.mozilla.fenix.ext.components
|
||||||
|
import org.mozilla.fenix.ext.showToolbar
|
||||||
|
import org.mozilla.fenix.settings.creditcards.controller.DefaultCreditCardsManagementController
|
||||||
|
import org.mozilla.fenix.settings.creditcards.interactor.CreditCardsManagementInteractor
|
||||||
|
import org.mozilla.fenix.settings.creditcards.interactor.DefaultCreditCardsManagementInteractor
|
||||||
|
import org.mozilla.fenix.settings.creditcards.view.CreditCardsManagementView
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a list of saved credit cards.
|
||||||
|
*/
|
||||||
|
class CreditCardsManagementFragment : Fragment() {
|
||||||
|
|
||||||
|
private lateinit var creditCardsStore: CreditCardsFragmentStore
|
||||||
|
private lateinit var interactor: CreditCardsManagementInteractor
|
||||||
|
private lateinit var creditCardsView: CreditCardsManagementView
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
val view = inflater.inflate(R.layout.fragment_saved_cards, container, false)
|
||||||
|
|
||||||
|
creditCardsStore = StoreProvider.get(this) {
|
||||||
|
CreditCardsFragmentStore(CreditCardsListState(creditCards = emptyList()))
|
||||||
|
}
|
||||||
|
|
||||||
|
interactor = DefaultCreditCardsManagementInteractor(
|
||||||
|
controller = DefaultCreditCardsManagementController(
|
||||||
|
navController = findNavController()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
creditCardsView = CreditCardsManagementView(view.saved_cards_layout, interactor)
|
||||||
|
|
||||||
|
loadCreditCards()
|
||||||
|
|
||||||
|
return view
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalCoroutinesApi
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
consumeFrom(creditCardsStore) { state ->
|
||||||
|
creditCardsView.update(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
showToolbar(getString(R.string.credit_cards_saved_cards))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all the credit cards from the autofill storage and updates the
|
||||||
|
* [CreditCardsFragmentStore] with the list of credit cards.
|
||||||
|
*/
|
||||||
|
private fun loadCreditCards() {
|
||||||
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
val creditCards = requireContext().components.core.autofillStorage.getAllCreditCards()
|
||||||
|
|
||||||
|
lifecycleScope.launch(Dispatchers.Main) {
|
||||||
|
creditCardsStore.dispatch(CreditCardsAction.UpdateCreditCards(creditCards))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
/* 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.settings.creditcards.controller
|
||||||
|
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import org.mozilla.fenix.settings.creditcards.CreditCardsManagementFragmentDirections
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [CreditCardsManagementFragment] controller. An interface that handles the view manipulation of
|
||||||
|
* the credit cards manager triggered by the Interactor.
|
||||||
|
*/
|
||||||
|
interface CreditCardsManagementController {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see [CreditCardsManagementInteractor.onSelectCreditCard]
|
||||||
|
*/
|
||||||
|
fun handleCreditCardClicked()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default implementation of [CreditCardsManagementController].
|
||||||
|
*/
|
||||||
|
class DefaultCreditCardsManagementController(
|
||||||
|
private val navController: NavController
|
||||||
|
) : CreditCardsManagementController {
|
||||||
|
|
||||||
|
override fun handleCreditCardClicked() {
|
||||||
|
navController.navigate(
|
||||||
|
CreditCardsManagementFragmentDirections
|
||||||
|
.actionCreditCardsManagementFragmentToCreditCardEditorFragment()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
/* 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.settings.creditcards.interactor
|
||||||
|
|
||||||
|
import org.mozilla.fenix.settings.creditcards.controller.CreditCardsManagementController
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the credit cards management Interactor.
|
||||||
|
*/
|
||||||
|
interface CreditCardsManagementInteractor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigates to the credit card editor to edit the selected credit card. Called when a user
|
||||||
|
* taps on a credit card item.
|
||||||
|
*/
|
||||||
|
fun onSelectCreditCard()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default implementation of [CreditCardEditorInteractor]
|
||||||
|
*/
|
||||||
|
class DefaultCreditCardsManagementInteractor(
|
||||||
|
private val controller: CreditCardsManagementController
|
||||||
|
) : CreditCardsManagementInteractor {
|
||||||
|
|
||||||
|
override fun onSelectCreditCard() {
|
||||||
|
controller.handleCreditCardClicked()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
/* 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.settings.creditcards.view
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import kotlinx.android.synthetic.main.credit_card_list_item.*
|
||||||
|
import mozilla.components.concept.storage.CreditCard
|
||||||
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.settings.creditcards.interactor.CreditCardsManagementInteractor
|
||||||
|
import org.mozilla.fenix.utils.view.ViewHolder
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Calendar
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View holder for a credit card list item.
|
||||||
|
*/
|
||||||
|
class CreditCardItemViewHolder(
|
||||||
|
view: View,
|
||||||
|
private val interactor: CreditCardsManagementInteractor
|
||||||
|
) : ViewHolder(view) {
|
||||||
|
|
||||||
|
fun bind(creditCard: CreditCard) {
|
||||||
|
credit_card_number.text = creditCard.cardNumber
|
||||||
|
|
||||||
|
bindCreditCardExpiryDate(creditCard)
|
||||||
|
|
||||||
|
itemView.setOnClickListener {
|
||||||
|
interactor.onSelectCreditCard()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the credit card expiry date formatted according to the locale.
|
||||||
|
*/
|
||||||
|
private fun bindCreditCardExpiryDate(creditCard: CreditCard) {
|
||||||
|
val dateFormat = SimpleDateFormat(DATE_PATTERN, Locale.getDefault())
|
||||||
|
|
||||||
|
val calendar = Calendar.getInstance()
|
||||||
|
calendar.set(Calendar.DAY_OF_MONTH, 1)
|
||||||
|
// Subtract 1 from the expiry month since Calendar.Month is based on a 0-indexed.
|
||||||
|
calendar.set(Calendar.MONTH, creditCard.expiryMonth.toInt() - 1)
|
||||||
|
calendar.set(Calendar.YEAR, creditCard.expiryYear.toInt())
|
||||||
|
|
||||||
|
expiry_date.text = dateFormat.format(calendar.time)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val LAYOUT_ID = R.layout.credit_card_list_item
|
||||||
|
|
||||||
|
// Date format pattern for the credit card expiry date.
|
||||||
|
private const val DATE_PATTERN = "MM/yyyy"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/* 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.settings.creditcards.view
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
|
import mozilla.components.concept.storage.CreditCard
|
||||||
|
import org.mozilla.fenix.settings.creditcards.interactor.CreditCardsManagementInteractor
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapter for a list of credit cards to be displayed.
|
||||||
|
*/
|
||||||
|
class CreditCardsAdapter(
|
||||||
|
private val interactor: CreditCardsManagementInteractor
|
||||||
|
) : ListAdapter<CreditCard, CreditCardItemViewHolder>(DiffCallback) {
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CreditCardItemViewHolder {
|
||||||
|
val view = LayoutInflater.from(parent.context)
|
||||||
|
.inflate(CreditCardItemViewHolder.LAYOUT_ID, parent, false)
|
||||||
|
return CreditCardItemViewHolder(view, interactor)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: CreditCardItemViewHolder, position: Int) {
|
||||||
|
holder.bind(getItem(position))
|
||||||
|
}
|
||||||
|
|
||||||
|
internal object DiffCallback : DiffUtil.ItemCallback<CreditCard>() {
|
||||||
|
override fun areItemsTheSame(oldItem: CreditCard, newItem: CreditCard) =
|
||||||
|
oldItem.guid == newItem.guid
|
||||||
|
|
||||||
|
override fun areContentsTheSame(oldItem: CreditCard, newItem: CreditCard) =
|
||||||
|
oldItem == newItem
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
/* 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.settings.creditcards.view
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import kotlinx.android.extensions.LayoutContainer
|
||||||
|
import kotlinx.android.synthetic.main.component_credit_cards.*
|
||||||
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.settings.creditcards.CreditCardsListState
|
||||||
|
import org.mozilla.fenix.settings.creditcards.interactor.CreditCardsManagementInteractor
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a list of credit cards.
|
||||||
|
*/
|
||||||
|
class CreditCardsManagementView(
|
||||||
|
override val containerView: ViewGroup,
|
||||||
|
val interactor: CreditCardsManagementInteractor
|
||||||
|
) : LayoutContainer {
|
||||||
|
|
||||||
|
private val creditCardsAdapter = CreditCardsAdapter(interactor)
|
||||||
|
|
||||||
|
init {
|
||||||
|
LayoutInflater.from(containerView.context).inflate(LAYOUT_ID, containerView, true)
|
||||||
|
|
||||||
|
credit_cards_list.apply {
|
||||||
|
adapter = creditCardsAdapter
|
||||||
|
layoutManager = LinearLayoutManager(containerView.context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the display of the credit cards based on the given [CreditCardsListState].
|
||||||
|
*/
|
||||||
|
fun update(state: CreditCardsListState) {
|
||||||
|
progress_bar.isVisible = state.isLoading
|
||||||
|
credit_cards_list.isVisible = state.creditCards.isNotEmpty()
|
||||||
|
|
||||||
|
creditCardsAdapter.submitList(state.creditCards)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val LAYOUT_ID = R.layout.component_credit_cards
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- 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/. -->
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/credit_cards_wrapper"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progress_bar"
|
||||||
|
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||||
|
android:indeterminate="true"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="8dp"
|
||||||
|
android:translationY="-3dp"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/credit_cards_list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:listitem="@layout/credit_card_list_item" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
@ -0,0 +1,45 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- 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/. -->
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:minHeight="?android:attr/listPreferredItemHeight">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/credit_card_number"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/saved_logins_item_margin_start"
|
||||||
|
android:layout_marginEnd="@dimen/saved_logins_item_margin_end"
|
||||||
|
android:ellipsize="middle"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||||
|
android:textColor="?primaryText"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/expiry_date"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_chainStyle="packed"
|
||||||
|
tools:text="mozilla.org" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/expiry_date"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/credit_cards_saved_cards_item_margin_start"
|
||||||
|
android:layout_marginEnd="@dimen/credit_cards_saved_cards_item_margin_end"
|
||||||
|
android:ellipsize="middle"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textColor="?secondaryText"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/credit_card_number"
|
||||||
|
app:layout_constraintVertical_chainStyle="packed"
|
||||||
|
tools:text="02/2022" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- 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/. -->
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/saved_cards_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:context="org.mozilla.fenix.settings.creditcards.CreditCardsManagementFragment" />
|
@ -0,0 +1,62 @@
|
|||||||
|
/* 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.settings.creditcards
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import io.mockk.mockk
|
||||||
|
import io.mockk.verify
|
||||||
|
import kotlinx.android.synthetic.main.credit_card_list_item.view.*
|
||||||
|
import mozilla.components.concept.storage.CreditCard
|
||||||
|
import mozilla.components.support.test.robolectric.testContext
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||||
|
import org.mozilla.fenix.settings.creditcards.interactor.CreditCardsManagementInteractor
|
||||||
|
import org.mozilla.fenix.settings.creditcards.view.CreditCardItemViewHolder
|
||||||
|
|
||||||
|
@RunWith(FenixRobolectricTestRunner::class)
|
||||||
|
class CreditCardItemViewHolderTest {
|
||||||
|
|
||||||
|
private lateinit var view: View
|
||||||
|
private lateinit var interactor: CreditCardsManagementInteractor
|
||||||
|
|
||||||
|
private val creditCard = CreditCard(
|
||||||
|
guid = "id",
|
||||||
|
billingName = "Banana Apple",
|
||||||
|
cardNumber = "4111111111111110",
|
||||||
|
expiryMonth = 1,
|
||||||
|
expiryYear = 2030,
|
||||||
|
cardType = "amex",
|
||||||
|
timeCreated = 1L,
|
||||||
|
timeLastUsed = 1L,
|
||||||
|
timeLastModified = 1L,
|
||||||
|
timesUsed = 1L
|
||||||
|
)
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
view = LayoutInflater.from(testContext).inflate(CreditCardItemViewHolder.LAYOUT_ID, null)
|
||||||
|
interactor = mockk(relaxed = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `GIVEN a new credit card item on bind THEN set the card number and expiry date text`() {
|
||||||
|
CreditCardItemViewHolder(view, interactor).bind(creditCard)
|
||||||
|
|
||||||
|
assertEquals(creditCard.cardNumber, view.credit_card_number.text)
|
||||||
|
assertEquals("0${creditCard.expiryMonth}/${creditCard.expiryYear}", view.expiry_date.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `WHEN a credit item is clicked THEN interactor is called`() {
|
||||||
|
CreditCardItemViewHolder(view, interactor).bind(creditCard)
|
||||||
|
|
||||||
|
view.performClick()
|
||||||
|
verify { interactor.onSelectCreditCard() }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
/* 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.settings.creditcards
|
||||||
|
|
||||||
|
import mozilla.components.concept.storage.CreditCard
|
||||||
|
import org.junit.Assert.assertFalse
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Test
|
||||||
|
import org.mozilla.fenix.settings.creditcards.view.CreditCardsAdapter
|
||||||
|
|
||||||
|
class CreditCardsAdapterTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testDiffCallback() {
|
||||||
|
val creditCard1 = CreditCard(
|
||||||
|
guid = "id",
|
||||||
|
billingName = "Banana Apple",
|
||||||
|
cardNumber = "4111111111111110",
|
||||||
|
expiryMonth = 1,
|
||||||
|
expiryYear = 2030,
|
||||||
|
cardType = "amex",
|
||||||
|
timeCreated = 1L,
|
||||||
|
timeLastUsed = 1L,
|
||||||
|
timeLastModified = 1L,
|
||||||
|
timesUsed = 1L
|
||||||
|
)
|
||||||
|
val creditCard2 = CreditCard(
|
||||||
|
guid = "id",
|
||||||
|
billingName = "Banana Apple",
|
||||||
|
cardNumber = "4111111111111110",
|
||||||
|
expiryMonth = 1,
|
||||||
|
expiryYear = 2030,
|
||||||
|
cardType = "amex",
|
||||||
|
timeCreated = 1L,
|
||||||
|
timeLastUsed = 1L,
|
||||||
|
timeLastModified = 1L,
|
||||||
|
timesUsed = 1L
|
||||||
|
)
|
||||||
|
|
||||||
|
assertTrue(
|
||||||
|
CreditCardsAdapter.DiffCallback.areItemsTheSame(creditCard1, creditCard2)
|
||||||
|
)
|
||||||
|
assertTrue(
|
||||||
|
CreditCardsAdapter.DiffCallback.areContentsTheSame(creditCard1, creditCard2)
|
||||||
|
)
|
||||||
|
|
||||||
|
val creditCard3 = CreditCard(
|
||||||
|
guid = "id3",
|
||||||
|
billingName = "Banana Apple",
|
||||||
|
cardNumber = "4111111111111110",
|
||||||
|
expiryMonth = 1,
|
||||||
|
expiryYear = 2030,
|
||||||
|
cardType = "amex",
|
||||||
|
timeCreated = 1L,
|
||||||
|
timeLastUsed = 1L,
|
||||||
|
timeLastModified = 1L,
|
||||||
|
timesUsed = 1L
|
||||||
|
)
|
||||||
|
|
||||||
|
assertFalse(
|
||||||
|
CreditCardsAdapter.DiffCallback.areItemsTheSame(creditCard1, creditCard3)
|
||||||
|
)
|
||||||
|
assertFalse(
|
||||||
|
CreditCardsAdapter.DiffCallback.areContentsTheSame(creditCard1, creditCard3)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/* 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.settings.creditcards
|
||||||
|
|
||||||
|
import io.mockk.mockk
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import mozilla.components.concept.storage.CreditCard
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Assert.assertFalse
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class CreditCardsFragmentStoreTest {
|
||||||
|
|
||||||
|
private lateinit var creditCardsState: CreditCardsListState
|
||||||
|
private lateinit var creditCardsStore: CreditCardsFragmentStore
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
creditCardsState = CreditCardsListState(creditCards = emptyList())
|
||||||
|
creditCardsStore = CreditCardsFragmentStore(creditCardsState)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testUpdateCreditCards() = runBlocking {
|
||||||
|
assertTrue(creditCardsStore.state.isLoading)
|
||||||
|
|
||||||
|
val creditCards: List<CreditCard> = listOf(mockk(), mockk())
|
||||||
|
creditCardsStore.dispatch(CreditCardsAction.UpdateCreditCards(creditCards)).join()
|
||||||
|
|
||||||
|
assertEquals(creditCards, creditCardsStore.state.creditCards)
|
||||||
|
assertFalse(creditCardsStore.state.isLoading)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
/* 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.settings.creditcards
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import io.mockk.mockk
|
||||||
|
import kotlinx.android.synthetic.main.component_credit_cards.view.*
|
||||||
|
import mozilla.components.concept.storage.CreditCard
|
||||||
|
import mozilla.components.support.test.robolectric.testContext
|
||||||
|
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.R
|
||||||
|
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||||
|
import org.mozilla.fenix.settings.creditcards.interactor.CreditCardsManagementInteractor
|
||||||
|
import org.mozilla.fenix.settings.creditcards.view.CreditCardsManagementView
|
||||||
|
|
||||||
|
@RunWith(FenixRobolectricTestRunner::class)
|
||||||
|
class CreditCardsManagementViewTest {
|
||||||
|
|
||||||
|
private lateinit var view: ViewGroup
|
||||||
|
private lateinit var interactor: CreditCardsManagementInteractor
|
||||||
|
private lateinit var creditCardsView: CreditCardsManagementView
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
view = LayoutInflater.from(testContext).inflate(CreditCardsManagementView.LAYOUT_ID, null)
|
||||||
|
.findViewById(R.id.credit_cards_wrapper)
|
||||||
|
interactor = mockk(relaxed = true)
|
||||||
|
|
||||||
|
creditCardsView = CreditCardsManagementView(view, interactor)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testUpdate() {
|
||||||
|
creditCardsView.update(CreditCardsListState(creditCards = emptyList()))
|
||||||
|
|
||||||
|
assertTrue(view.progress_bar.isVisible)
|
||||||
|
assertFalse(view.credit_cards_list.isVisible)
|
||||||
|
|
||||||
|
val creditCards: List<CreditCard> = listOf(mockk(), mockk())
|
||||||
|
creditCardsView.update(CreditCardsListState(
|
||||||
|
creditCards = creditCards,
|
||||||
|
isLoading = false
|
||||||
|
))
|
||||||
|
|
||||||
|
assertFalse(view.progress_bar.isVisible)
|
||||||
|
assertTrue(view.credit_cards_list.isVisible)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
/* 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.settings.creditcards
|
||||||
|
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import io.mockk.mockk
|
||||||
|
import io.mockk.spyk
|
||||||
|
import io.mockk.verify
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.mozilla.fenix.settings.creditcards.controller.DefaultCreditCardsManagementController
|
||||||
|
|
||||||
|
class DefaultCreditCardsManagementControllerTest {
|
||||||
|
|
||||||
|
private val navController: NavController = mockk(relaxed = true)
|
||||||
|
|
||||||
|
private lateinit var controller: DefaultCreditCardsManagementController
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
controller = spyk(
|
||||||
|
DefaultCreditCardsManagementController(
|
||||||
|
navController = navController
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun handleCreditCardClicked() {
|
||||||
|
controller.handleCreditCardClicked()
|
||||||
|
|
||||||
|
verify {
|
||||||
|
navController.navigate(
|
||||||
|
CreditCardsManagementFragmentDirections
|
||||||
|
.actionCreditCardsManagementFragmentToCreditCardEditorFragment()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/* 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.settings.creditcards
|
||||||
|
|
||||||
|
import io.mockk.mockk
|
||||||
|
import io.mockk.verify
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.mozilla.fenix.settings.creditcards.controller.CreditCardsManagementController
|
||||||
|
import org.mozilla.fenix.settings.creditcards.interactor.DefaultCreditCardsManagementInteractor
|
||||||
|
|
||||||
|
class DefaultCreditCardsManagementInteractorTest {
|
||||||
|
|
||||||
|
private val controller: CreditCardsManagementController = mockk(relaxed = true)
|
||||||
|
|
||||||
|
private lateinit var interactor: DefaultCreditCardsManagementInteractor
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
interactor = DefaultCreditCardsManagementInteractor(controller)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onSelectCreditCard() {
|
||||||
|
interactor.onSelectCreditCard()
|
||||||
|
verify { controller.handleCreditCardClicked() }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue