diff --git a/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/ext/CreditCard.kt b/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/ext/CreditCard.kt index 2b7e8c1a609..b3b55760b8f 100644 --- a/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/ext/CreditCard.kt +++ b/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/ext/CreditCard.kt @@ -5,12 +5,9 @@ package mozilla.components.browser.engine.gecko.ext import mozilla.components.concept.engine.prompt.CreditCard +import mozilla.components.support.utils.creditCardIIN import org.mozilla.geckoview.Autocomplete -// Placeholder for the card type. This will be replaced when we can identify the card type. -// This is dependent on https://github.com/mozilla-mobile/android-components/issues/9813. -private const val CARD_TYPE_PLACEHOLDER = "" - /** * Converts a GeckoView [Autocomplete.CreditCard] to an Android Components [CreditCard]. */ @@ -20,7 +17,7 @@ fun Autocomplete.CreditCard.toCreditCard() = CreditCard( number = number, expiryMonth = expirationMonth, expiryYear = expirationYear, - cardType = CARD_TYPE_PLACEHOLDER + cardType = number.creditCardIIN()?.creditCardIssuerNetwork?.name ?: "" ) /** diff --git a/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/creditcard/CreditCardItemViewHolder.kt b/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/creditcard/CreditCardItemViewHolder.kt index 8417c6b8e47..76b527a2c40 100644 --- a/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/creditcard/CreditCardItemViewHolder.kt +++ b/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/creditcard/CreditCardItemViewHolder.kt @@ -5,10 +5,12 @@ package mozilla.components.feature.prompts.creditcard import android.view.View +import android.widget.ImageView import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import mozilla.components.concept.engine.prompt.CreditCard import mozilla.components.feature.prompts.R +import mozilla.components.support.utils.creditCardIssuerNetwork import java.text.SimpleDateFormat import java.util.Calendar import java.util.Locale @@ -29,6 +31,10 @@ class CreditCardItemViewHolder( * @param creditCard The [CreditCard] to display. */ fun bind(creditCard: CreditCard) { + creditCard.cardType.creditCardIssuerNetwork()?.let { + itemView.findViewById(R.id.credit_card_logo).setImageResource(it.icon) + } + itemView.findViewById(R.id.credit_card_number).text = creditCard.obfuscatedCardNumber diff --git a/components/feature/prompts/src/main/res/layout/mozac_feature_prompts_credit_card_list_item.xml b/components/feature/prompts/src/main/res/layout/mozac_feature_prompts_credit_card_list_item.xml index 4b011aff912..34bc24b7ef3 100644 --- a/components/feature/prompts/src/main/res/layout/mozac_feature_prompts_credit_card_list_item.xml +++ b/components/feature/prompts/src/main/res/layout/mozac_feature_prompts_credit_card_list_item.xml @@ -9,32 +9,43 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:attr/selectableItemBackground" - android:clickable="true" - android:focusable="true" - android:minHeight="?android:attr/listPreferredItemHeight" - android:paddingStart="63dp" - android:paddingTop="8dp" - android:paddingEnd="8dp" - android:paddingBottom="8dp"> + android:minHeight="?android:attr/listPreferredItemHeight"> + + diff --git a/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/creditcard/CreditCardItemViewHolderTest.kt b/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/creditcard/CreditCardItemViewHolderTest.kt index d81a05e05ee..0cb08d848e0 100644 --- a/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/creditcard/CreditCardItemViewHolderTest.kt +++ b/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/creditcard/CreditCardItemViewHolderTest.kt @@ -6,13 +6,16 @@ package mozilla.components.feature.prompts.creditcard import android.view.LayoutInflater import android.view.View +import android.widget.ImageView import android.widget.TextView import androidx.test.ext.junit.runners.AndroidJUnit4 import mozilla.components.concept.engine.prompt.CreditCard import mozilla.components.feature.prompts.R import mozilla.components.support.test.mock import mozilla.components.support.test.robolectric.testContext +import mozilla.components.support.utils.CreditCardNetworkType import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -21,6 +24,7 @@ import org.junit.runner.RunWith class CreditCardItemViewHolderTest { private lateinit var view: View + private lateinit var cardLogoView: ImageView private lateinit var cardNumberView: TextView private lateinit var expirationDateView: TextView private lateinit var onCreditCardSelected: (CreditCard) -> Unit @@ -28,24 +32,26 @@ class CreditCardItemViewHolderTest { private val creditCard = CreditCard( guid = "1", name = "Banana Apple", - number = "4111111111111110", + number = "4111111111111111", expiryMonth = "5", expiryYear = "2030", - cardType = "amex" + cardType = CreditCardNetworkType.VISA.cardName ) @Before fun setup() { view = LayoutInflater.from(testContext).inflate(CreditCardItemViewHolder.LAYOUT_ID, null) + cardLogoView = view.findViewById(R.id.credit_card_logo) cardNumberView = view.findViewById(R.id.credit_card_number) expirationDateView = view.findViewById(R.id.credit_card_expiration_date) onCreditCardSelected = mock() } @Test - fun `GIVEN a credit card item WHEN bind is called THEN set the card number and expiry date text`() { + fun `GIVEN a credit card item WHEN bind is called THEN set the card number, logo and expiry date`() { CreditCardItemViewHolder(view, onCreditCardSelected).bind(creditCard) + assertNotNull(cardLogoView.drawable) assertEquals(creditCard.obfuscatedCardNumber, cardNumberView.text) assertEquals("0${creditCard.expiryMonth}/${creditCard.expiryYear}", expirationDateView.text) } diff --git a/components/support/utils/src/main/java/mozilla/components/support/utils/CreditCardUtils.kt b/components/support/utils/src/main/java/mozilla/components/support/utils/CreditCardUtils.kt new file mode 100644 index 00000000000..a380b3eb3d7 --- /dev/null +++ b/components/support/utils/src/main/java/mozilla/components/support/utils/CreditCardUtils.kt @@ -0,0 +1,303 @@ +/* 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 mozilla.components.support.utils + +import androidx.annotation.DrawableRes +import kotlin.math.floor +import kotlin.math.log10 + +/** + * Information about a credit card issuing network. + * + * @param name The name of the credit card issuer network. + * @param icon The icon of the credit card issuer network. + */ +data class CreditCardIssuerNetwork( + val name: String, + @DrawableRes val icon: Int +) + +/** + * Information about a credit card issuer identification numbers. + * + * @param startRange The start issuer identification number range. + * @param endRange The end issuer identification number range. + * @param cardNumberMaxLength A list of the range of maximum card number lengths. + */ +data class CreditCardIIN( + val creditCardIssuerNetwork: CreditCardIssuerNetwork, + val startRange: Int, + val endRange: Int, + val cardNumberMaxLength: List +) + +/** + * Enum of supported credit card network types. This list mirrors the networks from + * https://searchfox.org/mozilla-central/source/toolkit/modules/CreditCard.jsm + */ +enum class CreditCardNetworkType(val cardName: String) { + AMEX("amex"), + CARTEBANCAIRE("cartebancaire"), + DINERS("diners"), + DISCOVER("discover"), + JCB("jcb"), + MASTERCARD("mastercard"), + MIR("mir"), + UNIONPAY("unionpay"), + VISA("visa"), + GENERIC("") +} + +/** + * A mapping of credit card numbers to their respective credit card issuers. + */ +@Suppress("MagicNumber") +internal object CreditCardUtils { + + private val GENERIC = CreditCardIssuerNetwork( + name = CreditCardNetworkType.GENERIC.cardName, + icon = R.drawable.ic_icon_credit_card_generic + ) + private val AMEX = CreditCardIssuerNetwork( + name = CreditCardNetworkType.AMEX.cardName, + icon = R.drawable.ic_cc_logo_amex + ) + private val CARTEBANCAIRE = CreditCardIssuerNetwork( + name = CreditCardNetworkType.CARTEBANCAIRE.cardName, + icon = R.drawable.ic_icon_credit_card_generic + ) + private val DINERS = CreditCardIssuerNetwork( + name = CreditCardNetworkType.DINERS.cardName, + icon = R.drawable.ic_cc_logo_diners + ) + private val DISCOVER = CreditCardIssuerNetwork( + name = CreditCardNetworkType.DISCOVER.cardName, + icon = R.drawable.ic_cc_logo_discover + ) + private val JCB = CreditCardIssuerNetwork( + name = CreditCardNetworkType.JCB.cardName, + icon = R.drawable.ic_cc_logo_jcb + ) + private val MIR = CreditCardIssuerNetwork( + name = CreditCardNetworkType.MIR.cardName, + icon = R.drawable.ic_cc_logo_mir + ) + private val UNIONPAY = CreditCardIssuerNetwork( + name = CreditCardNetworkType.UNIONPAY.cardName, + icon = R.drawable.ic_cc_logo_unionpay + ) + private val VISA = CreditCardIssuerNetwork( + name = CreditCardNetworkType.VISA.cardName, + icon = R.drawable.ic_cc_logo_visa + ) + private val MASTERCARD = CreditCardIssuerNetwork( + name = CreditCardNetworkType.MASTERCARD.cardName, + icon = R.drawable.ic_cc_logo_mastercard + ) + + /** + * Map of recognized credit card issuer network name to their [CreditCardIssuerNetwork]. + */ + private val creditCardIssuers = mapOf( + CreditCardNetworkType.AMEX.cardName to AMEX, + CreditCardNetworkType.CARTEBANCAIRE.cardName to CARTEBANCAIRE, + CreditCardNetworkType.DINERS.cardName to DINERS, + CreditCardNetworkType.DISCOVER.cardName to DISCOVER, + CreditCardNetworkType.JCB.cardName to JCB, + CreditCardNetworkType.MIR.cardName to MIR, + CreditCardNetworkType.UNIONPAY.cardName to UNIONPAY, + CreditCardNetworkType.VISA.cardName to VISA, + CreditCardNetworkType.MASTERCARD.cardName to MASTERCARD + ) + + /** + * List of recognized credit card issuer networks. + * + * Based on https://searchfox.org/mozilla-central/rev/4275e4bd2b2aba34b2c69b314c4b50bdf83520af/toolkit/modules/CreditCard.jsm#40 + */ + private val creditCardIINs = listOf( + CreditCardIIN( + creditCardIssuerNetwork = AMEX, + startRange = 34, + endRange = 34, + cardNumberMaxLength = listOf(15) + ), + CreditCardIIN( + creditCardIssuerNetwork = AMEX, + startRange = 37, + endRange = 37, + cardNumberMaxLength = listOf(15) + ), + CreditCardIIN( + creditCardIssuerNetwork = CARTEBANCAIRE, + startRange = 4035, + endRange = 4035, + cardNumberMaxLength = listOf(16) + ), + CreditCardIIN( + creditCardIssuerNetwork = CARTEBANCAIRE, + startRange = 4360, + endRange = 4360, + cardNumberMaxLength = listOf(16) + ), + // We diverge from Wikipedia here, because Diners card + // support length of 14-19. + CreditCardIIN( + creditCardIssuerNetwork = DINERS, + startRange = 300, + endRange = 305, + cardNumberMaxLength = listOf(14, 19) + ), + CreditCardIIN( + creditCardIssuerNetwork = DINERS, + startRange = 3095, + endRange = 3095, + cardNumberMaxLength = listOf(14, 19) + ), + CreditCardIIN( + creditCardIssuerNetwork = DINERS, + startRange = 36, + endRange = 36, + cardNumberMaxLength = listOf(14, 19) + ), + CreditCardIIN( + creditCardIssuerNetwork = DINERS, + startRange = 38, + endRange = 39, + cardNumberMaxLength = listOf(14, 19) + ), + CreditCardIIN( + creditCardIssuerNetwork = DISCOVER, + startRange = 6011, + endRange = 6011, + cardNumberMaxLength = listOf(16, 19) + ), + CreditCardIIN( + creditCardIssuerNetwork = DISCOVER, + startRange = 622126, + endRange = 622925, + cardNumberMaxLength = listOf(16, 19) + ), + CreditCardIIN( + creditCardIssuerNetwork = DISCOVER, + startRange = 624000, + endRange = 626999, + cardNumberMaxLength = listOf(16, 19) + ), + CreditCardIIN( + creditCardIssuerNetwork = DISCOVER, + startRange = 628200, + endRange = 628899, + cardNumberMaxLength = listOf(16, 19) + ), + CreditCardIIN( + creditCardIssuerNetwork = DISCOVER, + startRange = 64, + endRange = 65, + cardNumberMaxLength = listOf(16, 19) + ), + CreditCardIIN( + creditCardIssuerNetwork = JCB, + startRange = 3528, + endRange = 3589, + cardNumberMaxLength = listOf(16, 19) + ), + CreditCardIIN( + creditCardIssuerNetwork = MASTERCARD, + startRange = 2221, + endRange = 2720, + cardNumberMaxLength = listOf(16) + ), + CreditCardIIN( + creditCardIssuerNetwork = MASTERCARD, + startRange = 51, + endRange = 55, + cardNumberMaxLength = listOf(16) + ), + CreditCardIIN( + creditCardIssuerNetwork = MIR, + startRange = 2200, + endRange = 2204, + cardNumberMaxLength = listOf(16) + ), + CreditCardIIN( + creditCardIssuerNetwork = UNIONPAY, + startRange = 62, + endRange = 62, + cardNumberMaxLength = listOf(16, 19) + ), + CreditCardIIN( + creditCardIssuerNetwork = UNIONPAY, + startRange = 81, + endRange = 81, + cardNumberMaxLength = listOf(16, 19) + ), + CreditCardIIN( + creditCardIssuerNetwork = VISA, + startRange = 4, + endRange = 4, + cardNumberMaxLength = listOf(16) + ) + ).sortedWith { a, b -> b.startRange - a.startRange } + + /** + * Returns the [CreditCardIIN] for the provided credit card number. + * + * Based on https://searchfox.org/mozilla-central/rev/4275e4bd2b2aba34b2c69b314c4b50bdf83520af/toolkit/modules/CreditCard.jsm#229 + * + * @param cardNumber The credit card number. + * @return the [CreditCardIIN] for the provided credit card number or null if it does not + * match any of the recognized credit card issuers. + */ + @Suppress("ComplexMethod") + fun getCreditCardIIN(cardNumber: String): CreditCardIIN? { + for (issuer in creditCardIINs) { + if (issuer.cardNumberMaxLength.size == 1 && + issuer.cardNumberMaxLength[0] != cardNumber.length + ) { + continue + } else if (issuer.cardNumberMaxLength.size > 1 && + (cardNumber.length < issuer.cardNumberMaxLength[0] || + cardNumber.length > issuer.cardNumberMaxLength[1]) + ) { + continue + } + + val prefixLength = floor(log10(issuer.startRange.toDouble())) + 1 + val prefix = cardNumber.substring(0, prefixLength.toInt()).toInt() + + if (prefix >= issuer.startRange && prefix <= issuer.endRange) { + return issuer + } + } + + return null + } + + /** + * Returns the [CreditCardIssuerNetwork] for the provided credit card issuer network name. + * + * @param cardType The credit card issuer network name. + * @return the [CreditCardIssuerNetwork] for the provided credit card issuer network. + */ + fun getCreditCardIssuerNetwork(cardType: String): CreditCardIssuerNetwork = + creditCardIssuers[cardType] ?: GENERIC +} + +/** + * Returns the [CreditCardIIN] for the provided credit card number. + * + * @return the [CreditCardIIN] for the provided credit card number or null if it does not + * match any of the recognized credit card issuers. + */ +fun String.creditCardIIN() = CreditCardUtils.getCreditCardIIN(this) + +/** + * Returns the [CreditCardIssuerNetwork] for the provided credit card type. + * + * @return the [CreditCardIssuerNetwork] for the provided credit card type orr null if it + * does not match any of recognized credit card type. + */ +fun String.creditCardIssuerNetwork() = CreditCardUtils.getCreditCardIssuerNetwork(this) diff --git a/components/support/utils/src/main/res/drawable/ic_cc_logo_amex.xml b/components/support/utils/src/main/res/drawable/ic_cc_logo_amex.xml new file mode 100644 index 00000000000..535799953a9 --- /dev/null +++ b/components/support/utils/src/main/res/drawable/ic_cc_logo_amex.xml @@ -0,0 +1,4 @@ + + + diff --git a/components/support/utils/src/main/res/drawable/ic_cc_logo_diners.xml b/components/support/utils/src/main/res/drawable/ic_cc_logo_diners.xml new file mode 100644 index 00000000000..9f8390e9f76 --- /dev/null +++ b/components/support/utils/src/main/res/drawable/ic_cc_logo_diners.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + diff --git a/components/support/utils/src/main/res/drawable/ic_cc_logo_discover.xml b/components/support/utils/src/main/res/drawable/ic_cc_logo_discover.xml new file mode 100644 index 00000000000..d58bd7c7af7 --- /dev/null +++ b/components/support/utils/src/main/res/drawable/ic_cc_logo_discover.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/support/utils/src/main/res/drawable/ic_cc_logo_jcb.xml b/components/support/utils/src/main/res/drawable/ic_cc_logo_jcb.xml new file mode 100644 index 00000000000..be738bb5b5d --- /dev/null +++ b/components/support/utils/src/main/res/drawable/ic_cc_logo_jcb.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/support/utils/src/main/res/drawable/ic_cc_logo_mastercard.xml b/components/support/utils/src/main/res/drawable/ic_cc_logo_mastercard.xml new file mode 100644 index 00000000000..0f83295c444 --- /dev/null +++ b/components/support/utils/src/main/res/drawable/ic_cc_logo_mastercard.xml @@ -0,0 +1,38 @@ + + + + + + + diff --git a/components/support/utils/src/main/res/drawable/ic_cc_logo_mir.xml b/components/support/utils/src/main/res/drawable/ic_cc_logo_mir.xml new file mode 100644 index 00000000000..367897fff41 --- /dev/null +++ b/components/support/utils/src/main/res/drawable/ic_cc_logo_mir.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + diff --git a/components/support/utils/src/main/res/drawable/ic_cc_logo_unionpay.xml b/components/support/utils/src/main/res/drawable/ic_cc_logo_unionpay.xml new file mode 100644 index 00000000000..b231f3b7a88 --- /dev/null +++ b/components/support/utils/src/main/res/drawable/ic_cc_logo_unionpay.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/support/utils/src/main/res/drawable/ic_cc_logo_visa.xml b/components/support/utils/src/main/res/drawable/ic_cc_logo_visa.xml new file mode 100644 index 00000000000..d2e1e3a506a --- /dev/null +++ b/components/support/utils/src/main/res/drawable/ic_cc_logo_visa.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + diff --git a/components/support/utils/src/main/res/drawable/ic_icon_credit_card_generic.xml b/components/support/utils/src/main/res/drawable/ic_icon_credit_card_generic.xml new file mode 100644 index 00000000000..f9a47fcc818 --- /dev/null +++ b/components/support/utils/src/main/res/drawable/ic_icon_credit_card_generic.xml @@ -0,0 +1,19 @@ + + + + + + + diff --git a/components/support/utils/src/test/java/mozilla/components/support/utils/CreditCardUtilsTest.kt b/components/support/utils/src/test/java/mozilla/components/support/utils/CreditCardUtilsTest.kt new file mode 100644 index 00000000000..230376abd40 --- /dev/null +++ b/components/support/utils/src/test/java/mozilla/components/support/utils/CreditCardUtilsTest.kt @@ -0,0 +1,109 @@ +/* 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 mozilla.components.support.utils + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class CreditCardUtilsTest { + + @Test + fun `GIVEN a list of recognized card numbers and their respective card type WHEN creditCardIIN is called for a given a card number THEN the correct cardType name is returned`() { + /** + * Test cases based on + * https://searchfox.org/mozilla-central/source/toolkit/modules/tests/xpcshell/test_CreditCard.js + */ + val recognizedCards = listOf( + // Edge cases + Pair("2221000000000000", "mastercard"), + Pair("2720000000000000", "mastercard"), + Pair("2200000000000000", "mir"), + Pair("2204000000000000", "mir"), + Pair("340000000000000", "amex"), + Pair("370000000000000", "amex"), + Pair("3000000000000000", "diners"), + Pair("3050000000000000", "diners"), + Pair("3095000000000000", "diners"), + Pair("36000000000000", "diners"), + Pair("3800000000000000", "diners"), + Pair("3900000000000000", "diners"), + Pair("3528000000000000", "jcb"), + Pair("3589000000000000", "jcb"), + Pair("4035000000000000", "cartebancaire"), + Pair("4360000000000000", "cartebancaire"), + Pair("4000000000000000", "visa"), + Pair("4999999999999999", "visa"), + Pair("5400000000000000", "mastercard"), + Pair("5500000000000000", "mastercard"), + Pair("5100000000000000", "mastercard"), + Pair("5399999999999999", "mastercard"), + Pair("6011000000000000", "discover"), + Pair("6221260000000000", "discover"), + Pair("6229250000000000", "discover"), + Pair("6240000000000000", "discover"), + Pair("6269990000000000", "discover"), + Pair("6282000000000000", "discover"), + Pair("6288990000000000", "discover"), + Pair("6400000000000000", "discover"), + Pair("6500000000000000", "discover"), + Pair("6200000000000000", "unionpay"), + Pair("8100000000000000", "unionpay"), + // Valid according to Luhn number + Pair("2204941877211882", "mir"), + Pair("2720994326581252", "mastercard"), + Pair("374542158116607", "amex"), + Pair("36006666333344", "diners"), + Pair("3541675340715696", "jcb"), + Pair("3543769248058305", "jcb"), + Pair("4035501428146300", "cartebancaire"), + Pair("4111111111111111", "visa"), + Pair("5346755600299631", "mastercard"), + Pair("5495770093313616", "mastercard"), + Pair("5574238524540144", "mastercard"), + Pair("6011029459267962", "discover"), + Pair("6278592974938779", "unionpay"), + Pair("8171999927660000", "unionpay"), + Pair("30569309025904", "diners"), + Pair("38520000023237", "diners") + ) + + for ((cardNumber, cardType) in recognizedCards) { + assertEquals(cardNumber.creditCardIIN()?.creditCardIssuerNetwork?.name, cardType) + } + + val unrecognizedCards = listOf( + "411111111111111", + "41111111111111111", + "", + "9111111111111111" + ) + + for (cardNumber in unrecognizedCards) { + assertNull(cardNumber.creditCardIIN()) + } + } + + @Test + fun `GIVEN a various card type strings WHEN creditCardIssuerNetwork is called THEN the correct CreditCardIssuerNetwork is returned`() { + val amexCard = CreditCardIssuerNetwork( + name = CreditCardNetworkType.AMEX.cardName, + icon = R.drawable.ic_cc_logo_amex + ) + + assertEquals(amexCard, CreditCardNetworkType.AMEX.cardName.creditCardIssuerNetwork()) + + val genericCard = CreditCardIssuerNetwork( + name = CreditCardNetworkType.GENERIC.cardName, + icon = R.drawable.ic_icon_credit_card_generic + ) + + assertEquals(genericCard, "".creditCardIssuerNetwork()) + assertEquals(genericCard, "blah".creditCardIssuerNetwork()) + } +}