1package com.peachpasswords.autofill23import com.peachpasswords.vault.VaultEntry4import com.peachpasswords.vault.isCard5import org.junit.Assert.assertEquals6import org.junit.Assert.assertFalse7import org.junit.Assert.assertTrue8import org.junit.Test910class AutofillCardTest {1112 private fun card(13 title: String = "Visa",14 number: String = "4111111111111111",15 expMonth: String = "09",16 expYear: String = "2028",17 cvc: String = "123",18 name: String = "June Doe",19 ) = VaultEntry(20 id = title,21 title = title,22 type = "card",23 cardNumber = number,24 expMonth = expMonth,25 expYear = expYear,26 cvc = cvc,27 cardholderName = name,28 createdAt = 0,29 modifiedAt = 0,30 )3132 @Test fun card_entry_is_recognised() {33 assertTrue(card().isCard())34 assertFalse(VaultEntry(id = "l", title = "Login", createdAt = 0, modifiedAt = 0).isCard())35 }3637 @Test fun card_entries_not_domain_matched() {38 val visa = card()39 val result = AutofillResponseBuilder.matchEntries(listOf(visa), "shop.example.com")40 assertTrue("cards have no URL so domain matching yields nothing", result.hits.isEmpty())41 }4243 @Test fun combo_expiry_formats_mm_yy() {44 val visa = card(expMonth = "9", expYear = "2028")45 val mm = visa.expMonth!!.padStart(2, '0')46 val yy = visa.expYear!!.takeLast(2)47 assertEquals("09/28", "$mm/$yy")48 }4950 @Test fun combo_expiry_handles_four_digit_year() {51 val visa = card(expMonth = "12", expYear = "2030")52 val mm = visa.expMonth!!.padStart(2, '0')53 val yy = visa.expYear!!.takeLast(2)54 assertEquals("12/30", "$mm/$yy")55 }5657 @Test fun card_number_strips_non_digits() {58 val visa = card(number = "4111 1111 1111 1111")59 val digits = visa.cardNumber!!.filter { it.isDigit() }60 assertEquals("4111111111111111", digits)61 }6263 @Test fun card_heuristic_regexes_match_common_labels() {64 val cardNumberRx = Regex("\\b(card\\s*number|credit\\s*card|card\\s*no|pan|cc\\s*num)\\b")65 assertTrue(cardNumberRx.containsMatchIn("card number"))66 assertTrue(cardNumberRx.containsMatchIn("credit card"))67 assertTrue(cardNumberRx.containsMatchIn("cc num"))68 assertFalse(cardNumberRx.containsMatchIn("discard number"))6970 val cvcRx = Regex("\\b(cvc|cvv|security\\s*code|card\\s*code)\\b")71 assertTrue(cvcRx.containsMatchIn("cvc"))72 assertTrue(cvcRx.containsMatchIn("security code"))7374 val nameRx = Regex("\\b(cardholder|card\\s*holder|name\\s*on\\s*card|card\\s*name)\\b")75 assertTrue(nameRx.containsMatchIn("cardholder name"))76 assertTrue(nameRx.containsMatchIn("name on card"))77 assertFalse(nameRx.containsMatchIn("username"))7879 val expMonthRx = Regex("\\b(exp\\s*month|expiration\\s*month|expiry\\s*month)\\b")80 assertTrue(expMonthRx.containsMatchIn("exp month"))81 assertTrue(expMonthRx.containsMatchIn("expiration month"))8283 val expDateRx = Regex("\\b(exp\\s*date|expiration\\s*date|expiry\\s*date|exp\\b)")84 assertTrue(expDateRx.containsMatchIn("exp date"))85 assertTrue(expDateRx.containsMatchIn("exp"))86 }8788 @Test fun picker_parsed_from_inputs_carries_card_ids() {89 val parsed = pickerParsedFromInputs(90 origin = "shop.example.com",91 isWebOrigin = true,92 callerPackage = "com.android.chrome",93 )94 assertFalse(parsed.hasCardField)95 assertEquals("shop.example.com", parsed.webDomain)96 assertEquals("com.android.chrome", parsed.packageName)97 }98}