diff options
Diffstat (limited to 'chrome/browser/autofill')
-rw-r--r-- | chrome/browser/autofill/autofill_dialog_controller_mac_unittest.mm | 2 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_ie_toolbar_import_win.cc | 9 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_manager.cc | 2 | ||||
-rw-r--r-- | chrome/browser/autofill/credit_card.cc | 25 | ||||
-rw-r--r-- | chrome/browser/autofill/credit_card.h | 6 | ||||
-rw-r--r-- | chrome/browser/autofill/form_group.cc | 10 | ||||
-rw-r--r-- | chrome/browser/autofill/form_group.h | 3 | ||||
-rw-r--r-- | chrome/browser/autofill/personal_data_manager.cc | 18 | ||||
-rw-r--r-- | chrome/browser/autofill/personal_data_manager.h | 3 | ||||
-rw-r--r-- | chrome/browser/autofill/personal_data_manager_unittest.cc | 443 |
10 files changed, 492 insertions, 29 deletions
diff --git a/chrome/browser/autofill/autofill_dialog_controller_mac_unittest.mm b/chrome/browser/autofill/autofill_dialog_controller_mac_unittest.mm index 13aeb4f..71c9ae8 100644 --- a/chrome/browser/autofill/autofill_dialog_controller_mac_unittest.mm +++ b/chrome/browser/autofill/autofill_dialog_controller_mac_unittest.mm @@ -271,7 +271,7 @@ TEST_F(AutoFillDialogControllerTest, CreditCardDataMutation) { ASSERT_TRUE(sheet != nil); AutoFillCreditCardModel* cm = [sheet creditCardModel]; EXPECT_TRUE([[cm nameOnCard] isEqualToString:@"DCH"]); - EXPECT_TRUE([[cm creditCardNumber] isEqualToString:@"1234 5678 9101 1121"]); + EXPECT_TRUE([[cm creditCardNumber] isEqualToString:@"1234567891011121"]); EXPECT_TRUE([[cm expirationMonth] isEqualToString:@"01"]); EXPECT_TRUE([[cm expirationYear] isEqualToString:@"2012"]); diff --git a/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc b/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc index 0165f1c..2350607 100644 --- a/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc +++ b/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc @@ -133,6 +133,9 @@ bool ImportSingleProfile(FormGroup* profile, string16 field_value = ReadAndDecryptValue(key, value_name.c_str()); if (!field_value.empty()) { has_non_empty_fields = true; + if (it->second == CREDIT_CARD_NUMBER) { + field_value = DecryptCCNumber(field_value); + } profile->SetInfo(AutoFillType(it->second), field_value); } } @@ -237,12 +240,6 @@ bool ImportCurrentUserProfiles(std::vector<AutoFillProfile>* profiles, if (ImportSingleProfile(&credit_card, &key, reg_to_field)) { string16 cc_number = credit_card.GetFieldText( AutoFillType(CREDIT_CARD_NUMBER)); - - if (!cc_number.empty()) { - // No additional password, and CC# is not empty, decrypt CC#. - cc_number = DecryptCCNumber(cc_number); - } - credit_card.SetInfo(AutoFillType(CREDIT_CARD_NUMBER), cc_number); if (!cc_number.empty()) credit_cards->push_back(credit_card); } diff --git a/chrome/browser/autofill/autofill_manager.cc b/chrome/browser/autofill/autofill_manager.cc index e5056e2..6f89173 100644 --- a/chrome/browser/autofill/autofill_manager.cc +++ b/chrome/browser/autofill/autofill_manager.cc @@ -409,7 +409,7 @@ void AutoFillManager::HandleSubmit() { // require querying the FormManager for updated field values. std::vector<FormStructure*> import; import.push_back(upload_form_structure_.get()); - if (!personal_data_->ImportFormData(import, this)) + if (!personal_data_->ImportFormData(import)) return; // Did we get credit card info? diff --git a/chrome/browser/autofill/credit_card.cc b/chrome/browser/autofill/credit_card.cc index b4e92b8..b85e538 100644 --- a/chrome/browser/autofill/credit_card.cc +++ b/chrome/browser/autofill/credit_card.cc @@ -19,7 +19,6 @@ namespace { -const string16::value_type kCreditCardSeparators[] = {' ','-',0}; const char* kCreditCardObfuscationString = "************"; const AutoFillFieldType kAutoFillCreditCardTypes[] = { @@ -124,6 +123,16 @@ std::string GetCreditCardType(const string16& number) { return kGenericCard; } +// Return a version of |number| that has had any non-digit values removed. +const string16 RemoveNonAsciiDigits(const string16& number) { + string16 stripped; + for (size_t i = 0; i < number.size(); ++i) { + if (IsAsciiDigit(number[i])) + stripped.append(1, number[i]); + } + return stripped; +} + } // namespace CreditCard::CreditCard(const std::string& guid) @@ -291,6 +300,10 @@ void CreditCard::SetInfo(const AutoFillType& type, const string16& value) { SetExpirationMonthFromString(value); break; + case CREDIT_CARD_EXP_2_DIGIT_YEAR: + // This is a read-only attribute. + break; + case CREDIT_CARD_EXP_4_DIGIT_YEAR: SetExpirationYearFromString(value); break; @@ -404,8 +417,10 @@ bool CreditCard::operator!=(const CreditCard& credit_card) const { // Use the Luhn formula to validate the number. // static bool CreditCard::IsCreditCardNumber(const string16& text) { - string16 number; - RemoveChars(text, kCreditCardSeparators, &number); + string16 number = RemoveNonAsciiDigits(text); + + if (number.empty()) + return false; int sum = 0; bool odd = false; @@ -476,6 +491,10 @@ void CreditCard::SetExpirationYearFromString(const string16& text) { set_expiration_year(year); } +void CreditCard::set_number(const string16& number) { + number_ = RemoveNonAsciiDigits(number); +} + void CreditCard::set_expiration_month(int expiration_month) { if (expiration_month < 0 || expiration_month > 12) return; diff --git a/chrome/browser/autofill/credit_card.h b/chrome/browser/autofill/credit_card.h index 91fc6ce..b6fdfde 100644 --- a/chrome/browser/autofill/credit_card.h +++ b/chrome/browser/autofill/credit_card.h @@ -70,6 +70,9 @@ class CreditCard : public FormGroup { // Returns true if there are no values (field types) set. bool IsEmpty() const; + // Returns the credit card number. + const string16& number() const { return number_; } + private: // The month and year are zero if not present. int Expiration4DigitYear() const { return expiration_year_; } @@ -84,13 +87,12 @@ class CreditCard : public FormGroup { // Sets |expiration_year_| to the integer conversion of |text|. void SetExpirationYearFromString(const string16& text); - const string16& number() const { return number_; } const string16& name_on_card() const { return name_on_card_; } const string16& last_four_digits() const { return last_four_digits_; } int expiration_month() const { return expiration_month_; } int expiration_year() const { return expiration_year_; } - void set_number(const string16& number) { number_ = number; } + void set_number(const string16& number); void set_name_on_card(const string16& name_on_card) { name_on_card_ = name_on_card; } diff --git a/chrome/browser/autofill/form_group.cc b/chrome/browser/autofill/form_group.cc index 7e91bc3..49beb16 100644 --- a/chrome/browser/autofill/form_group.cc +++ b/chrome/browser/autofill/form_group.cc @@ -76,3 +76,13 @@ void FormGroup::MergeWith(const FormGroup& form_group) { SetInfo(type, form_group.GetFieldText(type)); } } + +void FormGroup::OverwriteWith(const FormGroup& form_group) { + FieldTypeSet a;; + form_group.GetAvailableFieldTypes(&a); + + for (FieldTypeSet::const_iterator iter = a.begin(); iter != a.end(); ++iter) { + AutoFillType type(*iter); + SetInfo(type, form_group.GetFieldText(type)); + } +} diff --git a/chrome/browser/autofill/form_group.h b/chrome/browser/autofill/form_group.h index 5f16276..b1b2243 100644 --- a/chrome/browser/autofill/form_group.h +++ b/chrome/browser/autofill/form_group.h @@ -69,6 +69,9 @@ class FormGroup { // Merges the field data in |form_group| with this FormGroup. void MergeWith(const FormGroup& form_group); + + // Overwrites the field data in |form_group| with this FormGroup. + void OverwriteWith(const FormGroup& form_group); }; #endif // CHROME_BROWSER_AUTOFILL_FORM_GROUP_H_ diff --git a/chrome/browser/autofill/personal_data_manager.cc b/chrome/browser/autofill/personal_data_manager.cc index 1fb398e..4264baf 100644 --- a/chrome/browser/autofill/personal_data_manager.cc +++ b/chrome/browser/autofill/personal_data_manager.cc @@ -10,7 +10,6 @@ #include "base/logging.h" #include "base/string_number_conversions.h" #include "base/utf_string_conversions.h" -#include "chrome/browser/autofill/autofill_manager.h" #include "chrome/browser/autofill/autofill_field.h" #include "chrome/browser/autofill/form_structure.h" #include "chrome/browser/autofill/phone_number.h" @@ -169,8 +168,7 @@ void PersonalDataManager::RemoveObserver( } bool PersonalDataManager::ImportFormData( - const std::vector<FormStructure*>& form_structures, - AutoFillManager* autofill_manager) { + const std::vector<FormStructure*>& form_structures) { // Parse the form and construct a profile based on the information that is // possible to import. int importable_fields = 0; @@ -256,6 +254,13 @@ bool PersonalDataManager::ImportFormData( if (importable_credit_card_fields == 0) imported_credit_card_.reset(); + if (imported_credit_card_.get()) { + if (!CreditCard::IsCreditCardNumber(imported_credit_card_->GetFieldText( + AutoFillType(CREDIT_CARD_NUMBER)))) { + imported_credit_card_.reset(); + } + } + // We always save imported profiles. SaveImportedProfile(); @@ -756,10 +761,13 @@ void PersonalDataManager::SaveImportedCreditCard() { merged = true; } else if ((*iter)->IntersectionOfTypesHasEqualValues( *imported_credit_card_)) { - // |imported_profile| contains all of the data in this profile, plus - // more. + // |imported_profile| contains all of the data in this profile, plus more. merged = true; (*iter)->MergeWith(*imported_credit_card_); + } else if (!imported_credit_card_->number().empty() && + (*iter)->number() == imported_credit_card_->number()) { + merged = true; + (*iter)->OverwriteWith(*imported_credit_card_); } creditcards.push_back(**iter); diff --git a/chrome/browser/autofill/personal_data_manager.h b/chrome/browser/autofill/personal_data_manager.h index d73bc7c..2fd6d8a 100644 --- a/chrome/browser/autofill/personal_data_manager.h +++ b/chrome/browser/autofill/personal_data_manager.h @@ -67,8 +67,7 @@ class PersonalDataManager // field types that contain information in the FormStructures a profile will // be created with all of the information from recognized fields. Returns // whether a profile was created. - bool ImportFormData(const std::vector<FormStructure*>& form_structures, - AutoFillManager* autofill_manager); + bool ImportFormData(const std::vector<FormStructure*>& form_structures); // Gets |imported_profile_| and |imported_credit_card_| and returns their // values in |profile| and |credit_card| parameters respectively. One or diff --git a/chrome/browser/autofill/personal_data_manager_unittest.cc b/chrome/browser/autofill/personal_data_manager_unittest.cc index 2947e08..cf83af9 100644 --- a/chrome/browser/autofill/personal_data_manager_unittest.cc +++ b/chrome/browser/autofill/personal_data_manager_unittest.cc @@ -500,7 +500,7 @@ TEST_F(PersonalDataManagerTest, Refresh) { update.push_back(profile2); personal_data_->SetProfiles(&update); - // And wait for the refresh. + // Wait for the refresh. EXPECT_CALL(personal_data_observer_, OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop()); @@ -526,9 +526,9 @@ TEST_F(PersonalDataManagerTest, ImportFormData) { FormStructure form_structure(form); std::vector<FormStructure*> forms; forms.push_back(&form_structure); - personal_data_->ImportFormData(forms, NULL); + personal_data_->ImportFormData(forms); - // And wait for the refresh. + // Wait for the refresh. EXPECT_CALL(personal_data_observer_, OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop()); @@ -622,9 +622,9 @@ TEST_F(PersonalDataManagerTest, AggregateProfileData) { scoped_ptr<std::vector<FormStructure*> > forms( new std::vector<FormStructure*>); forms->push_back(form_structure.get()); - personal_data_->ImportFormData(*forms, NULL); + personal_data_->ImportFormData(*forms); - // And wait for the refresh. + // Wait for the refresh. EXPECT_CALL(personal_data_observer_, OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop()); @@ -654,9 +654,9 @@ TEST_F(PersonalDataManagerTest, AggregateProfileData) { form_structure.reset(new FormStructure(*form)); forms.reset(new std::vector<FormStructure*>); forms->push_back(form_structure.get()); - personal_data_->ImportFormData(*forms, NULL); + personal_data_->ImportFormData(*forms); - // And wait for the refresh. + // Wait for the refresh. EXPECT_CALL(personal_data_observer_, OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop()); @@ -701,9 +701,9 @@ TEST_F(PersonalDataManagerTest, AggregateProfileData) { form_structure.reset(new FormStructure(*form)); forms.reset(new std::vector<FormStructure*>); forms->push_back(form_structure.get()); - personal_data_->ImportFormData(*forms, NULL); + personal_data_->ImportFormData(*forms); - // And wait for the refresh. + // Wait for the refresh. EXPECT_CALL(personal_data_observer_, OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop()); @@ -724,3 +724,428 @@ TEST_F(PersonalDataManagerTest, AggregateProfileData) { NULL, NULL); EXPECT_EQ(0, expected->Compare(*results3[1])); } + +TEST_F(PersonalDataManagerTest, AggregateTwoDifferentCreditCards) { + FormData form1; + + // Start with a single valid credit card form. + webkit_glue::FormField field; + autofill_test::CreateTestFormField( + "Name on card:", "name_on_card", "Biggie Smalls", "text", &field); + form1.fields.push_back(field); + autofill_test::CreateTestFormField( + "Card Number:", "card_number", "4111-1111-1111-1111", "text", &field); + form1.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Month:", "exp_month", "01", "text", &field); + form1.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Year:", "exp_year", "2011", "text", &field); + form1.fields.push_back(field); + + FormStructure form_structure1(form1); + std::vector<FormStructure*> forms; + forms.push_back(&form_structure1); + personal_data_->ImportFormData(forms); + personal_data_->SaveImportedCreditCard(); + + // Wait for the refresh. + EXPECT_CALL(personal_data_observer_, + OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop()); + + MessageLoop::current()->Run(); + + CreditCard expected; + autofill_test::SetCreditCardInfo(&expected, + "L1", "Biggie Smalls", "4111111111111111", "01", "2011"); + const std::vector<CreditCard*>& results = personal_data_->credit_cards(); + ASSERT_EQ(1U, results.size()); + EXPECT_EQ(0, expected.Compare(*results[0])); + + // Add a second different valid credit card. + FormData form2; + autofill_test::CreateTestFormField( + "Name on card:", "name_on_card", "Jim Johansen", "text", &field); + form2.fields.push_back(field); + autofill_test::CreateTestFormField( + "Card Number:", "card_number", "5500 0000 0000 0004", "text", &field); + form2.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Month:", "exp_month", "02", "text", &field); + form2.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Year:", "exp_year", "2012", "text", &field); + form2.fields.push_back(field); + + FormStructure form_structure2(form2); + forms.clear(); + forms.push_back(&form_structure2); + personal_data_->ImportFormData(forms); + personal_data_->SaveImportedCreditCard(); + + // Wait for the refresh. + EXPECT_CALL(personal_data_observer_, + OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop()); + + MessageLoop::current()->Run(); + + CreditCard expected2; + autofill_test::SetCreditCardInfo(&expected2, + "L2", "Jim Johansen", "5500000000000004", "02", "2012"); + const std::vector<CreditCard*>& results2 = personal_data_->credit_cards(); + ASSERT_EQ(2U, results2.size()); + EXPECT_EQ(0, expected.Compare(*results2[0])); + EXPECT_EQ(0, expected2.Compare(*results2[1])); +} + +TEST_F(PersonalDataManagerTest, AggregateInvalidCreditCard) { + FormData form1; + + // Start with a single valid credit card form. + webkit_glue::FormField field; + autofill_test::CreateTestFormField( + "Name on card:", "name_on_card", "Biggie Smalls", "text", &field); + form1.fields.push_back(field); + autofill_test::CreateTestFormField( + "Card Number:", "card_number", "4111-1111-1111-1111", "text", &field); + form1.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Month:", "exp_month", "01", "text", &field); + form1.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Year:", "exp_year", "2011", "text", &field); + form1.fields.push_back(field); + + FormStructure form_structure1(form1); + std::vector<FormStructure*> forms; + forms.push_back(&form_structure1); + personal_data_->ImportFormData(forms); + personal_data_->SaveImportedCreditCard(); + + // Wait for the refresh. + EXPECT_CALL(personal_data_observer_, + OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop()); + + MessageLoop::current()->Run(); + + CreditCard expected; + autofill_test::SetCreditCardInfo(&expected, + "L1", "Biggie Smalls", "4111111111111111", "01", "2011"); + const std::vector<CreditCard*>& results = personal_data_->credit_cards(); + ASSERT_EQ(1U, results.size()); + EXPECT_EQ(0, expected.Compare(*results[0])); + + // Add a second different invalid credit card. + FormData form2; + autofill_test::CreateTestFormField( + "Name on card:", "name_on_card", "Jim Johansen", "text", &field); + form2.fields.push_back(field); + autofill_test::CreateTestFormField( + "Card Number:", "card_number", "1000000000000000", "text", &field); + form2.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Month:", "exp_month", "02", "text", &field); + form2.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Year:", "exp_year", "2012", "text", &field); + form2.fields.push_back(field); + + FormStructure form_structure2(form2); + forms.clear(); + forms.push_back(&form_structure2); + personal_data_->ImportFormData(forms); + personal_data_->SaveImportedCreditCard(); + + // Note: no refresh here. + + const std::vector<CreditCard*>& results2 = personal_data_->credit_cards(); + ASSERT_EQ(1U, results2.size()); + EXPECT_EQ(0, expected.Compare(*results2[0])); +} + +TEST_F(PersonalDataManagerTest, AggregateSameCreditCardWithConflict) { + FormData form1; + + // Start with a single valid credit card form. + webkit_glue::FormField field; + autofill_test::CreateTestFormField( + "Name on card:", "name_on_card", "Biggie Smalls", "text", &field); + form1.fields.push_back(field); + autofill_test::CreateTestFormField( + "Card Number:", "card_number", "4111-1111-1111-1111", "text", &field); + form1.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Month:", "exp_month", "01", "text", &field); + form1.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Year:", "exp_year", "2011", "text", &field); + form1.fields.push_back(field); + + FormStructure form_structure1(form1); + std::vector<FormStructure*> forms; + forms.push_back(&form_structure1); + personal_data_->ImportFormData(forms); + personal_data_->SaveImportedCreditCard(); + + // Wait for the refresh. + EXPECT_CALL(personal_data_observer_, + OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop()); + + MessageLoop::current()->Run(); + + CreditCard expected; + autofill_test::SetCreditCardInfo(&expected, + "L1", "Biggie Smalls", "4111111111111111", "01", "2011"); + const std::vector<CreditCard*>& results = personal_data_->credit_cards(); + ASSERT_EQ(1U, results.size()); + EXPECT_EQ(0, expected.Compare(*results[0])); + + // Add a second different valid credit card where the year is different but + // the credit card number matches. + FormData form2; + autofill_test::CreateTestFormField( + "Name on card:", "name_on_card", "Biggie Smalls", "text", &field); + form2.fields.push_back(field); + autofill_test::CreateTestFormField( + "Card Number:", "card_number", "4111 1111 1111 1111", "text", &field); + form2.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Month:", "exp_month", "01", "text", &field); + form2.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Year:", "exp_year", "2012", "text", &field); + form2.fields.push_back(field); + + FormStructure form_structure2(form2); + forms.clear(); + forms.push_back(&form_structure2); + personal_data_->ImportFormData(forms); + personal_data_->SaveImportedCreditCard(); + + // Wait for the refresh. + EXPECT_CALL(personal_data_observer_, + OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop()); + + MessageLoop::current()->Run(); + + // Expect that the newer information is saved. In this case the year is + // updated to "2012". + CreditCard expected2; + autofill_test::SetCreditCardInfo(&expected2, + "L1", "Biggie Smalls", "4111111111111111", "01", "2012"); + const std::vector<CreditCard*>& results2 = personal_data_->credit_cards(); + ASSERT_EQ(1U, results2.size()); + EXPECT_EQ(0, expected2.Compare(*results2[0])); +} + +TEST_F(PersonalDataManagerTest, AggregateEmptyCreditCardWithConflict) { + FormData form1; + + // Start with a single valid credit card form. + webkit_glue::FormField field; + autofill_test::CreateTestFormField( + "Name on card:", "name_on_card", "Biggie Smalls", "text", &field); + form1.fields.push_back(field); + autofill_test::CreateTestFormField( + "Card Number:", "card_number", "4111-1111-1111-1111", "text", &field); + form1.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Month:", "exp_month", "01", "text", &field); + form1.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Year:", "exp_year", "2011", "text", &field); + form1.fields.push_back(field); + + FormStructure form_structure1(form1); + std::vector<FormStructure*> forms; + forms.push_back(&form_structure1); + personal_data_->ImportFormData(forms); + personal_data_->SaveImportedCreditCard(); + + // Wait for the refresh. + EXPECT_CALL(personal_data_observer_, + OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop()); + + MessageLoop::current()->Run(); + + CreditCard expected; + autofill_test::SetCreditCardInfo(&expected, + "L1", "Biggie Smalls", "4111111111111111", "01", "2011"); + const std::vector<CreditCard*>& results = personal_data_->credit_cards(); + ASSERT_EQ(1U, results.size()); + EXPECT_EQ(0, expected.Compare(*results[0])); + + // Add a second credit card with no number. + FormData form2; + autofill_test::CreateTestFormField( + "Name on card:", "name_on_card", "Biggie Smalls", "text", &field); + form2.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Month:", "exp_month", "01", "text", &field); + form2.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Year:", "exp_year", "2012", "text", &field); + form2.fields.push_back(field); + + FormStructure form_structure2(form2); + forms.clear(); + forms.push_back(&form_structure2); + personal_data_->ImportFormData(forms); + personal_data_->SaveImportedCreditCard(); + + // Note: no refresh here. + + // No change is expected. + CreditCard expected2; + autofill_test::SetCreditCardInfo(&expected2, + "L1", "Biggie Smalls", "4111111111111111", "01", "2011"); + const std::vector<CreditCard*>& results2 = personal_data_->credit_cards(); + ASSERT_EQ(1U, results2.size()); + EXPECT_EQ(0, expected2.Compare(*results2[0])); +} + +TEST_F(PersonalDataManagerTest, AggregateCreditCardWithMissingInfoInNew) { + FormData form1; + + // Start with a single valid credit card form. + webkit_glue::FormField field; + autofill_test::CreateTestFormField( + "Name on card:", "name_on_card", "Biggie Smalls", "text", &field); + form1.fields.push_back(field); + autofill_test::CreateTestFormField( + "Card Number:", "card_number", "4111-1111-1111-1111", "text", &field); + form1.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Month:", "exp_month", "01", "text", &field); + form1.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Year:", "exp_year", "2011", "text", &field); + form1.fields.push_back(field); + + FormStructure form_structure1(form1); + std::vector<FormStructure*> forms; + forms.push_back(&form_structure1); + personal_data_->ImportFormData(forms); + personal_data_->SaveImportedCreditCard(); + + // Wait for the refresh. + EXPECT_CALL(personal_data_observer_, + OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop()); + + MessageLoop::current()->Run(); + + CreditCard expected; + autofill_test::SetCreditCardInfo(&expected, + "L1", "Biggie Smalls", "4111111111111111", "01", "2011"); + const std::vector<CreditCard*>& results = personal_data_->credit_cards(); + ASSERT_EQ(1U, results.size()); + EXPECT_EQ(0, expected.Compare(*results[0])); + + // Add a second different valid credit card where the name is missing but + // the credit card number matches. + FormData form2; + // Note missing name. + autofill_test::CreateTestFormField( + "Card Number:", "card_number", "4111111111111111", "text", &field); + form2.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Month:", "exp_month", "01", "text", &field); + form2.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Year:", "exp_year", "2011", "text", &field); + form2.fields.push_back(field); + + FormStructure form_structure2(form2); + forms.clear(); + forms.push_back(&form_structure2); + personal_data_->ImportFormData(forms); + personal_data_->SaveImportedCreditCard(); + + // Wait for the refresh. + EXPECT_CALL(personal_data_observer_, + OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop()); + + MessageLoop::current()->Run(); + + // No change is expected. + CreditCard expected2; + autofill_test::SetCreditCardInfo(&expected2, + "L1", "Biggie Smalls", "4111111111111111", "01", "2011"); + const std::vector<CreditCard*>& results2 = personal_data_->credit_cards(); + ASSERT_EQ(1U, results2.size()); + EXPECT_EQ(0, expected2.Compare(*results2[0])); +} + +TEST_F(PersonalDataManagerTest, AggregateCreditCardWithMissingInfoInOld) { + FormData form1; + + // Start with a single valid credit card form. + webkit_glue::FormField field; + // Note missing name. + autofill_test::CreateTestFormField( + "Card Number:", "card_number", "4111-1111-1111-1111", "text", &field); + form1.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Month:", "exp_month", "01", "text", &field); + form1.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Year:", "exp_year", "2011", "text", &field); + form1.fields.push_back(field); + + FormStructure form_structure1(form1); + std::vector<FormStructure*> forms; + forms.push_back(&form_structure1); + personal_data_->ImportFormData(forms); + personal_data_->SaveImportedCreditCard(); + + // Wait for the refresh. + EXPECT_CALL(personal_data_observer_, + OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop()); + + MessageLoop::current()->Run(); + + CreditCard expected; + autofill_test::SetCreditCardInfo(&expected, + "L1", NULL, "4111111111111111", "01", "2011"); + const std::vector<CreditCard*>& results = personal_data_->credit_cards(); + ASSERT_EQ(1U, results.size()); + EXPECT_EQ(0, expected.Compare(*results[0])); + + // Add a second different valid credit card where the year is different but + // the credit card number matches. + FormData form2; + autofill_test::CreateTestFormField( + "Name on card:", "name_on_card", "Biggie Smalls", "text", &field); + form2.fields.push_back(field); + autofill_test::CreateTestFormField( + "Card Number:", "card_number", "4111-1111-1111-1111", "text", &field); + form2.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Month:", "exp_month", "01", "text", &field); + form2.fields.push_back(field); + autofill_test::CreateTestFormField( + "Exp Year:", "exp_year", "2011", "text", &field); + form2.fields.push_back(field); + + FormStructure form_structure2(form2); + forms.clear(); + forms.push_back(&form_structure2); + personal_data_->ImportFormData(forms); + personal_data_->SaveImportedCreditCard(); + + // Wait for the refresh. + EXPECT_CALL(personal_data_observer_, + OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop()); + + MessageLoop::current()->Run(); + + // Expect that the newer information is saved. In this case the year is + // added to the existing credit card. + CreditCard expected2; + autofill_test::SetCreditCardInfo(&expected2, + "L1", "Biggie Smalls", "4111111111111111", "01", "2011"); + const std::vector<CreditCard*>& results2 = personal_data_->credit_cards(); + ASSERT_EQ(1U, results2.size()); + EXPECT_EQ(0, expected2.Compare(*results2[0])); +} + |