Skip to content

Commit

Permalink
not duplicating card number listeners for cvc multiple sets and only …
Browse files Browse the repository at this point in the history
…compute card metadata once per change
  • Loading branch information
jleon15 committed Dec 14, 2022
1 parent 90893df commit 770c507
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class CardFragment : Fragment() {
*/
private fun setValidationListeners() {
binding.cardNumber.addChangeEventListener {
println(it)
viewModel.cardNumber.observe(it)
}
binding.cardExpiration.addChangeEventListener {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ class CardBrandEnricher {
get() = cardDetails?.validLengths?.contains(cardLength) ?: false
}

class CardMetadata(
val brand: String?,
val cvcMask: String?,
val cardMask: String?,
val complete: Boolean
)

private val cardBrands = listOf(
CardDetails(
CardBrands.VISA.label,
Expand Down Expand Up @@ -205,8 +212,8 @@ class CardBrandEnricher {
)
)

fun evaluateCard(number: String?): CardResult {
if (number.isNullOrBlank()) return CardResult(null)
fun evaluateCard(number: String?): CardMetadata? {
if (number.isNullOrBlank()) return null

var bestMatch = CardResult(null)

Expand All @@ -222,7 +229,14 @@ class CardBrandEnricher {
}
}

return bestMatch
return with(bestMatch) {
CardMetadata(
this.cardDetails?.brand,
this.cardDetails?.cvcMask,
this.cardDetails?.cardMask,
this.complete
)
}
}

private fun chooseBestMatch(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class CardNumberElement @JvmOverloads constructor(
defStyleAttr: Int = 0
) : TextElement(context, attrs, defStyleAttr) {

var cardDetails: CardBrandEnricher.CardDetails? = null
var cardMetadata: CardBrandEnricher.CardMetadata? = null
private set

private val cardBrandEnricher: CardBrandEnricher = CardBrandEnricher()
Expand All @@ -29,11 +29,10 @@ class CardNumberElement @JvmOverloads constructor(
}

override fun beforeTextChanged(value: String?): String? {
val cardResult = cardBrandEnricher.evaluateCard(getDigitsOnly(value))
cardDetails = cardResult.cardDetails
cardMetadata = cardBrandEnricher.evaluateCard(getDigitsOnly(value))

if (cardResult.cardDetails?.cardMask != null)
mask = ElementMask(cardResult.cardDetails!!.cardMask)
if (cardMetadata?.cardMask != null)
mask = ElementMask(cardMetadata!!.cardMask!!)

return value
}
Expand All @@ -44,10 +43,10 @@ class CardNumberElement @JvmOverloads constructor(
isEmpty: Boolean,
isValid: Boolean
): ChangeEvent {
val cardResult = cardBrandEnricher.evaluateCard(getDigitsOnly(value))
cardDetails = cardResult.cardDetails
val cardMetadata = cardBrandEnricher.evaluateCard(getDigitsOnly(value))
this.cardMetadata = cardMetadata

val eventDetails = cardResult.cardDetails?.brand?.let { brand ->
val eventDetails = this.cardMetadata?.brand?.let { brand ->
mutableListOf(
EventDetails(
"cardBrand",
Expand All @@ -57,7 +56,7 @@ class CardNumberElement @JvmOverloads constructor(
} ?: mutableListOf()

return ChangeEvent(
cardResult.complete,
cardMetadata?.complete ?: false,
isEmpty,
isValid,
eventDetails
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ class CardVerificationCodeElement @JvmOverloads constructor(

var cardNumberElement: CardNumberElement? = null
set(value) {
field = value

if (value != null && cardNumberElement != value) {
if (value != null && cardNumberElement !== value) {
field = value
super.mask =
cardNumberElement?.cardDetails?.cvcMask?.let { ElementMask(it) } ?: defaultMask
cardNumberElement?.cardMetadata?.cvcMask?.let { ElementMask(it) } ?: defaultMask
field?.addChangeEventListener { updateMask() }
} else {
field = value
}
}

Expand All @@ -38,6 +39,7 @@ class CardVerificationCodeElement @JvmOverloads constructor(
}

private fun updateMask() {
super.mask = cardNumberElement?.cardDetails?.cvcMask?.let { ElementMask(it) } ?: defaultMask
super.mask =
cardNumberElement?.cardMetadata?.cvcMask?.let { ElementMask(it) } ?: defaultMask
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ package com.basistheory.android.view

import android.app.Activity
import com.basistheory.android.event.ChangeEvent
import io.mockk.impl.annotations.RelaxedMockK
import io.mockk.impl.annotations.SpyK
import io.mockk.junit4.MockKRule
import io.mockk.spyk
import io.mockk.verify
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.Robolectric
Expand Down Expand Up @@ -81,4 +87,13 @@ class CardVerificationCodeElementTests {
get { isComplete }.isTrue()
}
}

@Test
fun `setting card number element multiple times does not duplicate listeners`() {
val cardNumberElement = spyk(CardNumberElement(Robolectric.buildActivity(Activity::class.java).get()))
cvcElement.cardNumberElement = cardNumberElement
cvcElement.cardNumberElement = cardNumberElement

verify(exactly = 1) { cardNumberElement.addChangeEventListener(any()) }
}
}

0 comments on commit 770c507

Please sign in to comment.