Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose the current card brand in CardFormView, CardInputWidget, and CardMultiLineWidget #5238

Merged
merged 3 commits into from
Jun 30, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,7 @@

### Payments
* [FIXED] [5226](https://github.com/stripe/stripe-android/pull/5226) Persist `GooglePayLauncherViewModel` state across process death
* [ADDED] [5238](https://github.com/stripe/stripe-android/pull/5238) Expose the current card brand in CardFormView, CardInputWidget, and CardMultiLineWidget

## 20.6.2 - 2022-06-23
This release contains several bug fixes for Payments, reduces the size of StripeCardScan, and adds new `rememberFinancialConnections` features for Financial Connections.
Expand Down
3 changes: 3 additions & 0 deletions payments-core/api/payments-core.api
Expand Up @@ -7285,6 +7285,7 @@ public final class com/stripe/android/view/CardFormView : android/widget/LinearL
public fun <init> (Landroid/content/Context;Landroid/util/AttributeSet;)V
public fun <init> (Landroid/content/Context;Landroid/util/AttributeSet;I)V
public synthetic fun <init> (Landroid/content/Context;Landroid/util/AttributeSet;IILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getBrand ()Lcom/stripe/android/model/CardBrand;
public final fun getCardParams ()Lcom/stripe/android/model/CardParams;
public final fun setCardValidCallback (Lcom/stripe/android/view/CardValidCallback;)V
public fun setEnabled (Z)V
Expand Down Expand Up @@ -7314,6 +7315,7 @@ public final class com/stripe/android/view/CardInputWidget : android/widget/Line
public fun <init> (Landroid/content/Context;Landroid/util/AttributeSet;I)V
public synthetic fun <init> (Landroid/content/Context;Landroid/util/AttributeSet;IILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun clear ()V
public final fun getBrand ()Lcom/stripe/android/model/CardBrand;
public fun getCardParams ()Lcom/stripe/android/model/CardParams;
public fun getPaymentMethodCard ()Lcom/stripe/android/model/PaymentMethodCreateParams$Card;
public fun getPaymentMethodCreateParams ()Lcom/stripe/android/model/PaymentMethodCreateParams;
Expand Down Expand Up @@ -7347,6 +7349,7 @@ public final class com/stripe/android/view/CardMultilineWidget : android/widget/
public fun <init> (Landroid/content/Context;Landroid/util/AttributeSet;IZ)V
public synthetic fun <init> (Landroid/content/Context;Landroid/util/AttributeSet;IZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun clear ()V
public final synthetic fun getBrand ()Lcom/stripe/android/model/CardBrand;
public fun getCardParams ()Lcom/stripe/android/model/CardParams;
public final fun getPaymentMethodBillingDetails ()Lcom/stripe/android/model/PaymentMethod$BillingDetails;
public final fun getPaymentMethodBillingDetailsBuilder ()Lcom/stripe/android/model/PaymentMethod$BillingDetails$Builder;
Expand Down
Expand Up @@ -24,6 +24,7 @@ import com.stripe.android.databinding.StripeCardFormViewBinding
import com.stripe.android.databinding.StripeHorizontalDividerBinding
import com.stripe.android.databinding.StripeVerticalDividerBinding
import com.stripe.android.model.Address
import com.stripe.android.model.CardBrand
import com.stripe.android.model.CardParams
import com.stripe.android.view.CardFormView.Style
import com.stripe.android.view.CardValidCallback.Fields
Expand Down Expand Up @@ -97,6 +98,14 @@ class CardFormView @JvmOverloads constructor(
Borderless(1)
}

/**
* A [CardBrand] matching the current card number inputted by the user.
*/
val brand: CardBrand
get() {
return cardMultilineWidget.brand
}

/**
* Retrieve a [CardParams] representing the card details if all these fields are valid:
* card number, expiration date, CVC, postal, country.
Expand Down
Expand Up @@ -148,7 +148,10 @@ class CardInputWidget @JvmOverloads constructor(
return cvcEditText.cvc
}

private val brand: CardBrand
/**
* A [CardBrand] matching the current card number inputted by the user.
*/
val brand: CardBrand
get() {
return cardNumberEditText.cardBrand
}
Expand Down
Expand Up @@ -115,13 +115,13 @@ class CardMultilineWidget @JvmOverloads constructor(

private var cardBrand: CardBrand = CardBrand.Unknown

internal val brand: CardBrand
/**
* A [CardBrand] matching the current card number inputted by the user.
*/
val brand: CardBrand
@JvmSynthetic
get() = cardBrand

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) // For paymentsheet
fun getBrand() = brand

/**
* If [shouldShowPostalCode] is true and [postalCodeRequired] is true, then postal code is a
* required field.
Expand Down
Expand Up @@ -1654,6 +1654,30 @@ internal class CardInputWidgetTest {
verify(callback, times(2)).onInputChanged(any(), any())
}

@Test
fun `getBrand returns the right brands`() {
cardInputWidget.setCardNumber(null)
assertThat(cardInputWidget.brand).isEqualTo(CardBrand.Unknown)

cardInputWidget.setCardNumber(VISA_NO_SPACES)
assertThat(cardInputWidget.brand).isEqualTo(CardBrand.Visa)

cardInputWidget.setCardNumber(CardNumberFixtures.MASTERCARD_NO_SPACES)
assertThat(cardInputWidget.brand).isEqualTo(CardBrand.MasterCard)

cardInputWidget.setCardNumber(AMEX_NO_SPACES)
assertThat(cardInputWidget.brand).isEqualTo(CardBrand.AmericanExpress)

cardInputWidget.setCardNumber(CardNumberFixtures.DISCOVER_NO_SPACES)
assertThat(cardInputWidget.brand).isEqualTo(CardBrand.Discover)

cardInputWidget.setCardNumber(CardNumberFixtures.JCB_NO_SPACES)
assertThat(cardInputWidget.brand).isEqualTo(CardBrand.JCB)

cardInputWidget.setCardNumber(DINERS_CLUB_14_NO_SPACES)
assertThat(cardInputWidget.brand).isEqualTo(CardBrand.DinersClub)
}

@Test
fun `Enabled but not required postal code should fire card valid callback when changed`() {
val callback = mock<CardValidCallback>()
Expand Down
Expand Up @@ -10,7 +10,11 @@ import com.google.common.truth.Truth.assertThat
import com.stripe.android.ApiKeyFixtures
import com.stripe.android.CardNumberFixtures.AMEX_NO_SPACES
import com.stripe.android.CardNumberFixtures.AMEX_WITH_SPACES
import com.stripe.android.CardNumberFixtures.DINERS_CLUB_14_NO_SPACES
import com.stripe.android.CardNumberFixtures.DINERS_CLUB_14_WITH_SPACES
import com.stripe.android.CardNumberFixtures.DISCOVER_NO_SPACES
import com.stripe.android.CardNumberFixtures.JCB_NO_SPACES
import com.stripe.android.CardNumberFixtures.MASTERCARD_NO_SPACES
import com.stripe.android.CardNumberFixtures.VISA_NO_SPACES
import com.stripe.android.CardNumberFixtures.VISA_WITH_SPACES
import com.stripe.android.CustomerSession
Expand Down Expand Up @@ -1199,6 +1203,30 @@ internal class CardMultilineWidgetTest {
).isNotNull()
}

@Test
fun `getBrand returns the right brands`() {
cardMultilineWidget.setCardNumber(null)
assertThat(cardMultilineWidget.brand).isEqualTo(CardBrand.Unknown)

cardMultilineWidget.setCardNumber(VISA_NO_SPACES)
assertThat(cardMultilineWidget.brand).isEqualTo(CardBrand.Visa)

cardMultilineWidget.setCardNumber(MASTERCARD_NO_SPACES)
assertThat(cardMultilineWidget.brand).isEqualTo(CardBrand.MasterCard)

cardMultilineWidget.setCardNumber(AMEX_NO_SPACES)
assertThat(cardMultilineWidget.brand).isEqualTo(CardBrand.AmericanExpress)

cardMultilineWidget.setCardNumber(DISCOVER_NO_SPACES)
assertThat(cardMultilineWidget.brand).isEqualTo(CardBrand.Discover)

cardMultilineWidget.setCardNumber(JCB_NO_SPACES)
assertThat(cardMultilineWidget.brand).isEqualTo(CardBrand.JCB)

cardMultilineWidget.setCardNumber(DINERS_CLUB_14_NO_SPACES)
assertThat(cardMultilineWidget.brand).isEqualTo(CardBrand.DinersClub)
}

internal class WidgetControlGroup(
widget: CardMultilineWidget,
workContext: CoroutineContext
Expand Down