For #19680 - Show the card number when editing a credit card (#19681)

This commit is contained in:
Gabriel Luong 2021-05-26 20:22:11 -04:00 committed by GitHub
parent 0eee71d0cf
commit 338c488fae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 12 deletions

View File

@ -49,16 +49,17 @@ class CreditCardEditorFragment : SecureFragment(R.layout.fragment_credit_card_ed
showToolbar(getString(R.string.credit_cards_edit_card)) showToolbar(getString(R.string.credit_cards_edit_card))
} }
val storage = requireContext().components.core.autofillStorage
interactor = DefaultCreditCardEditorInteractor( interactor = DefaultCreditCardEditorInteractor(
controller = DefaultCreditCardEditorController( controller = DefaultCreditCardEditorController(
storage = requireContext().components.core.autofillStorage, storage = storage,
lifecycleScope = lifecycleScope, lifecycleScope = lifecycleScope,
navController = findNavController() navController = findNavController()
) )
) )
creditCardEditorState = creditCardEditorState =
args.creditCard?.toCreditCardEditorState() ?: getInitialCreditCardEditorState() args.creditCard?.toCreditCardEditorState(storage) ?: getInitialCreditCardEditorState()
creditCardEditorView = CreditCardEditorView(view, interactor) creditCardEditorView = CreditCardEditorView(view, interactor)
creditCardEditorView.bind(creditCardEditorState) creditCardEditorView.bind(creditCardEditorState)
} }

View File

@ -5,6 +5,7 @@
package org.mozilla.fenix.settings.creditcards package org.mozilla.fenix.settings.creditcards
import mozilla.components.concept.storage.CreditCard import mozilla.components.concept.storage.CreditCard
import mozilla.components.service.sync.autofill.AutofillCreditCardsAddressesStorage
import org.mozilla.fenix.settings.creditcards.CreditCardEditorFragment.Companion.NUMBER_OF_YEARS_TO_SHOW import org.mozilla.fenix.settings.creditcards.CreditCardEditorFragment.Companion.NUMBER_OF_YEARS_TO_SHOW
import java.util.Calendar import java.util.Calendar
@ -30,15 +31,17 @@ data class CreditCardEditorState(
/** /**
* Returns a [CreditCardEditorState] from the given [CreditCard]. * Returns a [CreditCardEditorState] from the given [CreditCard].
*/ */
fun CreditCard.toCreditCardEditorState(): CreditCardEditorState { fun CreditCard.toCreditCardEditorState(storage: AutofillCreditCardsAddressesStorage): CreditCardEditorState {
val crypto = storage.getCreditCardCrypto()
val key = crypto.key()
val cardNumber = crypto.decrypt(key, encryptedCardNumber)?.number ?: ""
val startYear = expiryYear.toInt() val startYear = expiryYear.toInt()
val endYear = startYear + NUMBER_OF_YEARS_TO_SHOW val endYear = startYear + NUMBER_OF_YEARS_TO_SHOW
return CreditCardEditorState( return CreditCardEditorState(
guid = guid, guid = guid,
billingName = billingName, billingName = billingName,
// TODO - need to represented a full CreditCardNumber object here, along with last4 cardNumber = cardNumber,
cardNumber = encryptedCardNumber.number,
expiryMonth = expiryMonth.toInt(), expiryMonth = expiryMonth.toInt(),
expiryYears = Pair(startYear, endYear), expiryYears = Pair(startYear, endYear),
isEditing = true isEditing = true

View File

@ -4,8 +4,12 @@
package org.mozilla.fenix.settings.creditcards package org.mozilla.fenix.settings.creditcards
import io.mockk.every
import io.mockk.mockk
import mozilla.components.concept.storage.CreditCard import mozilla.components.concept.storage.CreditCard
import mozilla.components.concept.storage.CreditCardNumber import mozilla.components.concept.storage.CreditCardNumber
import mozilla.components.service.sync.autofill.AutofillCreditCardsAddressesStorage
import mozilla.components.service.sync.autofill.AutofillCrypto
import mozilla.components.support.utils.CreditCardNetworkType import mozilla.components.support.utils.CreditCardNetworkType
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse import org.junit.Assert.assertFalse
@ -16,10 +20,11 @@ import java.util.Calendar
class CreditCardEditorStateTest { class CreditCardEditorStateTest {
private val cardNumber = "4111111111111110"
private val creditCard = CreditCard( private val creditCard = CreditCard(
guid = "id", guid = "id",
billingName = "Banana Apple", billingName = "Banana Apple",
encryptedCardNumber = CreditCardNumber.Encrypted("4111111111111110"), encryptedCardNumber = CreditCardNumber.Encrypted(cardNumber),
cardNumberLast4 = "1110", cardNumberLast4 = "1110",
expiryMonth = 5, expiryMonth = 5,
expiryYear = 2030, expiryYear = 2030,
@ -32,7 +37,13 @@ class CreditCardEditorStateTest {
@Test @Test
fun testToCreditCardEditorState() { fun testToCreditCardEditorState() {
val state = creditCard.toCreditCardEditorState() val storage: AutofillCreditCardsAddressesStorage = mockk(relaxed = true)
val crypto: AutofillCrypto = mockk(relaxed = true)
every { storage.getCreditCardCrypto() } returns crypto
every { crypto.decrypt(any(), any()) } returns CreditCardNumber.Plaintext(cardNumber)
val state = creditCard.toCreditCardEditorState(storage)
val startYear = creditCard.expiryYear.toInt() val startYear = creditCard.expiryYear.toInt()
val endYear = startYear + NUMBER_OF_YEARS_TO_SHOW val endYear = startYear + NUMBER_OF_YEARS_TO_SHOW

View File

@ -6,6 +6,7 @@ package org.mozilla.fenix.settings.creditcards
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
import io.mockk.spyk import io.mockk.spyk
import io.mockk.verify import io.mockk.verify
@ -14,6 +15,8 @@ import mozilla.components.concept.storage.CreditCard
import mozilla.components.concept.storage.CreditCardNumber import mozilla.components.concept.storage.CreditCardNumber
import mozilla.components.concept.storage.NewCreditCardFields import mozilla.components.concept.storage.NewCreditCardFields
import mozilla.components.concept.storage.UpdatableCreditCardFields import mozilla.components.concept.storage.UpdatableCreditCardFields
import mozilla.components.service.sync.autofill.AutofillCreditCardsAddressesStorage
import mozilla.components.service.sync.autofill.AutofillCrypto
import mozilla.components.support.test.robolectric.testContext import mozilla.components.support.test.robolectric.testContext
import mozilla.components.support.utils.CreditCardNetworkType import mozilla.components.support.utils.CreditCardNetworkType
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
@ -36,11 +39,14 @@ class CreditCardEditorViewTest {
private lateinit var view: View private lateinit var view: View
private lateinit var interactor: CreditCardEditorInteractor private lateinit var interactor: CreditCardEditorInteractor
private lateinit var creditCardEditorView: CreditCardEditorView private lateinit var creditCardEditorView: CreditCardEditorView
private lateinit var storage: AutofillCreditCardsAddressesStorage
private lateinit var crypto: AutofillCrypto
private val cardNumber = "4111111111111111"
private val creditCard = CreditCard( private val creditCard = CreditCard(
guid = "id", guid = "id",
billingName = "Banana Apple", billingName = "Banana Apple",
encryptedCardNumber = CreditCardNumber.Encrypted("4111111111111111"), encryptedCardNumber = CreditCardNumber.Encrypted(cardNumber),
cardNumberLast4 = "1111", cardNumberLast4 = "1111",
expiryMonth = 5, expiryMonth = 5,
expiryYear = 2030, expiryYear = 2030,
@ -55,6 +61,11 @@ class CreditCardEditorViewTest {
fun setup() { fun setup() {
view = LayoutInflater.from(testContext).inflate(R.layout.fragment_credit_card_editor, null) view = LayoutInflater.from(testContext).inflate(R.layout.fragment_credit_card_editor, null)
interactor = mockk(relaxed = true) interactor = mockk(relaxed = true)
storage = mockk(relaxed = true)
crypto = mockk(relaxed = true)
every { storage.getCreditCardCrypto() } returns crypto
every { crypto.decrypt(any(), any()) } returns CreditCardNumber.Plaintext(cardNumber)
creditCardEditorView = spyk(CreditCardEditorView(view, interactor)) creditCardEditorView = spyk(CreditCardEditorView(view, interactor))
} }
@ -87,9 +98,9 @@ class CreditCardEditorViewTest {
@Test @Test
fun `GIVEN a credit card THEN credit card form inputs are displaying the provided credit card information`() { fun `GIVEN a credit card THEN credit card form inputs are displaying the provided credit card information`() {
creditCardEditorView.bind(creditCard.toCreditCardEditorState()) creditCardEditorView.bind(creditCard.toCreditCardEditorState(storage))
assertEquals(creditCard.encryptedCardNumber.number, view.card_number_input.text.toString()) assertEquals(cardNumber, view.card_number_input.text.toString())
assertEquals(creditCard.billingName, view.name_on_card_input.text.toString()) assertEquals(creditCard.billingName, view.name_on_card_input.text.toString())
with(view.expiry_month_drop_down) { with(view.expiry_month_drop_down) {
@ -108,7 +119,7 @@ class CreditCardEditorViewTest {
@Test @Test
fun `GIVEN a credit card WHEN the delete card button is clicked THEN interactor is called`() { fun `GIVEN a credit card WHEN the delete card button is clicked THEN interactor is called`() {
creditCardEditorView.bind(creditCard.toCreditCardEditorState()) creditCardEditorView.bind(creditCard.toCreditCardEditorState(storage))
assertEquals(View.VISIBLE, view.delete_button.visibility) assertEquals(View.VISIBLE, view.delete_button.visibility)
@ -202,7 +213,7 @@ class CreditCardEditorViewTest {
@Test @Test
fun `GIVEN a valid credit card WHEN the save button is clicked THEN interactor is called`() { fun `GIVEN a valid credit card WHEN the save button is clicked THEN interactor is called`() {
creditCardEditorView.bind(creditCard.toCreditCardEditorState()) creditCardEditorView.bind(creditCard.toCreditCardEditorState(storage))
view.save_button.performClick() view.save_button.performClick()