summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autofill
diff options
context:
space:
mode:
authordhollowa@chromium.org <dhollowa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-07 17:33:10 +0000
committerdhollowa@chromium.org <dhollowa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-07 17:33:10 +0000
commit83723f04212bffad8931220b0687d6c6a0030cc5 (patch)
treeb3406b7922651bf83b6b636e3bb186a58c98b558 /chrome/browser/autofill
parent52db5c2886844fe651be3f520938f2520795c724 (diff)
downloadchromium_src-83723f04212bffad8931220b0687d6c6a0030cc5.zip
chromium_src-83723f04212bffad8931220b0687d6c6a0030cc5.tar.gz
chromium_src-83723f04212bffad8931220b0687d6c6a0030cc5.tar.bz2
AutoFill credit card filling when initiated from an address fill.
When user initiates AutoFill for an address we also fill in credit card information from the designated default credit card if one exists. BUG=38320 TEST=PersonalDataManagerTest, manual testing with cc.html (attached). Review URL: http://codereview.chromium.org/1527018 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@43848 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/autofill')
-rw-r--r--chrome/browser/autofill/autofill_manager.cc11
-rw-r--r--chrome/browser/autofill/personal_data_manager.cc53
-rw-r--r--chrome/browser/autofill/personal_data_manager.h8
-rw-r--r--chrome/browser/autofill/personal_data_manager_unittest.cc195
4 files changed, 264 insertions, 3 deletions
diff --git a/chrome/browser/autofill/autofill_manager.cc b/chrome/browser/autofill/autofill_manager.cc
index acb8ed0..8a6d3a7 100644
--- a/chrome/browser/autofill/autofill_manager.cc
+++ b/chrome/browser/autofill/autofill_manager.cc
@@ -264,6 +264,12 @@ bool AutoFillManager::FillAutoFillFormData(int query_id,
credit_card = *iter;
break;
}
+ } else {
+ // If we're filling a profile we can attempt to use the default credit card
+ // for any matching fields.
+ int default_credit_card = personal_data_->DefaultCreditCard();
+ if (default_credit_card != -1)
+ credit_card = credit_cards[default_credit_card];
}
if (!profile && !credit_card)
@@ -283,14 +289,13 @@ bool AutoFillManager::FillAutoFillFormData(int query_id,
for (size_t j = 0; j < result.fields.size(); ++j) {
if (field->name() == result.fields[j].name()) {
AutoFillType autofill_type(field->heuristic_type());
- if (credit_card) {
+ if (credit_card &&
+ autofill_type.group() == AutoFillType::CREDIT_CARD) {
result.fields[j].set_value(
credit_card->GetFieldText(autofill_type));
} else if (profile) {
result.fields[j].set_value(
profile->GetFieldText(autofill_type));
- } else {
- NOTREACHED();
}
break;
}
diff --git a/chrome/browser/autofill/personal_data_manager.cc b/chrome/browser/autofill/personal_data_manager.cc
index 593e47b..a3affd7 100644
--- a/chrome/browser/autofill/personal_data_manager.cc
+++ b/chrome/browser/autofill/personal_data_manager.cc
@@ -8,6 +8,7 @@
#include <iterator>
#include "base/logging.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"
@@ -418,6 +419,58 @@ const std::vector<AutoFillProfile*>& PersonalDataManager::web_profiles() {
return web_profiles_.get();
}
+int PersonalDataManager::DefaultProfile() const {
+ if (web_profiles_.empty())
+ return -1;
+
+ // If no default is explicitly set we default to first element.
+ string16 default_label = WideToUTF16Hack(profile_->GetPrefs()->GetString(
+ prefs::kAutoFillDefaultProfile));
+ if (default_label.empty())
+ return 0;
+
+ std::vector<AutoFillProfile*>::const_iterator iter;
+ size_t i = 0;
+ for (iter = web_profiles_->begin();
+ iter != web_profiles_->end();
+ ++iter, ++i) {
+ if (default_label == (*iter)->Label())
+ break;
+ }
+
+ DCHECK(i < web_profiles_->size());
+ if (i < web_profiles_->size())
+ return i;
+ else
+ return 0;
+}
+
+int PersonalDataManager::DefaultCreditCard() const {
+ if (credit_cards_.empty())
+ return -1;
+
+ // If no default is explicitly set we default to first element.
+ string16 default_label = WideToUTF16Hack(profile_->GetPrefs()->GetString(
+ prefs::kAutoFillDefaultCreditCard));
+ if (default_label.empty())
+ return 0;
+
+ std::vector<CreditCard*>::const_iterator iter;
+ size_t i = 0;
+ for (iter = credit_cards_->begin();
+ iter != credit_cards_->end();
+ ++iter, ++i) {
+ if (default_label == (*iter)->Label())
+ break;
+ }
+
+ DCHECK(i < credit_cards_->size());
+ if (i < credit_cards_->size())
+ return i;
+ else
+ return 0;
+}
+
PersonalDataManager::PersonalDataManager()
: profile_(NULL),
is_initialized_(false),
diff --git a/chrome/browser/autofill/personal_data_manager.h b/chrome/browser/autofill/personal_data_manager.h
index f90440c..fa0eb20 100644
--- a/chrome/browser/autofill/personal_data_manager.h
+++ b/chrome/browser/autofill/personal_data_manager.h
@@ -105,6 +105,14 @@ class PersonalDataManager : public WebDataServiceConsumer,
const std::vector<AutoFillProfile*>& web_profiles();
const std::vector<CreditCard*>& credit_cards() { return credit_cards_.get(); }
+ // Returns the index of the default profile within the vector returned by
+ // |web_profiles()|, or -1 if there are no profiles.
+ int DefaultProfile() const;
+
+ // Returns the index of the default credit card within the vector returned by
+ // |credit_cards()|, or -1 if there are no credit cards.
+ int DefaultCreditCard() const;
+
// Creates a profile labeled |label|, with it's own locally unique ID.
// This must be called on the DB thread with the expectation that the
// returned form will be synchronously persisted to the WebDatabase. See
diff --git a/chrome/browser/autofill/personal_data_manager_unittest.cc b/chrome/browser/autofill/personal_data_manager_unittest.cc
index eaeca7e..ecce104 100644
--- a/chrome/browser/autofill/personal_data_manager_unittest.cc
+++ b/chrome/browser/autofill/personal_data_manager_unittest.cc
@@ -342,3 +342,198 @@ TEST_F(PersonalDataManagerTest, Refresh) {
ASSERT_EQ(1U, results3.size());
EXPECT_EQ(profile0, *results2.at(0));
}
+
+TEST_F(PersonalDataManagerTest, DefaultProfiles) {
+ AutoFillProfile profile0(string16(), 0);
+ autofill_unittest::SetProfileInfo(&profile0,
+ "Billing", "Marion", "Mitchell", "Morrison",
+ "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
+ "91601", "US", "12345678910", "01987654321");
+
+ AutoFillProfile profile1(string16(), 0);
+ autofill_unittest::SetProfileInfo(&profile1,
+ "Home", "Josephine", "Alicia", "Saenz",
+ "joewayne@me.xyz", "Fox", "903 Apple Ct.", NULL, "Orlando", "FL", "32801",
+ "US", "19482937549", "13502849239");
+
+ AutoFillProfile profile2(string16(), 0);
+ autofill_unittest::SetProfileInfo(&profile2,
+ "Work", "Josephine", "Alicia", "Saenz",
+ "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
+ "32801", "US", "19482937549", "13502849239");
+
+ // This will verify that the web database has been loaded and the notification
+ // sent out.
+ EXPECT_CALL(personal_data_observer_,
+ OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop());
+
+ // The message loop will exit when the mock observer is notified.
+ MessageLoop::current()->Run();
+
+ // Check that with no profiles our default profile index is -1.
+ EXPECT_EQ(-1, personal_data_->DefaultProfile());
+
+ // Add the three test profiles to the database.
+ std::vector<AutoFillProfile> update;
+ update.push_back(profile0);
+ update.push_back(profile1);
+ personal_data_->SetProfiles(&update);
+
+ // The PersonalDataManager will update the unique IDs when saving the
+ // profiles, so we have to update the expectations.
+ profile0.set_unique_id(update[0].unique_id());
+ profile1.set_unique_id(update[1].unique_id());
+
+ const std::vector<AutoFillProfile*>& results1 = personal_data_->profiles();
+ ASSERT_EQ(2U, results1.size());
+ EXPECT_EQ(profile0, *results1.at(0));
+ EXPECT_EQ(profile1, *results1.at(1));
+
+ // Three operations in one:
+ // - Update profile0
+ // - Remove profile1
+ // - Add profile2
+ profile0.SetInfo(AutoFillType(NAME_FIRST), ASCIIToUTF16("John"));
+ update.clear();
+ update.push_back(profile0);
+ update.push_back(profile2);
+ personal_data_->SetProfiles(&update);
+
+ // Set the expected unique ID for profile2.
+ profile2.set_unique_id(update[1].unique_id());
+
+ // AutoFillProfile IDs are re-used, so the third profile to be added will have
+ // a unique ID that matches the old unique ID of the removed profile1, even
+ // though that ID has already been used.
+ const std::vector<AutoFillProfile*>& results2 = personal_data_->profiles();
+ ASSERT_EQ(2U, results2.size());
+ EXPECT_EQ(profile0, *results2.at(0));
+ EXPECT_EQ(profile2, *results2.at(1));
+ EXPECT_EQ(profile2.unique_id(), profile1.unique_id());
+
+ // Reset the PersonalDataManager. This tests that the personal data was saved
+ // to the web database, and that we can load the profiles from the web
+ // database.
+ ResetPersonalDataManager();
+
+ // This will verify that the web database has been loaded and the notification
+ // sent out.
+ EXPECT_CALL(personal_data_observer_,
+ OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop());
+
+ // The message loop will exit when the PersonalDataLoadedObserver is notified.
+ MessageLoop::current()->Run();
+
+ // Verify that we've loaded the profiles from the web database.
+ const std::vector<AutoFillProfile*>& results3 = personal_data_->profiles();
+ ASSERT_EQ(2U, results3.size());
+ EXPECT_EQ(profile0, *results3.at(0));
+ EXPECT_EQ(profile2, *results3.at(1));
+
+ // Check that with profiles our default profile index is 0 prior to explicitly
+ // setting a default.
+ EXPECT_EQ(0, personal_data_->DefaultProfile());
+
+ profile_->GetPrefs()->SetString(prefs::kAutoFillDefaultProfile,
+ UTF8ToWide("Work"));
+
+ // Check that with profiles our default profile index is 1 after setting
+ // to label of profile1.
+ EXPECT_EQ(1, personal_data_->DefaultProfile());
+}
+
+TEST_F(PersonalDataManagerTest, DefaultCreditCards) {
+ CreditCard creditcard0(string16(), 0);
+ autofill_unittest::SetCreditCardInfo(&creditcard0,
+ "Corporate", "John Dillinger", "Visa",
+ "123456789012", "01", "2010", "123", "Chicago", "Indianapolis");
+
+ CreditCard creditcard1(string16(), 0);
+ autofill_unittest::SetCreditCardInfo(&creditcard1,
+ "Personal", "Bonnie Parker", "Mastercard",
+ "098765432109", "12", "2012", "987", "Dallas", "");
+
+ CreditCard creditcard2(string16(), 0);
+ autofill_unittest::SetCreditCardInfo(&creditcard2,
+ "Savings", "Clyde Barrow", "American Express",
+ "777666888555", "04", "2015", "445", "Home", "Farm");
+
+ // This will verify that the web database has been loaded and the notification
+ // sent out.
+ EXPECT_CALL(personal_data_observer_,
+ OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop());
+
+ // The message loop will exit when the mock observer is notified.
+ MessageLoop::current()->Run();
+
+ // Check that with no credit cards our default credit card index is -1.
+ EXPECT_EQ(-1, personal_data_->DefaultCreditCard());
+
+ // Add the three test credit cards to the database.
+ std::vector<CreditCard> update;
+ update.push_back(creditcard0);
+ update.push_back(creditcard1);
+ personal_data_->SetCreditCards(&update);
+
+ // The PersonalDataManager will update the unique IDs when saving the
+ // credit cards, so we have to update the expectations.
+ creditcard0.set_unique_id(update[0].unique_id());
+ creditcard1.set_unique_id(update[1].unique_id());
+
+ const std::vector<CreditCard*>& results1 = personal_data_->credit_cards();
+ ASSERT_EQ(2U, results1.size());
+ EXPECT_EQ(creditcard0, *results1.at(0));
+ EXPECT_EQ(creditcard1, *results1.at(1));
+
+ // Three operations in one:
+ // - Update creditcard0
+ // - Remove creditcard1
+ // - Add creditcard2
+ creditcard0.SetInfo(AutoFillType(CREDIT_CARD_NAME), ASCIIToUTF16("Joe"));
+ update.clear();
+ update.push_back(creditcard0);
+ update.push_back(creditcard2);
+ personal_data_->SetCreditCards(&update);
+
+ // Set the expected unique ID for creditcard2.
+ creditcard2.set_unique_id(update[1].unique_id());
+
+ // CreditCard IDs are re-used, so the third credit card to be added will have
+ // a unique ID that matches the old unique ID of the removed creditcard1, even
+ // though that ID has already been used.
+ const std::vector<CreditCard*>& results2 = personal_data_->credit_cards();
+ ASSERT_EQ(2U, results2.size());
+ EXPECT_EQ(creditcard0, *results2.at(0));
+ EXPECT_EQ(creditcard2, *results2.at(1));
+ EXPECT_EQ(creditcard2.unique_id(), creditcard1.unique_id());
+
+ // Reset the PersonalDataManager. This tests that the personal data was saved
+ // to the web database, and that we can load the credit cards from the web
+ // database.
+ ResetPersonalDataManager();
+
+ // This will verify that the web database has been loaded and the notification
+ // sent out.
+ EXPECT_CALL(personal_data_observer_,
+ OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop());
+
+ // The message loop will exit when the PersonalDataLoadedObserver is notified.
+ MessageLoop::current()->Run();
+
+ // Verify that we've loaded the credit cards from the web database.
+ const std::vector<CreditCard*>& results3 = personal_data_->credit_cards();
+ ASSERT_EQ(2U, results3.size());
+ EXPECT_EQ(creditcard0, *results3.at(0));
+ EXPECT_EQ(creditcard2, *results3.at(1));
+
+ // Check that with credit cards our default credit card index is 0 prior to
+ // explicitly setting a default.
+ EXPECT_EQ(0, personal_data_->DefaultCreditCard());
+
+ profile_->GetPrefs()->SetString(prefs::kAutoFillDefaultCreditCard,
+ UTF8ToWide("Savings"));
+
+ // Check that with credit cards our default credit card index is 1 after
+ // setting to label of creditcard1.
+ EXPECT_EQ(1, personal_data_->DefaultCreditCard());
+}