package com.peachpasswords.autofill import com.peachpasswords.vault.VaultEntry import com.peachpasswords.vault.isCard import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test class AutofillCardTest { private fun card( title: String = "Visa", number: String = "4111111111111111", expMonth: String = "09", expYear: String = "2028", cvc: String = "123", name: String = "June Doe", ) = VaultEntry( id = title, title = title, type = "card", cardNumber = number, expMonth = expMonth, expYear = expYear, cvc = cvc, cardholderName = name, createdAt = 0, modifiedAt = 0, ) @Test fun card_entry_is_recognised() { assertTrue(card().isCard()) assertFalse(VaultEntry(id = "l", title = "Login", createdAt = 0, modifiedAt = 0).isCard()) } @Test fun card_entries_not_domain_matched() { val visa = card() val result = AutofillResponseBuilder.matchEntries(listOf(visa), "shop.example.com") assertTrue("cards have no URL so domain matching yields nothing", result.hits.isEmpty()) } @Test fun combo_expiry_formats_mm_yy() { val visa = card(expMonth = "9", expYear = "2028") val mm = visa.expMonth!!.padStart(2, '0') val yy = visa.expYear!!.takeLast(2) assertEquals("09/28", "$mm/$yy") } @Test fun combo_expiry_handles_four_digit_year() { val visa = card(expMonth = "12", expYear = "2030") val mm = visa.expMonth!!.padStart(2, '0') val yy = visa.expYear!!.takeLast(2) assertEquals("12/30", "$mm/$yy") } @Test fun card_number_strips_non_digits() { val visa = card(number = "4111 1111 1111 1111") val digits = visa.cardNumber!!.filter { it.isDigit() } assertEquals("4111111111111111", digits) } @Test fun card_heuristic_regexes_match_common_labels() { val cardNumberRx = Regex("\\b(card\\s*number|credit\\s*card|card\\s*no|pan|cc\\s*num)\\b") assertTrue(cardNumberRx.containsMatchIn("card number")) assertTrue(cardNumberRx.containsMatchIn("credit card")) assertTrue(cardNumberRx.containsMatchIn("cc num")) assertFalse(cardNumberRx.containsMatchIn("discard number")) val cvcRx = Regex("\\b(cvc|cvv|security\\s*code|card\\s*code)\\b") assertTrue(cvcRx.containsMatchIn("cvc")) assertTrue(cvcRx.containsMatchIn("security code")) val nameRx = Regex("\\b(cardholder|card\\s*holder|name\\s*on\\s*card|card\\s*name)\\b") assertTrue(nameRx.containsMatchIn("cardholder name")) assertTrue(nameRx.containsMatchIn("name on card")) assertFalse(nameRx.containsMatchIn("username")) val expMonthRx = Regex("\\b(exp\\s*month|expiration\\s*month|expiry\\s*month)\\b") assertTrue(expMonthRx.containsMatchIn("exp month")) assertTrue(expMonthRx.containsMatchIn("expiration month")) val expDateRx = Regex("\\b(exp\\s*date|expiration\\s*date|expiry\\s*date|exp\\b)") assertTrue(expDateRx.containsMatchIn("exp date")) assertTrue(expDateRx.containsMatchIn("exp")) } @Test fun picker_parsed_from_inputs_carries_card_ids() { val parsed = pickerParsedFromInputs( origin = "shop.example.com", isWebOrigin = true, callerPackage = "com.android.chrome", ) assertFalse(parsed.hasCardField) assertEquals("shop.example.com", parsed.webDomain) assertEquals("com.android.chrome", parsed.packageName) } }