Commit 8dcb6974 authored by ahutter@chromium.org's avatar ahutter@chromium.org

Force at least first and last name for CREDIT_CARD_NAME when using Wallet.

BUG=

Review URL: https://chromiumcodereview.appspot.com/15401005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@202618 0039d316-1c4b-4281-b951-d872f2087c98
parent b2f981a9
......@@ -10701,6 +10701,10 @@ Would you like to start <ph name="CONTROL_PANEL_APPLET_NAME">$1<ex>Add/Remove Pr
The <ph name="LEGAL_DOC_LINK_TEXT_1">$1<ex>Google Wallet Terms Of Service</ex></ph>, <ph name="LEGAL_DOC_LINK_TEXT_2">$2<ex>Privacy Policy</ex></ph>, and <ph name="LEGAL_DOC_LINK_TEXT_3">$3<ex>Terms Of Use</ex></ph> have been updated. By clicking Submit you verify that you accept these changes.
</message>
<!-- Autofill dialog: validation messages -->
<message name="IDS_AUTOFILL_DIALOG_VALIDATION_WALLET_REQUIRES_TWO_NAMES" desc="Message displayed to user when card holder name validation for Wallet fails.">
Google Wallet requires at least a first and last name.
</message>
<!-- Autocheckout bubble -->
<message name="IDS_AUTOCHECKOUT_BUBBLE_PROMPT_SIGNED_IN" desc="Text for prompting a Google user to start an Autocheckout flow.">
......
......@@ -322,6 +322,13 @@ const wallet::Address* FindDuplicateAddress(
return NULL;
}
bool IsCardHolderNameValidForWallet(const string16& name) {
base::string16 whitespace_collapsed_name = CollapseWhitespace(name, true);
std::vector<base::string16> split_name;
base::SplitString(whitespace_collapsed_name, ' ', &split_name);
return split_name.size() >= 2;
}
} // namespace
AutofillDialogController::~AutofillDialogController() {}
......@@ -1140,13 +1147,59 @@ gfx::Image AutofillDialogControllerImpl::IconForField(
string16 AutofillDialogControllerImpl::InputValidityMessage(
AutofillFieldType type,
const string16& value) const {
if (InputIsValid(type, value))
return string16();
switch (AutofillType::GetEquivalentFieldType(type)) {
case EMAIL_ADDRESS:
if (!value.empty() && !IsValidEmailAddress(value))
return ASCIIToUTF16("Are you sure this is right?");
break;
case CREDIT_CARD_NUMBER:
if (!value.empty() && !autofill::IsValidCreditCardNumber(value))
return ASCIIToUTF16("Are you sure this is right?");
break;
case CREDIT_CARD_NAME:
// Wallet requires a first and last name.
if (!value.empty() && IsPayingWithWallet() &&
!IsCardHolderNameValidForWallet(value)) {
return l10n_util::GetStringUTF16(
IDS_AUTOFILL_DIALOG_VALIDATION_WALLET_REQUIRES_TWO_NAMES);
}
break;
case CREDIT_CARD_EXP_MONTH:
case CREDIT_CARD_EXP_4_DIGIT_YEAR:
break;
case CREDIT_CARD_VERIFICATION_CODE:
if (!value.empty() && !autofill::IsValidCreditCardSecurityCode(value))
return ASCIIToUTF16("Are you sure this is right?");
break;
case ADDRESS_HOME_LINE1:
break;
case ADDRESS_HOME_LINE2:
return base::string16(); // Line 2 is optional - always valid.
case ADDRESS_HOME_CITY:
case ADDRESS_HOME_STATE:
case ADDRESS_HOME_ZIP:
case ADDRESS_HOME_COUNTRY:
break;
case NAME_FULL: // Used for shipping.
break;
case PHONE_HOME_WHOLE_NUMBER: // Used in billing section.
break;
if (value.empty())
return ASCIIToUTF16("You forgot one");
default:
NOTREACHED(); // Trying to validate unknown field.
break;
}
return ASCIIToUTF16("Are you sure this is right?");
return !value.empty() ? base::string16() : ASCIIToUTF16("You forgot one");
}
// TODO(estade): Replace all the error messages here with more helpful and
......@@ -1187,7 +1240,8 @@ ValidityData AutofillDialogControllerImpl::InputsAreValid(
// If there is a credit card number and a CVC, validate them together.
if (field_values.count(CREDIT_CARD_NUMBER) &&
field_values.count(CREDIT_CARD_VERIFICATION_CODE) &&
InputIsValid(CREDIT_CARD_NUMBER, field_values[CREDIT_CARD_NUMBER])) {
InputValidityMessage(CREDIT_CARD_NUMBER,
field_values[CREDIT_CARD_NUMBER]).empty()) {
if (!autofill::IsValidCreditCardSecurityCode(
field_values[CREDIT_CARD_VERIFICATION_CODE],
field_values[CREDIT_CARD_NUMBER])) {
......@@ -2307,46 +2361,6 @@ bool AutofillDialogControllerImpl::IsManuallyEditingAnySection() const {
return false;
}
bool AutofillDialogControllerImpl::InputIsValid(AutofillFieldType type,
const string16& value) const {
switch (AutofillType::GetEquivalentFieldType(type)) {
case EMAIL_ADDRESS:
return IsValidEmailAddress(value);
case CREDIT_CARD_NUMBER:
return autofill::IsValidCreditCardNumber(value);
case CREDIT_CARD_NAME:
break;
case CREDIT_CARD_EXP_MONTH:
case CREDIT_CARD_EXP_4_DIGIT_YEAR:
break;
case CREDIT_CARD_VERIFICATION_CODE:
return autofill::IsValidCreditCardSecurityCode(value);
case ADDRESS_HOME_LINE1:
break;
case ADDRESS_HOME_LINE2:
return true; // Line 2 is optional - always valid.
case ADDRESS_HOME_CITY:
case ADDRESS_HOME_STATE:
case ADDRESS_HOME_ZIP:
case ADDRESS_HOME_COUNTRY:
break;
case NAME_FULL: // Used for shipping.
break;
case PHONE_HOME_WHOLE_NUMBER: // Used in billing section.
break;
default:
NOTREACHED(); // Trying to validate unknown field.
break;
}
return !value.empty();
}
bool AutofillDialogControllerImpl::AllSectionsAreValid() const {
for (size_t section = SECTION_MIN; section <= SECTION_MAX; ++section) {
if (!SectionIsValid(static_cast<DialogSection>(section)))
......
......@@ -398,10 +398,6 @@ class AutofillDialogControllerImpl : public AutofillDialogController,
// Whether the user has chosen to enter all new data in at least one section.
bool IsManuallyEditingAnySection() const;
// Returns true if the |value| is a valid string for the given autofill field
// type.
bool InputIsValid(AutofillFieldType type, const string16& value) const;
// Whether all of the input fields currently showing in the dialog have valid
// contents.
bool AllSectionsAreValid() const;
......
......@@ -434,8 +434,6 @@ TEST_F(AutofillDialogControllerTest, PhoneNumberValidation) {
// Construct DetailOutputMap from existing data.
SwitchToAutofill();
EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1);
AutofillProfile full_profile(test::GetVerifiedProfile());
controller()->GetTestingManager()->AddTestingProfile(&full_profile);
controller()->EditClickedForSection(SECTION_SHIPPING);
......@@ -503,6 +501,101 @@ TEST_F(AutofillDialogControllerTest, PhoneNumberValidation) {
EXPECT_EQ(1U, validity_data.count(PHONE_HOME_WHOLE_NUMBER));
}
TEST_F(AutofillDialogControllerTest, CardHolderNameValidation) {
// Construct DetailOutputMap from AutofillProfile data.
SwitchToAutofill();
AutofillProfile full_profile(test::GetVerifiedProfile());
controller()->GetTestingManager()->AddTestingProfile(&full_profile);
controller()->EditClickedForSection(SECTION_SHIPPING);
DetailOutputMap outputs;
const DetailInputs& inputs =
controller()->RequestedFieldsForSection(SECTION_CC);
// Input an empty card holder name with VALIDATE_FINAL.
SetOutputValue(inputs, &outputs, CREDIT_CARD_NAME, "");
ValidityData validity_data =
controller()->InputsAreValid(outputs,
AutofillDialogController::VALIDATE_FINAL);
EXPECT_EQ(1U, validity_data.count(CREDIT_CARD_NAME));
// Input an empty card holder name with VALIDATE_EDIT.
validity_data =
controller()->InputsAreValid(outputs,
AutofillDialogController::VALIDATE_EDIT);
EXPECT_EQ(0U, validity_data.count(CREDIT_CARD_NAME));
// Input a non-empty card holder name.
SetOutputValue(inputs, &outputs, CREDIT_CARD_NAME, "Bob");
validity_data =
controller()->InputsAreValid(outputs,
AutofillDialogController::VALIDATE_FINAL);
EXPECT_EQ(0U, validity_data.count(CREDIT_CARD_NAME));
// Switch to Wallet which only considers names with with at least two names to
// be valid.
SwitchToWallet();
// Setup some wallet state.
scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
wallet_items->AddAddress(wallet::GetTestShippingAddress());
wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
controller()->OnDidGetWalletItems(wallet_items.Pass());
controller()->EditClickedForSection(SECTION_CC_BILLING);
DetailOutputMap wallet_outputs;
const DetailInputs& wallet_inputs =
controller()->RequestedFieldsForSection(SECTION_CC_BILLING);
// Input an empty card holder name with VALIDATE_FINAL. Data source should not
// change this behavior.
SetOutputValue(wallet_inputs, &wallet_outputs, CREDIT_CARD_NAME, "");
validity_data =
controller()->InputsAreValid(wallet_outputs,
AutofillDialogController::VALIDATE_FINAL);
EXPECT_EQ(1U, validity_data.count(CREDIT_CARD_NAME));
// Input an empty card holder name with VALIDATE_EDIT. Data source should not
// change this behavior.
validity_data =
controller()->InputsAreValid(wallet_outputs,
AutofillDialogController::VALIDATE_EDIT);
EXPECT_EQ(0U, validity_data.count(CREDIT_CARD_NAME));
// Input a one name card holder name. Wallet does not currently support this.
SetOutputValue(wallet_inputs, &wallet_outputs, CREDIT_CARD_NAME, "Bob");
validity_data =
controller()->InputsAreValid(wallet_outputs,
AutofillDialogController::VALIDATE_FINAL);
EXPECT_EQ(1U, validity_data.count(CREDIT_CARD_NAME));
// Input a two name card holder name.
SetOutputValue(wallet_inputs, &wallet_outputs, CREDIT_CARD_NAME,
"Bob Barker");
validity_data =
controller()->InputsAreValid(wallet_outputs,
AutofillDialogController::VALIDATE_FINAL);
EXPECT_EQ(0U, validity_data.count(CREDIT_CARD_NAME));
// Input a more than two name card holder name.
SetOutputValue(wallet_inputs, &wallet_outputs, CREDIT_CARD_NAME,
"John Jacob Jingleheimer Schmidt");
validity_data =
controller()->InputsAreValid(wallet_outputs,
AutofillDialogController::VALIDATE_FINAL);
EXPECT_EQ(0U, validity_data.count(CREDIT_CARD_NAME));
// Input a card holder name with lots of crazy whitespace.
SetOutputValue(wallet_inputs, &wallet_outputs, CREDIT_CARD_NAME,
" \\n\\r John \\n Jacob Jingleheimer \\t Schmidt ");
validity_data =
controller()->InputsAreValid(wallet_outputs,
AutofillDialogController::VALIDATE_FINAL);
EXPECT_EQ(0U, validity_data.count(CREDIT_CARD_NAME));
}
TEST_F(AutofillDialogControllerTest, AutofillProfiles) {
ui::MenuModel* shipping_model =
controller()->MenuModelForSection(SECTION_SHIPPING);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment