summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autofill
diff options
context:
space:
mode:
authorjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-20 22:01:17 +0000
committerjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-20 22:01:17 +0000
commit9c6d006761c3313f7fe81ff304d10a6c02400622 (patch)
tree238158837a6f8800c5d2a0a2faa9434fffbbd718 /chrome/browser/autofill
parent58555ce035571ee7d8620dd3e57cc7bf1adfd9b2 (diff)
downloadchromium_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.cc158
-rw-r--r--chrome/browser/autofill/autofill_manager.h44
-rw-r--r--chrome/browser/autofill/autofill_manager_unittest.cc330
-rw-r--r--chrome/browser/autofill/autofill_profile.cc19
-rw-r--r--chrome/browser/autofill/form_structure.cc2
-rw-r--r--chrome/browser/autofill/personal_data_manager.cc7
-rw-r--r--chrome/browser/autofill/personal_data_manager.h2
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);