private boolean isCvcLengthValid() { String cvcValue = mCvcNumberEditText.getText().toString().trim(); int cvcLength = cvcValue.length(); if (mIsAmEx && cvcLength == Card.CVC_LENGTH_AMERICAN_EXPRESS) { return true; } if (cvcLength == Card.CVC_LENGTH_COMMON) { return true; } return false; }
private boolean isCvcLengthValid() { int cvcLength = mCvcEditText.getText().toString().trim().length(); if (TextUtils.equals(Card.AMERICAN_EXPRESS, mCardBrand) && cvcLength == Card.CVC_LENGTH_AMERICAN_EXPRESS) { return true; } if (cvcLength == Card.CVC_LENGTH_COMMON) { return true; } return false; }
public ShippingInformation getShippingInformation() { if (!validateAllFields()) { return null; } Address address = new Address.Builder().setCity(mCityEditText.getText().toString()) .setCountry(mCountryAutoCompleteTextView.getSelectedCountryCode()).setLine1 (mAddressEditText.getText().toString()).setLine2 (mAddressEditText2.getText().toString()).setPostalCode (mPostalCodeEditText.getText().toString()).setState(mStateEditText .getText().toString()).build(); ShippingInformation shippingInformation = new ShippingInformation(address, mNameEditText .getText().toString(), mPhoneNumberEditText.getText().toString()); return shippingInformation; }
@Override public void onDeleteEmpty() { String fieldText = backUpTarget.getText().toString(); if (fieldText.length() > 1) { backUpTarget.setText( fieldText.substring(0, fieldText.length() - 1)); } backUpTarget.requestFocus(); backUpTarget.setSelection(backUpTarget.length()); } }
@Override public void onInitializeAccessibilityNodeInfo( @NonNull View host, @NonNull AccessibilityNodeInfoCompat info) { super.onInitializeAccessibilityNodeInfo(host, info); final String accLabel = getResources().getString( R.string.acc_label_cvc_node, mCvcNumberEditText.getText() ); info.setText(accLabel); }
@Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { scrollRight(); if (mCardInputListener != null) { mCardInputListener.onFocusChange(FOCUS_CVC); } } updateIconCvc( mCardNumberEditText.getCardBrand(), hasFocus, mCvcNumberEditText.getText().toString()); } });
private void flipToCvcIconIfNotFinished() { if (ViewUtils.isCvcMaximalLength(mCardBrand, mCvcEditText.getText().toString())) { return; } @DrawableRes int resourceId = Card.AMERICAN_EXPRESS.equals(mCardBrand) ? R.drawable.ic_cvc_amex : R.drawable.ic_cvc; updateDrawable(resourceId, true); }
/** * Gets a {@link Card} object from the user input, if all fields are valid. If not, returns * {@code null}. * * @return a valid {@link Card} object based on user input, or {@code null} if any field is * invalid */ @Nullable public Card getCard() { if (validateAllFields()) { String cardNumber = mCardNumberEditText.getCardNumber(); int[] cardDate = mExpiryDateEditText.getValidDateFields(); String cvcValue = mCvcEditText.getText().toString(); Card card = new Card(cardNumber, cardDate[0], cardDate[1], cvcValue); if (mShouldShowPostalCode) { card.setAddressZip(mPostalCodeEditText.getText().toString()); } return card.addLoggingToken(CARD_MULTILINE_TOKEN); } return null; }
@Test public void populateShippingInfo_whenShippingInfoProvided_populates() { mShippingInfoWidget.populateShippingInfo(mShippingInfo); assertEquals(mStateEditText.getText().toString(), "CA"); assertEquals(mCityEditText.getText().toString(), "San Francisco"); assertEquals(mAddressLine1EditText.getText().toString(), "185 Berry St"); assertEquals(mAddressLine2EditText.getText().toString(), "10th Floor"); assertEquals(mPhoneEditText.getText().toString(), "(123) 456 - 7890"); assertEquals(mPostalEditText.getText().toString(), "12345"); assertEquals(mNameEditText.getText().toString(), "Fake Name"); assertEquals(mCountryAutoCompleteTextView.getSelectedCountryCode(), "US"); }
/** * Gets a {@link Card} object from the user input, if all fields are valid. If not, returns * {@code null}. * * @return a valid {@link Card} object based on user input, or {@code null} if any field is * invalid */ @Nullable public Card getCard() { String cardNumber = mCardNumberEditText.getCardNumber(); int[] cardDate = mExpiryDateEditText.getValidDateFields(); if (cardNumber == null || cardDate == null || cardDate.length != 2) { return null; } // CVC/CVV is the only field not validated by the entry control itself, so we check here. String cvcValue = mCvcNumberEditText.getText().toString().trim(); if (!isCvcLengthValid()) { return null; } return new Card(cardNumber, cardDate[0], cardDate[1], cvcValue) .addLoggingToken(LOGGING_TOKEN); }
@Test public void setCvcCode_withLongString_truncatesValue() { mCardInputWidget.setCvcCode("1234"); assertEquals("123", mCvcEditText.getText().toString()); }
@Test public void setExpirationDate_withValidData_setsCorrectValues() { mCardInputWidget.setExpiryDate(12, 79); assertEquals("12/79", mExpiryEditText.getText().toString()); }
@Test public void setCvcCode_withValidData_setsValue() { mCardInputWidget.setCvcCode("123"); assertEquals("123", mCvcEditText.getText().toString()); }
@Test public void setCvcCode_whenCardBrandIsAmericanExpress_allowsFourDigits() { mCardInputWidget.setCardNumber(VALID_AMEX_NO_SPACES); mCardInputWidget.setCvcCode("1234"); assertEquals("1234", mCvcEditText.getText().toString()); }
@Test public void deleteWhenEmpty_fromPostalCode_shiftsToCvc() { mCardMultilineWidget.setCardInputListener(mFullCardListener); mFullGroup.cardNumberEditText.setText(VALID_DINERS_CLUB_WITH_SPACES); mFullGroup.expiryDateEditText.append("12"); mFullGroup.expiryDateEditText.append("50"); mFullGroup.cvcEditText.append("123"); reset(mFullCardListener); ViewTestUtils.sendDeleteKeyEvent(mFullGroup.postalCodeEditText); verify(mFullCardListener, times(1)).onFocusChange(FOCUS_CVC); assertEquals("12", mFullGroup.cvcEditText.getText().toString()); }
@Test public void clear_whenZipRequiredAndAllFieldsEntered_clearsAllfields() { // The input date here will be invalid after 2050. Please update the test. assertTrue(Calendar.getInstance().get(Calendar.YEAR) < 2050); mFullGroup.cardNumberEditText.setText(VALID_VISA_WITH_SPACES); mFullGroup.expiryDateEditText.append("12"); mFullGroup.expiryDateEditText.append("50"); mFullGroup.cvcEditText.append("123"); mFullGroup.postalCodeEditText.append("12345"); mCardMultilineWidget.clear(); assertEquals("", mFullGroup.cardNumberEditText.getText().toString()); assertEquals("", mFullGroup.expiryDateEditText.getText().toString()); assertEquals("", mFullGroup.cvcEditText.getText().toString()); assertEquals("", mFullGroup.postalCodeEditText.getText().toString()); }
@Test public void addValues_thenClear_leavesAllTextFieldsEmpty() { mCardInputWidget.setCardNumber(VALID_AMEX_NO_SPACES); mCardInputWidget.setExpiryDate(12, 2079); mCardInputWidget.setCvcCode("1234"); mCardInputWidget.clear(); assertEquals("", mCardNumberEditText.getText().toString()); assertEquals("", mExpiryEditText.getText().toString()); assertEquals("", mCvcEditText.getText().toString()); assertEquals(R.id.et_cvc_number, mOnGlobalFocusChangeListener.getOldFocusId()); assertEquals(R.id.et_card_number, mOnGlobalFocusChangeListener.getNewFocusId()); }
/** * Validates all fields and shows error messages if appropriate. * * @return {@code true} if all shown fields are valid, {@code false} otherwise */ public boolean validateAllFields() { boolean cardNumberIsValid = CardUtils.isValidCardNumber(mCardNumberEditText.getCardNumber()); boolean expiryIsValid = mExpiryDateEditText.getValidDateFields() != null && mExpiryDateEditText.isDateValid(); boolean cvcIsValid = isCvcLengthValid(); mCardNumberEditText.setShouldShowError(!cardNumberIsValid); mExpiryDateEditText.setShouldShowError(!expiryIsValid); mCvcEditText.setShouldShowError(!cvcIsValid); boolean postalCodeIsValidOrGone; if (mShouldShowPostalCode) { postalCodeIsValidOrGone = isPostalCodeMaximalLength(true, mPostalCodeEditText.getText().toString()); mPostalCodeEditText.setShouldShowError(!postalCodeIsValidOrGone); } else { postalCodeIsValidOrGone = true; } return cardNumberIsValid && expiryIsValid && cvcIsValid && postalCodeIsValidOrGone; }
@Test public void onDeleteFromCvcDate_whenNotEmpty_doesNotShiftFocusOrDeleteEntry() { // This test will be invalid if run between 2080 and 2112. Please update the code. assertTrue(Calendar.getInstance().get(Calendar.YEAR) < 2080); mCardNumberEditText.setText(VALID_AMEX_WITH_SPACES); mExpiryEditText.append("12"); mExpiryEditText.append("79"); assertTrue(mCvcEditText.hasFocus()); mCvcEditText.append("123"); ViewTestUtils.sendDeleteKeyEvent(mCvcEditText); assertTrue(mCvcEditText.hasFocus()); assertEquals("12/79", mExpiryEditText.getText().toString()); }
@Test public void onDeleteFromCvcDate_whenEmpty_shiftsFocusToExpiryAndDeletesDigit() { // This test will be invalid if run between 2080 and 2112. Please update the code. assertTrue(Calendar.getInstance().get(Calendar.YEAR) < 2080); mCardInputWidget.setCardInputListener(mCardInputListener); mCardNumberEditText.setText(VALID_VISA_WITH_SPACES); verify(mCardInputListener).onCardComplete(); verify(mCardInputListener).onFocusChange(FOCUS_EXPIRY); mExpiryEditText.append("12"); mExpiryEditText.append("79"); verify(mCardInputListener).onExpirationComplete(); verify(mCardInputListener).onFocusChange(FOCUS_CVC); assertTrue(mCvcEditText.hasFocus()); // Clearing already-verified data. reset(mCardInputListener); ViewTestUtils.sendDeleteKeyEvent(mCvcEditText); verify(mCardInputListener).onFocusChange(FOCUS_EXPIRY); assertEquals(R.id.et_cvc_number, mOnGlobalFocusChangeListener.getOldFocusId()); assertEquals(R.id.et_expiry_date, mOnGlobalFocusChangeListener.getNewFocusId()); String expectedResult = "12/7"; assertEquals(expectedResult, mExpiryEditText.getText().toString()); assertEquals(expectedResult.length(), mExpiryEditText.getSelectionStart()); }