diff options
author | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-20 22:01:17 +0000 |
---|---|---|
committer | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-20 22:01:17 +0000 |
commit | 9c6d006761c3313f7fe81ff304d10a6c02400622 (patch) | |
tree | 238158837a6f8800c5d2a0a2faa9434fffbbd718 /chrome/browser/autofill | |
parent | 58555ce035571ee7d8620dd3e57cc7bf1adfd9b2 (diff) | |
download | chromium_src-9c6d006761c3313f7fe81ff304d10a6c02400622.zip chromium_src-9c6d006761c3313f7fe81ff304d10a6c02400622.tar.gz chromium_src-9c6d006761c3313f7fe81ff304d10a6c02400622.tar.bz2 |
AutoFill: Segregate profile and credit card filling.
* Refactor suggestions filling into Get[Profile,CreditCard]Suggestions.
* Don't fill the default credit card when the AutoFill shortcut is initiated.
* Don't fill the default credit card when filling the profile.
BUG=41334
TEST=none
Review URL: http://codereview.chromium.org/1619029
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45087 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/autofill')
-rw-r--r-- | chrome/browser/autofill/autofill_manager.cc | 158 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_manager.h | 44 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_manager_unittest.cc | 330 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_profile.cc | 19 | ||||
-rw-r--r-- | chrome/browser/autofill/form_structure.cc | 2 | ||||
-rw-r--r-- | chrome/browser/autofill/personal_data_manager.cc | 7 | ||||
-rw-r--r-- | chrome/browser/autofill/personal_data_manager.h | 2 |
7 files changed, 468 insertions, 94 deletions
diff --git a/chrome/browser/autofill/autofill_manager.cc b/chrome/browser/autofill/autofill_manager.cc index e174898..ce06a48 100644 --- a/chrome/browser/autofill/autofill_manager.cc +++ b/chrome/browser/autofill/autofill_manager.cc @@ -41,9 +41,9 @@ AutoFillManager::AutoFillManager(TabContents* tab_contents) infobar_(NULL) { DCHECK(tab_contents); + // |personal_data_| is NULL when using TestTabContents. personal_data_ = tab_contents_->profile()->GetOriginalProfile()->GetPersonalDataManager(); - DCHECK(personal_data_); download_manager_.SetObserver(this); } @@ -122,9 +122,8 @@ bool AutoFillManager::GetAutoFillSuggestions(int query_id, if (!host) return false; - const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles(); - const std::vector<CreditCard*>& credit_cards = personal_data_->credit_cards(); - if (profiles.empty() && credit_cards.empty()) + if (personal_data_->profiles().empty() && + personal_data_->credit_cards().empty()) return false; AutoFillField* form_field = NULL; @@ -154,38 +153,10 @@ bool AutoFillManager::GetAutoFillSuggestions(int query_id, std::vector<string16> values; std::vector<string16> labels; - for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin(); - iter != profiles.end(); ++iter) { - string16 field_text = - (*iter)->GetFieldText(AutoFillType(form_field->type())); - if (!field.value().empty() && - StartsWith(field_text, field.value(), false)) { - string16 value = (*iter)->GetFieldText(AutoFillType(form_field->type())); - string16 label = (*iter)->Label(); - - values.push_back(value); - labels.push_back(label); - } - } - - for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin(); - iter != credit_cards.end(); ++iter) { - string16 field_text = - (*iter)->GetFieldText(AutoFillType(form_field->type())); - if (!field.value().empty() && - StartsWith(field_text, field.value(), false)) { - string16 value; - if (form_field->type() == CREDIT_CARD_NUMBER) { - value = (*iter)->ObfuscatedNumber(); - } else { - value = (*iter)->GetFieldText(AutoFillType(form_field->type())); - } - string16 label = (*iter)->Label(); - - values.push_back(value); - labels.push_back(label); - } - } + if (AutoFillType(form_field->type()).group() != AutoFillType::CREDIT_CARD) + GetProfileSuggestions(field, form_field->type(), &values, &labels); + else + GetCreditCardSuggestions(field, form_field->type(), &values, &labels); // No suggestions. if (values.empty()) @@ -213,7 +184,7 @@ bool AutoFillManager::FillAutoFillFormData(int query_id, if (profiles.empty() && credit_cards.empty()) return false; - // Find profile that matches |name| and |label| in question. + // Find profile that matches the |value| and |label| in question. const AutoFillProfile* profile = NULL; for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin(); iter != profiles.end(); ++iter) { @@ -249,17 +220,14 @@ bool AutoFillManager::FillAutoFillFormData(int query_id, } } } - } 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) return false; + // We fill either the profile or the credit card, not both. + DCHECK((profile && !credit_card) || (!profile && credit_card)); + FormData result = form; for (std::vector<FormStructure*>::const_iterator iter = form_structures_.begin(); @@ -407,6 +375,20 @@ void AutoFillManager::OnHeuristicsRequestError( int http_error) { } +bool AutoFillManager::IsAutoFillEnabled() const { + PrefService* prefs = tab_contents_->profile()->GetPrefs(); + + // Migrate obsolete AutoFill pref. + if (prefs->HasPrefPath(prefs::kFormAutofillEnabled)) { + bool enabled = prefs->GetBoolean(prefs::kFormAutofillEnabled); + prefs->ClearPref(prefs::kFormAutofillEnabled); + prefs->SetBoolean(prefs::kAutoFillEnabled, enabled); + return enabled; + } + + return prefs->GetBoolean(prefs::kAutoFillEnabled); +} + void AutoFillManager::DeterminePossibleFieldTypes( FormStructure* form_structure) { // TODO(jhawkins): Update field text. @@ -441,20 +423,6 @@ void AutoFillManager::UploadFormData() { // form_is_autofilled); } -bool AutoFillManager::IsAutoFillEnabled() { - PrefService* prefs = tab_contents_->profile()->GetPrefs(); - - // Migrate obsolete AutoFill pref. - if (prefs->HasPrefPath(prefs::kFormAutofillEnabled)) { - bool enabled = prefs->GetBoolean(prefs::kFormAutofillEnabled); - prefs->ClearPref(prefs::kFormAutofillEnabled); - prefs->SetBoolean(prefs::kAutoFillEnabled, enabled); - return enabled; - } - - return prefs->GetBoolean(prefs::kAutoFillEnabled); -} - void AutoFillManager::FillDefaultProfile() { if (!IsAutoFillEnabled()) return; @@ -465,8 +433,7 @@ void AutoFillManager::FillDefaultProfile() { // TODO(jhawkins): Do we need to wait for the profiles to be loaded? const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles(); - const std::vector<CreditCard*>& credit_cards = personal_data_->credit_cards(); - if (profiles.empty() && credit_cards.empty()) + if (profiles.empty()) return; AutoFillProfile* profile = NULL; @@ -474,13 +441,8 @@ void AutoFillManager::FillDefaultProfile() { if (default_profile != -1) profile = profiles[default_profile]; - CreditCard* credit_card = NULL; - int default_credit_card = personal_data_->DefaultCreditCard(); - if (default_credit_card != -1) - credit_card = credit_cards[default_credit_card]; - - // We'll have either one or the other at this point. - DCHECK(profile || credit_card); + // If we have any profiles, at least one of them must be the default. + DCHECK(profile); std::vector<FormData> forms; for (std::vector<FormStructure*>::const_iterator iter = @@ -497,13 +459,13 @@ void AutoFillManager::FillDefaultProfile() { for (size_t i = 0; i < form_structure->field_count(); ++i) { const AutoFillField* field = form_structure->field(i); - AutoFillType type(field->type()); - if (credit_card && type.group() == AutoFillType::CREDIT_CARD) { - form.fields[i].set_value(credit_card->GetFieldText(type)); - } else if (profile) { - form.fields[i].set_value(profile->GetFieldText(type)); - } + + // Don't AutoFill credit card information. + if (type.group() == AutoFillType::CREDIT_CARD) + continue; + + form.fields[i].set_value(profile->GetFieldText(type)); } forms.push_back(form); @@ -518,3 +480,55 @@ AutoFillManager::AutoFillManager() personal_data_(NULL), download_manager_(NULL) { } + +AutoFillManager::AutoFillManager(TabContents* tab_contents, + PersonalDataManager* personal_data) + : tab_contents_(tab_contents), + personal_data_(personal_data), + download_manager_(NULL), // No download manager in tests. + infobar_(NULL) { + DCHECK(tab_contents); +} + +void AutoFillManager::GetProfileSuggestions(const FormField& field, + AutoFillFieldType type, + std::vector<string16>* values, + std::vector<string16>* labels) { + const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles(); + for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin(); + iter != profiles.end(); ++iter) { + AutoFillProfile* profile = *iter; + + // The value of the stored data for this field type in the |profile|. + string16 profile_field_value = profile->GetFieldText(AutoFillType(type)); + + if (StartsWith(profile_field_value, field.value(), false)) { + values->push_back(profile_field_value); + labels->push_back(profile->Label()); + } + } +} + +void AutoFillManager::GetCreditCardSuggestions(const FormField& field, + AutoFillFieldType type, + std::vector<string16>* values, + std::vector<string16>* labels) { + // TODO(jhawkins): Only return suggestions for the credit card number until + // the AutoFill dropdown is redesigned to show a credit card icon. + if (type != CREDIT_CARD_NUMBER) + return; + + const std::vector<CreditCard*>& credit_cards = personal_data_->credit_cards(); + for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin(); + iter != credit_cards.end(); ++iter) { + CreditCard* credit_card = *iter; + + // The value of the stored data for this field type in the |credit_card|. + string16 creditcard_field_value = + credit_card->GetFieldText(AutoFillType(type)); + if (StartsWith(creditcard_field_value, field.value(), false)) { + values->push_back(credit_card->ObfuscatedNumber()); + labels->push_back(credit_card->Label()); + } + } +} diff --git a/chrome/browser/autofill/autofill_manager.h b/chrome/browser/autofill/autofill_manager.h index a8fe529..eb0abe7 100644 --- a/chrome/browser/autofill/autofill_manager.h +++ b/chrome/browser/autofill/autofill_manager.h @@ -15,11 +15,6 @@ #include "chrome/browser/autofill/personal_data_manager.h" #include "chrome/browser/renderer_host/render_view_host_delegate.h" -namespace webkit_glue { -struct FormData; -class FormField; -} // namespace webkit_glue - class AutoFillInfoBarDelegate; class AutoFillProfile; class CreditCard; @@ -27,6 +22,11 @@ class FormStructure; class PrefService; class TabContents; +namespace webkit_glue { +struct FormData; +class FormField; +} // namespace webkit_glue + // TODO(jhawkins): Maybe this should be in a grd file? extern const char* kAutoFillLearnMoreUrl; @@ -81,6 +81,9 @@ class AutoFillManager : public RenderViewHostDelegate::AutoFill, AutoFillDownloadManager::AutoFillRequestType request_type, int http_error); + // Returns the value of the AutoFillEnabled pref. + virtual bool IsAutoFillEnabled() const; + // Uses heuristics and existing personal data to determine the possible field // types. void DeterminePossibleFieldTypes(FormStructure* form_structure); @@ -88,30 +91,43 @@ class AutoFillManager : public RenderViewHostDelegate::AutoFill, // Handles the form data submitted by the user. void HandleSubmit(); - - // Uploads the form data to the autofill server. + // Uploads the form data to the AutoFill server. void UploadFormData(); - // Returns the value of the AutoFillEnabled pref. - bool IsAutoFillEnabled(); - - // Fills all the forms in the page with the default profile. + // Fills all the forms in the page with the default profile. Credit card + // fields are not filled out. // TODO(jhawkins): Do we really want to fill all of the forms on the page? // Check how toolbar handles this case. void FillDefaultProfile(); protected: - // For AutoFillInfoBarDelegateTest. + // For tests. AutoFillManager(); + AutoFillManager(TabContents* tab_contents, + PersonalDataManager* personal_data); private: + // Returns a list of values from the stored profiles that match |type| and the + // value of |field| and returns the labels of the matching profiles. + void GetProfileSuggestions(const webkit_glue::FormField& field, + AutoFillFieldType type, + std::vector<string16>* values, + std::vector<string16>* labels); + + // Returns a list of values from the stored credit cards that match |type| and + // the value of |field| and returns the labels of the matching credit cards. + void GetCreditCardSuggestions(const webkit_glue::FormField& field, + AutoFillFieldType type, + std::vector<string16>* values, + std::vector<string16>* labels); + // The TabContents hosting this AutoFillManager. // Weak reference. // May not be NULL. TabContents* tab_contents_; // The personal data manager, used to save and load personal data to/from the - // web database. + // web database. This is overridden by the AutoFillManagerTest. // Weak reference. // May be NULL. NULL indicates OTR. PersonalDataManager* personal_data_; @@ -125,7 +141,7 @@ class AutoFillManager : public RenderViewHostDelegate::AutoFill, // The form data the user has submitted. scoped_ptr<FormStructure> upload_form_structure_; - // The infobar that asks for permission to store form information. + // The InfoBar that asks for permission to store form information. scoped_ptr<AutoFillInfoBarDelegate> infobar_; DISALLOW_COPY_AND_ASSIGN(AutoFillManager); diff --git a/chrome/browser/autofill/autofill_manager_unittest.cc b/chrome/browser/autofill/autofill_manager_unittest.cc new file mode 100644 index 0000000..91ef6ea --- /dev/null +++ b/chrome/browser/autofill/autofill_manager_unittest.cc @@ -0,0 +1,330 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <vector> + +#include "base/scoped_ptr.h" +#include "base/scoped_vector.h" +#include "base/string16.h" +#include "base/tuple.h" +#include "chrome/browser/autofill/autofill_common_unittest.h" +#include "chrome/browser/autofill/autofill_manager.h" +#include "chrome/browser/autofill/autofill_profile.h" +#include "chrome/browser/autofill/credit_card.h" +#include "chrome/browser/autofill/personal_data_manager.h" +#include "chrome/browser/renderer_host/test/test_render_view_host.h" +#include "chrome/common/ipc_test_sink.h" +#include "chrome/common/render_messages.h" +#include "googleurl/src/gurl.h" +#include "webkit/glue/form_data.h" +#include "webkit/glue/form_field.h" + +using webkit_glue::FormData; + +namespace { + +class TestPersonalDataManager : public PersonalDataManager { + public: + TestPersonalDataManager() { + CreateTestAutoFillProfiles(&web_profiles_); + CreateTestCreditCards(&credit_cards_); + } + + virtual void InitializeIfNeeded() {} + + private: + void CreateTestAutoFillProfiles(ScopedVector<AutoFillProfile>* profiles) { + AutoFillProfile* profile = new AutoFillProfile; + autofill_unittest::SetProfileInfo(profile, "Home", "Elvis", "Aaron", + "Presley", "theking@gmail.com", "RCA", + "3734 Elvis Presley Blvd.", "Apt. 10", + "Memphis", "Tennessee", "38116", "USA", + "12345678901", ""); + profiles->push_back(profile); + profile = new AutoFillProfile; + autofill_unittest::SetProfileInfo(profile, "Work", "Charles", "Hardin", + "Holley", "buddy@gmail.com", "Decca", + "123 Apple St.", "unit 6", "Lubbock", + "Texas", "79401", "USA", "23456789012", + ""); + profiles->push_back(profile); + } + + void CreateTestCreditCards(ScopedVector<CreditCard>* credit_cards) { + CreditCard* credit_card = new CreditCard; + autofill_unittest::SetCreditCardInfo(credit_card, "First", "Elvis Presley", + "Visa", "1234567890123456", "04", + "2012", "456", "", ""); + credit_cards->push_back(credit_card); + credit_card = new CreditCard; + autofill_unittest::SetCreditCardInfo(credit_card, "Second", "Buddy Holly", + "Mastercard", "0987654321098765", "10", + "2014", "678", "", ""); + credit_cards->push_back(credit_card); + } + + DISALLOW_COPY_AND_ASSIGN(TestPersonalDataManager); +}; + +class TestAutoFillManager : public AutoFillManager { + public: + explicit TestAutoFillManager(TabContents* tab_contents) + : AutoFillManager(tab_contents, &test_personal_data_) { + } + + virtual bool IsAutoFillEnabled() const { return true; } + + private: + TestPersonalDataManager test_personal_data_; + + DISALLOW_COPY_AND_ASSIGN(TestAutoFillManager); +}; + +void CreateTestFormField(const char* label, + const char* name, + const char* value, + const char* type, + webkit_glue::FormField* field) { + *field = webkit_glue::FormField(ASCIIToUTF16(label), ASCIIToUTF16(name), + ASCIIToUTF16(value), ASCIIToUTF16(type)); +} + +void CreateTestFormData(FormData* form) { + form->name = ASCIIToUTF16("MyForm"); + form->method = ASCIIToUTF16("POST"); + form->origin = GURL("http://myform.com/form.html"); + form->action = GURL("http://myform.com/submit.html"); + + webkit_glue::FormField field; + CreateTestFormField("First Name", "firstname", "", "text", &field); + form->fields.push_back(field); + CreateTestFormField("Middle Name", "middlename", "", "text", &field); + form->fields.push_back(field); + CreateTestFormField("Last Name", "lastname", "", "text", &field); + form->fields.push_back(field); + CreateTestFormField("Address Line 1", "addr1", "", "text", &field); + form->fields.push_back(field); + CreateTestFormField("Address Line 2", "addr2", "", "text", &field); + form->fields.push_back(field); + CreateTestFormField("City", "city", "", "text", &field); + form->fields.push_back(field); + CreateTestFormField("State", "state", "", "text", &field); + form->fields.push_back(field); + CreateTestFormField("Postal Code", "zipcode", "", "text", &field); + form->fields.push_back(field); + CreateTestFormField("Country", "country", "", "text", &field); + form->fields.push_back(field); + CreateTestFormField("Phone Number", "phonenumber", "", "text", &field); + form->fields.push_back(field); + CreateTestFormField("Email", "email", "", "text", &field); + form->fields.push_back(field); + CreateTestFormField("Name on Card", "nameoncard", "", "text", &field); + form->fields.push_back(field); + CreateTestFormField("Card Number", "cardnumber", "", "text", &field); + form->fields.push_back(field); + CreateTestFormField("Expiration Date", "ccmonth", "", "text", &field); + form->fields.push_back(field); + CreateTestFormField("", "ccyear", "", "text", &field); + form->fields.push_back(field); +} + +class AutoFillManagerTest : public RenderViewHostTestHarness { + public: + AutoFillManagerTest() {} + + virtual void SetUp() { + RenderViewHostTestHarness::SetUp(); + autofill_manager_.reset(new TestAutoFillManager(contents())); + } + + bool GetAutoFillSuggestionsMessage(int *page_id, + std::vector<string16>* values, + std::vector<string16>* labels, + int* default_idx) { + const uint32 kMsgID = ViewMsg_AutoFillSuggestionsReturned::ID; + const IPC::Message* message = + process()->sink().GetFirstMessageMatching(kMsgID); + if (!message) + return false; + Tuple4<int, std::vector<string16>, std::vector<string16>, int> + autofill_param; + ViewMsg_AutoFillSuggestionsReturned::Read(message, &autofill_param); + if (page_id) + *page_id = autofill_param.a; + if (values) + *values = autofill_param.b; + if (labels) + *labels = autofill_param.c; + if (default_idx) + *default_idx = autofill_param.d; + return true; + } + + protected: + scoped_ptr<TestAutoFillManager> autofill_manager_; + + private: + DISALLOW_COPY_AND_ASSIGN(AutoFillManagerTest); +}; + +TEST_F(AutoFillManagerTest, GetProfileSuggestionsEmptyValue) { + FormData form; + CreateTestFormData(&form); + + // Set up our FormStructures. + std::vector<FormData> forms; + forms.push_back(form); + autofill_manager_->FormsSeen(forms); + + // The page ID sent to the AutoFillManager from the RenderView, used to send + // an IPC message back to the renderer. + const int kPageID = 1; + + webkit_glue::FormField field; + CreateTestFormField("First Name", "firstname", "", "text", &field); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, field)); + + // Test that we sent the right message to the renderer. + int page_id = 0; + std::vector<string16> values; + std::vector<string16> labels; + int idx = 0; + EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &idx)); + EXPECT_EQ(kPageID, page_id); + ASSERT_EQ(2U, values.size()); + EXPECT_EQ(ASCIIToUTF16("Elvis"), values[0]); + EXPECT_EQ(ASCIIToUTF16("Charles"), values[1]); + ASSERT_EQ(2U, labels.size()); + EXPECT_EQ(ASCIIToUTF16("Home"), labels[0]); + EXPECT_EQ(ASCIIToUTF16("Work"), labels[1]); + EXPECT_EQ(-1, idx); +} + +TEST_F(AutoFillManagerTest, GetProfileSuggestionsMatchCharacter) { + FormData form; + CreateTestFormData(&form); + + // Set up our FormStructures. + std::vector<FormData> forms; + forms.push_back(form); + autofill_manager_->FormsSeen(forms); + + // The page ID sent to the AutoFillManager from the RenderView, used to send + // an IPC message back to the renderer. + const int kPageID = 1; + + webkit_glue::FormField field; + CreateTestFormField("First Name", "firstname", "E", "text", &field); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, field)); + + // Test that we sent the right message to the renderer. + int page_id = 0; + std::vector<string16> values; + std::vector<string16> labels; + int idx = 0; + EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &idx)); + EXPECT_EQ(kPageID, page_id); + ASSERT_EQ(1U, values.size()); + EXPECT_EQ(ASCIIToUTF16("Elvis"), values[0]); + ASSERT_EQ(1U, labels.size()); + EXPECT_EQ(ASCIIToUTF16("Home"), labels[0]); + EXPECT_EQ(-1, idx); +} + +TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsEmptyValue) { + FormData form; + CreateTestFormData(&form); + + // Set up our FormStructures. + std::vector<FormData> forms; + forms.push_back(form); + autofill_manager_->FormsSeen(forms); + + // The page ID sent to the AutoFillManager from the RenderView, used to send + // an IPC message back to the renderer. + const int kPageID = 1; + + webkit_glue::FormField field; + CreateTestFormField("Card Number", "cardnumber", "", "text", &field); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, field)); + + // Test that we sent the right message to the renderer. + int page_id = 0; + std::vector<string16> values; + std::vector<string16> labels; + int idx = 0; + EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &idx)); + EXPECT_EQ(kPageID, page_id); + ASSERT_EQ(2U, values.size()); + EXPECT_EQ(ASCIIToUTF16("************3456"), values[0]); + EXPECT_EQ(ASCIIToUTF16("************8765"), values[1]); + ASSERT_EQ(2U, labels.size()); + EXPECT_EQ(ASCIIToUTF16("First"), labels[0]); + EXPECT_EQ(ASCIIToUTF16("Second"), labels[1]); + EXPECT_EQ(-1, idx); +} + +TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsMatchCharacter) { + FormData form; + CreateTestFormData(&form); + + // Set up our FormStructures. + std::vector<FormData> forms; + forms.push_back(form); + autofill_manager_->FormsSeen(forms); + + // The page ID sent to the AutoFillManager from the RenderView, used to send + // an IPC message back to the renderer. + const int kPageID = 1; + + webkit_glue::FormField field; + CreateTestFormField("Card Number", "cardnumber", "1", "text", &field); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, field)); + + // Test that we sent the right message to the renderer. + int page_id = 0; + std::vector<string16> values; + std::vector<string16> labels; + int idx = 0; + EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &idx)); + EXPECT_EQ(kPageID, page_id); + ASSERT_EQ(1U, values.size()); + EXPECT_EQ(ASCIIToUTF16("************3456"), values[0]); + ASSERT_EQ(1U, labels.size()); + EXPECT_EQ(ASCIIToUTF16("First"), labels[0]); + EXPECT_EQ(-1, idx); +} + +TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonCCNumber) { + FormData form; + CreateTestFormData(&form); + + // Set up our FormStructures. + std::vector<FormData> forms; + forms.push_back(form); + autofill_manager_->FormsSeen(forms); + + // The page ID sent to the AutoFillManager from the RenderView, used to send + // an IPC message back to the renderer. + const int kPageID = 1; + + webkit_glue::FormField field; + int page_id = 0; + std::vector<string16> values; + std::vector<string16> labels; + int idx = 0; + CreateTestFormField("Name on Card", "nameoncard", "", "text", &field); + EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(kPageID, field)); + EXPECT_FALSE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &idx)); + + CreateTestFormField("Expiration Date", "ccmonth", "", "text", &field); + EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(kPageID, field)); + EXPECT_FALSE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &idx)); + + CreateTestFormField("", "ccyear", "", "text", &field); + EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(kPageID, field)); + EXPECT_FALSE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &idx)); +} + +} // namespace diff --git a/chrome/browser/autofill/autofill_profile.cc b/chrome/browser/autofill/autofill_profile.cc index 6d4fdfd..0224448 100644 --- a/chrome/browser/autofill/autofill_profile.cc +++ b/chrome/browser/autofill/autofill_profile.cc @@ -18,20 +18,29 @@ #include "chrome/browser/autofill/home_phone_number.h" #include "grit/generated_resources.h" +namespace { + +void InitPersonalInfo(FormGroupMap* personal_info) { + (*personal_info)[AutoFillType::CONTACT_INFO] = new ContactInfo(); + (*personal_info)[AutoFillType::PHONE_HOME] = new HomePhoneNumber(); + (*personal_info)[AutoFillType::PHONE_FAX] = new FaxNumber(); + (*personal_info)[AutoFillType::ADDRESS_HOME] = new HomeAddress(); + (*personal_info)[AutoFillType::ADDRESS_BILLING] = new BillingAddress(); +} + +} // namespace + AutoFillProfile::AutoFillProfile(const string16& label, int unique_id) : label_(label), unique_id_(unique_id), use_billing_address_(true) { - personal_info_[AutoFillType::CONTACT_INFO] = new ContactInfo(); - personal_info_[AutoFillType::PHONE_HOME] = new HomePhoneNumber(); - personal_info_[AutoFillType::PHONE_FAX] = new FaxNumber(); - personal_info_[AutoFillType::ADDRESS_HOME] = new HomeAddress(); - personal_info_[AutoFillType::ADDRESS_BILLING] = new BillingAddress(); + InitPersonalInfo(&personal_info_); } AutoFillProfile::AutoFillProfile() : unique_id_(0), use_billing_address_(true) { + InitPersonalInfo(&personal_info_); } AutoFillProfile::AutoFillProfile(const AutoFillProfile& source) diff --git a/chrome/browser/autofill/form_structure.cc b/chrome/browser/autofill/form_structure.cc index 0c28609..febd1b4 100644 --- a/chrome/browser/autofill/form_structure.cc +++ b/chrome/browser/autofill/form_structure.cc @@ -87,7 +87,7 @@ FormStructure::FormStructure(const FormData& form) fields_.push_back(NULL); std::string method = UTF16ToUTF8(form.method); - if (method == kFormMethodPost) { + if (StringToLowerASCII(method) == kFormMethodPost) { method_ = POST; } else { // Either the method is 'get', or we don't know. In this case we default diff --git a/chrome/browser/autofill/personal_data_manager.cc b/chrome/browser/autofill/personal_data_manager.cc index 664bbed..254fd06 100644 --- a/chrome/browser/autofill/personal_data_manager.cc +++ b/chrome/browser/autofill/personal_data_manager.cc @@ -364,7 +364,6 @@ void PersonalDataManager::GetPossibleFieldTypes(const string16& text, InitializeIfNeeded(); string16 clean_info = StringToLowerASCII(CollapseWhitespace(text, false)); - if (clean_info.empty()) { possible_types->insert(EMPTY_TYPE); return; @@ -377,6 +376,7 @@ void PersonalDataManager::GetPossibleFieldTypes(const string16& text, DLOG(ERROR) << "NULL information in profiles list"; continue; } + profile->GetPossibleFieldTypes(clean_info, possible_types); } @@ -387,6 +387,7 @@ void PersonalDataManager::GetPossibleFieldTypes(const string16& text, DLOG(ERROR) << "NULL information in credit cards list"; continue; } + credit_card->GetPossibleFieldTypes(clean_info, possible_types); } @@ -400,6 +401,10 @@ bool PersonalDataManager::HasPassword() { } const std::vector<AutoFillProfile*>& PersonalDataManager::profiles() { + // |profile_| is NULL in AutoFillManagerTest. + if (!profile_) + return web_profiles_.get(); + bool auxiliary_profiles_enabled = profile_->GetPrefs()->GetBoolean( prefs::kAutoFillAuxiliaryProfilesEnabled); if (auxiliary_profiles_enabled) { diff --git a/chrome/browser/autofill/personal_data_manager.h b/chrome/browser/autofill/personal_data_manager.h index 1c161d9..a5903a9 100644 --- a/chrome/browser/autofill/personal_data_manager.h +++ b/chrome/browser/autofill/personal_data_manager.h @@ -156,7 +156,7 @@ class PersonalDataManager : public WebDataServiceConsumer, // Initializes the object if needed. This should be called at the beginning // of all the public functions to make sure that the object has been properly // initialized before use. - void InitializeIfNeeded(); + virtual void InitializeIfNeeded(); // This will create and reserve a new unique ID for a profile. int CreateNextUniqueID(std::set<int>* unique_ids); |