summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autofill
diff options
context:
space:
mode:
authorisherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-16 06:19:56 +0000
committerisherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-16 06:19:56 +0000
commit1866d061a07ad56c082f439d5f50301944be4170 (patch)
tree2983cc377e5fe79f41f93fa7354258bee17ec07d /chrome/browser/autofill
parente41c1da3c9b54efaa715b86aeec81a50ee86bfd4 (diff)
downloadchromium_src-1866d061a07ad56c082f439d5f50301944be4170.zip
chromium_src-1866d061a07ad56c082f439d5f50301944be4170.tar.gz
chromium_src-1866d061a07ad56c082f439d5f50301944be4170.tar.bz2
Display a warning when autofill is disabled for a website.
This depends on a WebKit change being tracked at https://bugs.webkit.org/show_bug.cgi?id=49291 BUG=58509 TEST=unit_tests --gtest_filter=AutoFillManagerTest.*:AutoFillHelperTest.* Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=66214 Review URL: http://codereview.chromium.org/4591001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@66237 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/autofill')
-rw-r--r--chrome/browser/autofill/autofill_manager.cc63
-rw-r--r--chrome/browser/autofill/autofill_manager.h3
-rw-r--r--chrome/browser/autofill/autofill_manager_unittest.cc273
-rw-r--r--chrome/browser/autofill/form_structure.cc55
-rw-r--r--chrome/browser/autofill/form_structure.h19
-rw-r--r--chrome/browser/autofill/form_structure_unittest.cc48
6 files changed, 324 insertions, 137 deletions
diff --git a/chrome/browser/autofill/autofill_manager.cc b/chrome/browser/autofill/autofill_manager.cc
index 6f89173..50b31a0 100644
--- a/chrome/browser/autofill/autofill_manager.cc
+++ b/chrome/browser/autofill/autofill_manager.cc
@@ -7,6 +7,7 @@
#include <limits>
#include <string>
+#include "app/l10n_util.h"
#include "base/basictypes.h"
#include "base/string16.h"
#include "base/utf_string_conversions.h"
@@ -22,6 +23,7 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
+#include "grit/generated_resources.h"
#include "webkit/glue/form_data.h"
#include "webkit/glue/form_field.h"
@@ -132,7 +134,7 @@ void AutoFillManager::FormSubmitted(const FormData& form) {
// Grab a copy of the form data.
upload_form_structure_.reset(new FormStructure(form));
- if (!upload_form_structure_->IsAutoFillable())
+ if (!upload_form_structure_->IsAutoFillable(true))
return;
// Determine the possible field types and upload the form structure to the
@@ -148,8 +150,7 @@ void AutoFillManager::FormsSeen(const std::vector<FormData>& forms) {
ParseForms(forms);
}
-bool AutoFillManager::GetAutoFillSuggestions(int query_id,
- bool field_autofilled,
+bool AutoFillManager::GetAutoFillSuggestions(bool field_autofilled,
const FormField& field) {
if (!IsAutoFillEnabled())
return false;
@@ -172,7 +173,7 @@ bool AutoFillManager::GetAutoFillSuggestions(int query_id,
form = *form_iter;
// Don't send suggestions for forms that aren't auto-fillable.
- if (!form->IsAutoFillable())
+ if (!form->IsAutoFillable(false))
continue;
for (std::vector<AutoFillField*>::const_iterator iter = form->begin();
@@ -214,6 +215,30 @@ bool AutoFillManager::GetAutoFillSuggestions(int query_id,
if (values.empty())
return false;
+ // Don't provide AutoFill suggestions when AutoFill is disabled, but provide a
+ // warning to the user.
+ if (!form->IsAutoFillable(true)) {
+ values.assign(
+ 1, l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED));
+ labels.assign(1, string16());
+ icons.assign(1, string16());
+ unique_ids.assign(1, -1);
+ host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids);
+ return true;
+ }
+
+ // Don't provide credit card suggestions for non-HTTPS pages, but provide a
+ // warning to the user.
+ if (!FormIsHTTPS(form) && type.group() == AutoFillType::CREDIT_CARD) {
+ values.assign(
+ 1, l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION));
+ labels.assign(1, string16());
+ icons.assign(1, string16());
+ unique_ids.assign(1, -1);
+ host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids);
+ return true;
+ }
+
// If the form is auto-filled and the renderer is querying for suggestions,
// then the user is editing the value of a field. In this case, mimick
// autocomplete. In particular, don't display labels, as that information is
@@ -231,8 +256,7 @@ bool AutoFillManager::GetAutoFillSuggestions(int query_id,
}
}
- host->AutoFillSuggestionsReturned(
- query_id, values, labels, icons, unique_ids);
+ host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids);
return true;
}
@@ -525,10 +549,6 @@ void AutoFillManager::GetCreditCardSuggestions(FormStructure* form,
std::vector<string16>* labels,
std::vector<string16>* icons,
std::vector<int>* unique_ids) {
- // Don't return CC suggestions for non-HTTPS pages.
- if (!FormIsHTTPS(form))
- return;
-
for (std::vector<CreditCard*>::const_iterator iter =
personal_data_->credit_cards().begin();
iter != personal_data_->credit_cards().end(); ++iter) {
@@ -599,22 +619,33 @@ void AutoFillManager::FillPhoneNumberField(const AutoFillProfile* profile,
}
}
-void AutoFillManager::ParseForms(
- const std::vector<webkit_glue::FormData>& forms) {
- for (std::vector<FormData>::const_iterator iter =
- forms.begin();
+void AutoFillManager::ParseForms(const std::vector<FormData>& forms) {
+ std::vector<FormStructure *> non_queryable_forms;
+ for (std::vector<FormData>::const_iterator iter = forms.begin();
iter != forms.end(); ++iter) {
scoped_ptr<FormStructure> form_structure(new FormStructure(*iter));
- if (!form_structure->ShouldBeParsed())
+ if (!form_structure->ShouldBeParsed(false))
continue;
DeterminePossibleFieldTypes(form_structure.get());
- form_structures_.push_back(form_structure.release());
+
+ // Set aside forms with method GET so that they are not included in the
+ // query to the server.
+ if (form_structure->ShouldBeParsed(true))
+ form_structures_.push_back(form_structure.release());
+ else
+ non_queryable_forms.push_back(form_structure.release());
}
// If none of the forms were parsed, no use querying the server.
if (!form_structures_.empty() && !disable_download_manager_requests_)
download_manager_.StartQueryRequest(form_structures_);
+
+ for (std::vector<FormStructure *>::const_iterator iter =
+ non_queryable_forms.begin();
+ iter != non_queryable_forms.end(); ++iter) {
+ form_structures_.push_back(*iter);
+ }
}
// When sending IDs (across processes) to the renderer we pack credit card and
diff --git a/chrome/browser/autofill/autofill_manager.h b/chrome/browser/autofill/autofill_manager.h
index b0b87bb..60e1468 100644
--- a/chrome/browser/autofill/autofill_manager.h
+++ b/chrome/browser/autofill/autofill_manager.h
@@ -50,8 +50,7 @@ class AutoFillManager : public RenderViewHostDelegate::AutoFill,
// RenderViewHostDelegate::AutoFill implementation:
virtual void FormSubmitted(const webkit_glue::FormData& form);
virtual void FormsSeen(const std::vector<webkit_glue::FormData>& forms);
- virtual bool GetAutoFillSuggestions(int query_id,
- bool field_autofilled,
+ virtual bool GetAutoFillSuggestions(bool field_autofilled,
const webkit_glue::FormField& field);
virtual bool FillAutoFillFormData(int query_id,
const webkit_glue::FormData& form,
diff --git a/chrome/browser/autofill/autofill_manager_unittest.cc b/chrome/browser/autofill/autofill_manager_unittest.cc
index 264dc80..182148d 100644
--- a/chrome/browser/autofill/autofill_manager_unittest.cc
+++ b/chrome/browser/autofill/autofill_manager_unittest.cc
@@ -4,6 +4,7 @@
#include <vector>
+#include "app/l10n_util.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "base/scoped_vector.h"
@@ -23,6 +24,7 @@
#include "chrome/common/pref_names.h"
#include "chrome/common/render_messages.h"
#include "googleurl/src/gurl.h"
+#include "grit/generated_resources.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/glue/form_data.h"
#include "webkit/glue/form_field.h"
@@ -59,6 +61,14 @@ class TestPersonalDataManager : public PersonalDataManager {
web_profiles_->push_back(profile);
}
+ void ClearAutoFillProfiles() {
+ web_profiles_.reset();
+ }
+
+ void ClearCreditCards() {
+ credit_cards_.reset();
+ }
+
private:
void CreateTestAutoFillProfiles(ScopedVector<AutoFillProfile>* profiles) {
AutoFillProfile* profile = new AutoFillProfile;
@@ -110,7 +120,8 @@ class TestAutoFillManager : public AutoFillManager {
public:
TestAutoFillManager(TabContents* tab_contents,
TestPersonalDataManager* personal_manager)
- : AutoFillManager(tab_contents, NULL) {
+ : AutoFillManager(tab_contents, NULL),
+ autofill_enabled_(true) {
test_personal_data_ = personal_manager;
set_personal_data_manager(personal_manager);
// Download manager requests are disabled for purposes of this unit-test.
@@ -118,7 +129,11 @@ class TestAutoFillManager : public AutoFillManager {
set_disable_download_manager_requests(true);
}
- virtual bool IsAutoFillEnabled() const { return true; }
+ virtual bool IsAutoFillEnabled() const { return autofill_enabled_; }
+
+ void set_autofill_enabled(bool autofill_enabled) {
+ autofill_enabled_ = autofill_enabled;
+ }
AutoFillProfile* GetLabeledProfile(const char* label) {
return test_personal_data_->GetLabeledProfile(label);
@@ -130,6 +145,7 @@ class TestAutoFillManager : public AutoFillManager {
private:
TestPersonalDataManager* test_personal_data_;
+ bool autofill_enabled_;
DISALLOW_COPY_AND_ASSIGN(TestAutoFillManager);
};
@@ -293,11 +309,12 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsEmptyValue) {
webkit_glue::FormField field;
autofill_test::CreateTestFormField(
"First Name", "firstname", "", "text", &field);
- EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field));
+ rvh()->ResetAutoFillState(kPageID);
+ EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field));
// No suggestions provided, so send an empty vector as the results.
// This triggers the combined message send.
- rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>());
+ rvh()->AutocompleteSuggestionsReturned(std::vector<string16>());
// Test that we sent the right message to the renderer.
int page_id = 0;
@@ -338,11 +355,12 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsMatchCharacter) {
webkit_glue::FormField field;
autofill_test::CreateTestFormField(
"First Name", "firstname", "E", "text", &field);
- EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field));
+ rvh()->ResetAutoFillState(kPageID);
+ EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field));
// No suggestions provided, so send an empty vector as the results.
// This triggers the combined message send.
- rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>());
+ rvh()->AutocompleteSuggestionsReturned(std::vector<string16>());
// Test that we sent the right message to the renderer.
int page_id = 0;
@@ -394,8 +412,109 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsUnknownFields) {
autofill_test::CreateTestFormField(
"Username", "username", "", "text", &field);
+ rvh()->ResetAutoFillState(kPageID);
EXPECT_FALSE(
- autofill_manager_->GetAutoFillSuggestions(kPageID, false, field));
+ autofill_manager_->GetAutoFillSuggestions(false, field));
+}
+
+// Test that we return no suggestions when autofill is disabled.
+TEST_F(AutoFillManagerTest, GetProfileSuggestionsAutofillDisabledByUser) {
+ FormData form;
+ CreateTestAddressFormData(&form);
+
+ // Set up our FormStructures.
+ std::vector<FormData> forms;
+ forms.push_back(form);
+ autofill_manager_->FormsSeen(forms);
+
+ // Disable AutoFill.
+ autofill_manager_->set_autofill_enabled(false);
+
+ // 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;
+ autofill_test::CreateTestFormField(
+ "First Name", "firstname", "", "text", &field);
+ rvh()->ResetAutoFillState(kPageID);
+ EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(false, field));
+}
+
+// Test that we return a warning explaining that autofill suggestions are
+// unavailable when the form method is GET rather than POST.
+TEST_F(AutoFillManagerTest, GetProfileSuggestionsMethodGet) {
+ FormData form;
+ CreateTestAddressFormData(&form);
+ form.method = ASCIIToUTF16("GET");
+
+ // 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;
+ autofill_test::CreateTestFormField(
+ "First Name", "firstname", "", "text", &field);
+ rvh()->ResetAutoFillState(kPageID);
+ EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field));
+
+ // No suggestions provided, so send an empty vector as the results.
+ // This triggers the combined message send.
+ rvh()->AutocompleteSuggestionsReturned(std::vector<string16>());
+
+ // Test that we sent the right message to the renderer.
+ int page_id = 0;
+ std::vector<string16> values;
+ std::vector<string16> labels;
+ std::vector<string16> icons;
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
+ &icons));
+ EXPECT_EQ(kPageID, page_id);
+ ASSERT_EQ(1U, values.size());
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED),
+ values[0]);
+ ASSERT_EQ(1U, labels.size());
+ EXPECT_EQ(string16(), labels[0]);
+ ASSERT_EQ(1U, icons.size());
+ EXPECT_EQ(string16(), icons[0]);
+
+ // Now add some Autocomplete suggestions. We should return the autocomplete
+ // suggestions and the warning; these will be culled by the renderer.
+ process()->sink().ClearMessages();
+ const int kPageID2 = 2;
+ rvh()->ResetAutoFillState(kPageID2);
+ EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field));
+
+ std::vector<string16> suggestions;
+ suggestions.push_back(ASCIIToUTF16("Jay"));
+ suggestions.push_back(ASCIIToUTF16("Jason"));
+ rvh()->AutocompleteSuggestionsReturned(suggestions);
+
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
+ &icons));
+ EXPECT_EQ(kPageID2, page_id);
+ ASSERT_EQ(3U, values.size());
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED),
+ values[0]);
+ EXPECT_EQ(ASCIIToUTF16("Jay"), values[1]);
+ EXPECT_EQ(ASCIIToUTF16("Jason"), values[2]);
+ ASSERT_EQ(3U, labels.size());
+ EXPECT_EQ(string16(), labels[0]);
+ EXPECT_EQ(string16(), labels[1]);
+ EXPECT_EQ(string16(), labels[2]);
+ ASSERT_EQ(3U, icons.size());
+ EXPECT_EQ(string16(), icons[0]);
+ EXPECT_EQ(string16(), icons[1]);
+ EXPECT_EQ(string16(), icons[2]);
+
+ // Now clear the test profiles and try again -- we shouldn't return a warning.
+ test_personal_data_->ClearAutoFillProfiles();
+ EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(false, field));
}
// Test that we return all credit card profile suggestions when all form fields
@@ -416,11 +535,12 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsEmptyValue) {
webkit_glue::FormField field;
autofill_test::CreateTestFormField(
"Card Number", "cardnumber", "", "text", &field);
- EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field));
+ rvh()->ResetAutoFillState(kPageID);
+ EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field));
// No suggestions provided, so send an empty vector as the results.
// This triggers the combined message send.
- rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>());
+ rvh()->AutocompleteSuggestionsReturned(std::vector<string16>());
// Test that we sent the right message to the renderer.
int page_id = 0;
@@ -459,11 +579,12 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsMatchCharacter) {
webkit_glue::FormField field;
autofill_test::CreateTestFormField(
"Card Number", "cardnumber", "4", "text", &field);
- EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field));
+ rvh()->ResetAutoFillState(kPageID);
+ EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field));
// No suggestions provided, so send an empty vector as the results.
// This triggers the combined message send.
- rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>());
+ rvh()->AutocompleteSuggestionsReturned(std::vector<string16>());
// Test that we sent the right message to the renderer.
int page_id = 0;
@@ -499,11 +620,12 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonCCNumber) {
webkit_glue::FormField field;
autofill_test::CreateTestFormField(
"Name on Card", "nameoncard", "", "text", &field);
- EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field));
+ rvh()->ResetAutoFillState(kPageID);
+ EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field));
// No suggestions provided, so send an empty vector as the results.
// This triggers the combined message send.
- rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>());
+ rvh()->AutocompleteSuggestionsReturned(std::vector<string16>());
// Test that we sent the right message to the renderer.
int page_id = 0;
@@ -524,8 +646,8 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonCCNumber) {
EXPECT_EQ(ASCIIToUTF16("masterCardCC"), icons[1]);
}
-// Test that we return no credit card profile suggestions when the form is not
-// https.
+// Test that we return a warning explaining that credit card profile suggestions
+// are unavailable when the form is not https.
TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonHTTPS) {
FormData form;
CreateTestCreditCardFormData(&form, false);
@@ -542,8 +664,61 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonHTTPS) {
webkit_glue::FormField field;
autofill_test::CreateTestFormField(
"Card Number", "cardnumber", "", "text", &field);
- EXPECT_FALSE(
- autofill_manager_->GetAutoFillSuggestions(kPageID, false, field));
+ rvh()->ResetAutoFillState(kPageID);
+ EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field));
+
+ // No suggestions provided, so send an empty vector as the results.
+ // This triggers the combined message send.
+ rvh()->AutocompleteSuggestionsReturned(std::vector<string16>());
+
+ // Test that we sent the right message to the renderer.
+ int page_id = 0;
+ std::vector<string16> values;
+ std::vector<string16> labels;
+ std::vector<string16> icons;
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
+ &icons));
+ EXPECT_EQ(kPageID, page_id);
+ ASSERT_EQ(1U, values.size());
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION),
+ values[0]);
+ ASSERT_EQ(1U, labels.size());
+ EXPECT_EQ(string16(), labels[0]);
+ ASSERT_EQ(1U, icons.size());
+ EXPECT_EQ(string16(), icons[0]);
+
+ // Now add some Autocomplete suggestions. We should show the autocomplete
+ // suggestions and the warning.
+ process()->sink().ClearMessages();
+ const int kPageID2 = 2;
+ rvh()->ResetAutoFillState(kPageID2);
+ EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field));
+
+ std::vector<string16> suggestions;
+ suggestions.push_back(ASCIIToUTF16("Jay"));
+ suggestions.push_back(ASCIIToUTF16("Jason"));
+ rvh()->AutocompleteSuggestionsReturned(suggestions);
+
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
+ &icons));
+ EXPECT_EQ(kPageID2, page_id);
+ ASSERT_EQ(3U, values.size());
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION),
+ values[0]);
+ EXPECT_EQ(ASCIIToUTF16("Jay"), values[1]);
+ EXPECT_EQ(ASCIIToUTF16("Jason"), values[2]);
+ ASSERT_EQ(3U, labels.size());
+ EXPECT_EQ(string16(), labels[0]);
+ EXPECT_EQ(string16(), labels[1]);
+ EXPECT_EQ(string16(), labels[2]);
+ ASSERT_EQ(3U, icons.size());
+ EXPECT_EQ(string16(), icons[0]);
+ EXPECT_EQ(string16(), icons[1]);
+ EXPECT_EQ(string16(), icons[2]);
+
+ // Clear the test credit cards and try again -- we shouldn't return a warning.
+ test_personal_data_->ClearCreditCards();
+ EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(false, field));
}
// Test that we return profile and credit card suggestions for combined forms.
@@ -564,11 +739,12 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestions) {
webkit_glue::FormField field;
autofill_test::CreateTestFormField(
"First Name", "firstname", "", "text", &field);
- EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field));
+ rvh()->ResetAutoFillState(kPageID);
+ EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field));
// No suggestions provided, so send an empty vector as the results.
// This triggers the combined message send.
- rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>());
+ rvh()->AutocompleteSuggestionsReturned(std::vector<string16>());
// Test that we sent the right address suggestions to the renderer.
int page_id = 0;
@@ -593,11 +769,12 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestions) {
process()->sink().ClearMessages();
autofill_test::CreateTestFormField(
"Card Number", "cardnumber", "", "text", &field);
- EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field));
+ rvh()->ResetAutoFillState(kPageID);
+ EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field));
// No suggestions provided, so send an empty vector as the results.
// This triggers the combined message send.
- rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>());
+ rvh()->AutocompleteSuggestionsReturned(std::vector<string16>());
// Test that we sent the credit card suggestions to the renderer.
page_id = 0;
@@ -616,7 +793,9 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestions) {
}
// Test that for non-https forms with both address and credit card fields, we
-// only return address suggestions.
+// only return address suggestions. Instead of credit card suggestions, we
+// should return a warning explaining that credit card profile suggestions are
+// unavailable when the form is not https.
TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestionsNonHttps) {
FormData form;
CreateTestAddressFormData(&form);
@@ -634,11 +813,12 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestionsNonHttps) {
webkit_glue::FormField field;
autofill_test::CreateTestFormField(
"First Name", "firstname", "", "text", &field);
- EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field));
+ rvh()->ResetAutoFillState(kPageID);
+ EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field));
// No suggestions provided, so send an empty vector as the results.
// This triggers the combined message send.
- rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>());
+ rvh()->AutocompleteSuggestionsReturned(std::vector<string16>());
// Test that we sent the right address suggestions to the renderer.
int page_id = 0;
@@ -660,10 +840,31 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestionsNonHttps) {
EXPECT_EQ(string16(), icons[0]);
EXPECT_EQ(string16(), icons[1]);
+ process()->sink().ClearMessages();
autofill_test::CreateTestFormField(
"Card Number", "cardnumber", "", "text", &field);
- EXPECT_FALSE(
- autofill_manager_->GetAutoFillSuggestions(kPageID, false, field));
+ rvh()->ResetAutoFillState(kPageID);
+ EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field));
+
+ // No suggestions provided, so send an empty vector as the results.
+ // This triggers the combined message send.
+ rvh()->AutocompleteSuggestionsReturned(std::vector<string16>());
+
+ // Test that we sent the right message to the renderer.
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
+ &icons));
+ EXPECT_EQ(kPageID, page_id);
+ ASSERT_EQ(1U, values.size());
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION),
+ values[0]);
+ ASSERT_EQ(1U, labels.size());
+ EXPECT_EQ(string16(), labels[0]);
+ ASSERT_EQ(1U, icons.size());
+ EXPECT_EQ(string16(), icons[0]);
+
+ // Clear the test credit cards and try again -- we shouldn't return a warning.
+ test_personal_data_->ClearCreditCards();
+ EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(false, field));
}
// Test that we correctly combine autofill and autocomplete suggestions.
@@ -683,14 +884,15 @@ TEST_F(AutoFillManagerTest, GetCombinedAutoFillAndAutocompleteSuggestions) {
webkit_glue::FormField field;
autofill_test::CreateTestFormField(
"First Name", "firstname", "", "text", &field);
- EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field));
+ rvh()->ResetAutoFillState(kPageID);
+ EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field));
// Add some Autocomplete suggestions.
// This triggers the combined message send.
std::vector<string16> suggestions;
suggestions.push_back(ASCIIToUTF16("Jay"));
suggestions.push_back(ASCIIToUTF16("Jason"));
- rvh()->AutocompleteSuggestionsReturned(kPageID, suggestions);
+ rvh()->AutocompleteSuggestionsReturned(suggestions);
// Test that we sent the right message to the renderer.
int page_id = 0;
@@ -735,11 +937,12 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsFieldIsAutoFilled) {
webkit_glue::FormField field;
autofill_test::CreateTestFormField(
"First Name", "firstname", "", "text", &field);
- EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, true, field));
+ rvh()->ResetAutoFillState(kPageID);
+ EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(true, field));
// No suggestions provided, so send an empty vector as the results.
// This triggers the combined message send.
- rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>());
+ rvh()->AutocompleteSuggestionsReturned(std::vector<string16>());
// Test that we sent the right message to the renderer.
int page_id = 0;
@@ -778,14 +981,15 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsForAutocompleteOnly) {
webkit_glue::FormField field;
autofill_test::CreateTestFormField(
"Some Field", "somefield", "", "text", &field);
- EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(kPageID, true, field));
+ rvh()->ResetAutoFillState(kPageID);
+ EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(true, field));
// Add some Autocomplete suggestions.
// This triggers the combined message send.
std::vector<string16> suggestions;
suggestions.push_back(ASCIIToUTF16("one"));
suggestions.push_back(ASCIIToUTF16("two"));
- rvh()->AutocompleteSuggestionsReturned(kPageID, suggestions);
+ rvh()->AutocompleteSuggestionsReturned(suggestions);
// Test that we sent the right message to the renderer.
int page_id = 0;
@@ -830,11 +1034,12 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsWithDuplicateValues) {
webkit_glue::FormField field;
autofill_test::CreateTestFormField(
"First Name", "firstname", "", "text", &field);
- EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, true, field));
+ rvh()->ResetAutoFillState(kPageID);
+ EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(true, field));
// No suggestions provided, so send an empty vector as the results.
// This triggers the combined message send.
- rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>());
+ rvh()->AutocompleteSuggestionsReturned(std::vector<string16>());
// Test that we sent the right message to the renderer.
int page_id = 0;
diff --git a/chrome/browser/autofill/form_structure.cc b/chrome/browser/autofill/form_structure.cc
index 0eab86b..b5b2db7 100644
--- a/chrome/browser/autofill/form_structure.cc
+++ b/chrome/browser/autofill/form_structure.cc
@@ -107,7 +107,7 @@ bool FormStructure::EncodeUploadRequest(bool auto_fill_used,
std::string* encoded_xml) const {
DCHECK(encoded_xml);
encoded_xml->clear();
- bool auto_fillable = IsAutoFillable();
+ bool auto_fillable = IsAutoFillable(false);
DCHECK(auto_fillable); // Caller should've checked for search pages.
if (!auto_fillable)
return false;
@@ -232,8 +232,6 @@ void FormStructure::ParseQueryResponse(const std::string& response_xml,
form->UpdateAutoFillCount();
}
-
- return;
}
std::string FormStructure::FormSignature() const {
@@ -247,11 +245,11 @@ std::string FormStructure::FormSignature() const {
return Hash64Bit(form_string);
}
-bool FormStructure::IsAutoFillable() const {
+bool FormStructure::IsAutoFillable(bool require_method_post) const {
if (autofill_count() < kRequiredFillableFields)
return false;
- return ShouldBeParsed();
+ return ShouldBeParsed(require_method_post);
}
bool FormStructure::HasAutoFillableValues() const {
@@ -268,46 +266,6 @@ bool FormStructure::HasAutoFillableValues() const {
return false;
}
-// TODO(jhawkins): Cache this result.
-bool FormStructure::HasBillingFields() const {
- for (std::vector<AutoFillField*>::const_iterator iter = begin();
- iter != end(); ++iter) {
- if (!*iter)
- return false;
-
- AutoFillField* field = *iter;
- if (!field)
- continue;
-
- AutoFillType type(field->type());
- if (type.group() == AutoFillType::ADDRESS_BILLING ||
- type.group() == AutoFillType::CREDIT_CARD)
- return true;
- }
-
- return false;
-}
-
-// TODO(jhawkins): Cache this result.
-bool FormStructure::HasNonBillingFields() const {
- for (std::vector<AutoFillField*>::const_iterator iter = begin();
- iter != end(); ++iter) {
- if (!*iter)
- return false;
-
- AutoFillField* field = *iter;
- if (!field)
- continue;
-
- AutoFillType type(field->type());
- if (type.group() != AutoFillType::ADDRESS_BILLING &&
- type.group() != AutoFillType::CREDIT_CARD)
- return true;
- }
-
- return false;
-}
-
void FormStructure::UpdateAutoFillCount() {
autofill_count_ = 0;
for (std::vector<AutoFillField*>::const_iterator iter = begin();
@@ -318,7 +276,7 @@ void FormStructure::UpdateAutoFillCount() {
}
}
-bool FormStructure::ShouldBeParsed() const {
+bool FormStructure::ShouldBeParsed(bool require_method_post) const {
if (field_count() < kRequiredFillableFields)
return false;
@@ -328,10 +286,7 @@ bool FormStructure::ShouldBeParsed() const {
if (target_url_.path() == "/search")
return false;
- if (method_ == GET)
- return false;
-
- return true;
+ return !require_method_post || (method_ == POST);
}
void FormStructure::set_possible_types(int index, const FieldTypeSet& types) {
diff --git a/chrome/browser/autofill/form_structure.h b/chrome/browser/autofill/form_structure.h
index 77e106f4..fe4c5da 100644
--- a/chrome/browser/autofill/form_structure.h
+++ b/chrome/browser/autofill/form_structure.h
@@ -61,22 +61,15 @@ class FormStructure {
// the form name, and the form field names in a 64-bit hash.
std::string FormSignature() const;
- // Runs a quick heuristic to rule out pages but obviously not auto-fillable,
- // like google/yahoo/msn search, etc.
- bool IsAutoFillable() const;
+ // Runs a quick heuristic to rule out forms that are obviously not
+ // auto-fillable, like google/yahoo/msn search, etc. The requirement that the
+ // form's method be POST is only applied if |require_method_post| is true.
+ bool IsAutoFillable(bool require_method_post) const;
// Returns true if at least one of the form fields relevant for AutoFill
// is not empty.
bool HasAutoFillableValues() const;
- // Returns true if at least one of the form fields is a billing field, which
- // includes billing address fields and credit card fields.
- bool HasBillingFields() const;
-
- // Returns true if at least one of the form fields is a non-billing field,
- // which includes billing address fields and credit card fields.
- bool HasNonBillingFields() const;
-
// Resets |autofill_count_| and counts the number of auto-fillable fields.
// This is used when we receive server data for form fields. At that time,
// we may have more known fields than just the number of fields we matched
@@ -84,7 +77,9 @@ class FormStructure {
void UpdateAutoFillCount();
// Returns true if this form matches the structural requirements for AutoFill.
- bool ShouldBeParsed() const;
+ // The requirement that the form's method be POST is only applied if
+ // |require_method_post| is true.
+ bool ShouldBeParsed(bool require_method_post) const;
// Sets the possible types for the field at |index|.
void set_possible_types(int index, const FieldTypeSet& types);
diff --git a/chrome/browser/autofill/form_structure_unittest.cc b/chrome/browser/autofill/form_structure_unittest.cc
index b5881d6..8eb03fd 100644
--- a/chrome/browser/autofill/form_structure_unittest.cc
+++ b/chrome/browser/autofill/form_structure_unittest.cc
@@ -199,7 +199,7 @@ TEST(FormStructureTest, IsAutoFillable) {
ASCIIToUTF16("submit"),
0));
form_structure.reset(new FormStructure(form));
- EXPECT_FALSE(form_structure->IsAutoFillable());
+ EXPECT_FALSE(form_structure->IsAutoFillable(true));
// We now have three text fields, but only two auto-fillable fields.
form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("First Name"),
@@ -213,7 +213,7 @@ TEST(FormStructureTest, IsAutoFillable) {
ASCIIToUTF16("text"),
0));
form_structure.reset(new FormStructure(form));
- EXPECT_FALSE(form_structure->IsAutoFillable());
+ EXPECT_FALSE(form_structure->IsAutoFillable(true));
// We now have three auto-fillable fields.
form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Email"),
@@ -222,23 +222,25 @@ TEST(FormStructureTest, IsAutoFillable) {
ASCIIToUTF16("text"),
0));
form_structure.reset(new FormStructure(form));
- EXPECT_TRUE(form_structure->IsAutoFillable());
+ EXPECT_TRUE(form_structure->IsAutoFillable(true));
- // The method must be 'post'.
+ // The method must be 'post', though we can intentionally ignore this
+ // criterion for the sake of providing a helpful warning message to the user.
form.method = ASCIIToUTF16("get");
form_structure.reset(new FormStructure(form));
- EXPECT_FALSE(form_structure->IsAutoFillable());
+ EXPECT_FALSE(form_structure->IsAutoFillable(true));
+ EXPECT_TRUE(form_structure->IsAutoFillable(false));
// The target cannot include http(s)://*/search...
form.method = ASCIIToUTF16("post");
form.action = GURL("http://google.com/search?q=hello");
form_structure.reset(new FormStructure(form));
- EXPECT_FALSE(form_structure->IsAutoFillable());
+ EXPECT_FALSE(form_structure->IsAutoFillable(true));
// But search can be in the URL.
form.action = GURL("http://search.com/?q=hello");
form_structure.reset(new FormStructure(form));
- EXPECT_TRUE(form_structure->IsAutoFillable());
+ EXPECT_TRUE(form_structure->IsAutoFillable(true));
}
TEST(FormStructureTest, HeuristicsContactInfo) {
@@ -292,7 +294,7 @@ TEST(FormStructureTest, HeuristicsContactInfo) {
ASCIIToUTF16("submit"),
0));
form_structure.reset(new FormStructure(form));
- EXPECT_TRUE(form_structure->IsAutoFillable());
+ EXPECT_TRUE(form_structure->IsAutoFillable(true));
// Expect the correct number of fields.
ASSERT_EQ(9U, form_structure->field_count());
@@ -410,7 +412,7 @@ TEST(FormStructureTest, HeuristicsHiddenFields) {
ASCIIToUTF16("submit"),
0));
form_structure.reset(new FormStructure(form));
- EXPECT_TRUE(form_structure->IsAutoFillable());
+ EXPECT_TRUE(form_structure->IsAutoFillable(true));
// Expect the correct number of fields.
ASSERT_EQ(17U, form_structure->field_count());
@@ -503,7 +505,7 @@ TEST(FormStructureTest, HeuristicsSample8) {
ASCIIToUTF16("submit"),
0));
form_structure.reset(new FormStructure(form));
- EXPECT_TRUE(form_structure->IsAutoFillable());
+ EXPECT_TRUE(form_structure->IsAutoFillable(true));
ASSERT_EQ(10U, form_structure->field_count());
ASSERT_EQ(9U, form_structure->autofill_count());
@@ -581,7 +583,7 @@ TEST(FormStructureTest, HeuristicsSample6) {
ASCIIToUTF16("submit"),
0));
form_structure.reset(new FormStructure(form));
- EXPECT_TRUE(form_structure->IsAutoFillable());
+ EXPECT_TRUE(form_structure->IsAutoFillable(true));
ASSERT_EQ(7U, form_structure->field_count());
ASSERT_EQ(6U, form_structure->autofill_count());
@@ -655,7 +657,7 @@ TEST(FormStructureTest, HeuristicsLabelsOnly) {
ASCIIToUTF16("submit"),
0));
form_structure.reset(new FormStructure(form));
- EXPECT_TRUE(form_structure->IsAutoFillable());
+ EXPECT_TRUE(form_structure->IsAutoFillable(true));
ASSERT_EQ(9U, form_structure->field_count());
ASSERT_EQ(8U, form_structure->autofill_count());
@@ -716,7 +718,7 @@ TEST(FormStructureTest, HeuristicsCreditCardInfo) {
ASCIIToUTF16("submit"),
0));
form_structure.reset(new FormStructure(form));
- EXPECT_TRUE(form_structure->IsAutoFillable());
+ EXPECT_TRUE(form_structure->IsAutoFillable(true));
ASSERT_EQ(6U, form_structure->field_count());
ASSERT_EQ(4U, form_structure->autofill_count());
@@ -778,7 +780,7 @@ TEST(FormStructureTest, HeuristicsCreditCardInfoWithUnknownCardField) {
ASCIIToUTF16("submit"),
0));
form_structure.reset(new FormStructure(form));
- EXPECT_TRUE(form_structure->IsAutoFillable());
+ EXPECT_TRUE(form_structure->IsAutoFillable(true));
ASSERT_EQ(7U, form_structure->field_count());
ASSERT_EQ(4U, form_structure->autofill_count());
@@ -829,7 +831,7 @@ TEST(FormStructureTest, ThreeAddressLines) {
ASCIIToUTF16("text"),
0));
form_structure.reset(new FormStructure(form));
- EXPECT_TRUE(form_structure->IsAutoFillable());
+ EXPECT_TRUE(form_structure->IsAutoFillable(true));
ASSERT_EQ(4U, form_structure->field_count());
ASSERT_EQ(3U, form_structure->autofill_count());
@@ -875,7 +877,7 @@ TEST(FormStructureTest, BillingAndShippingAddresses) {
ASCIIToUTF16("text"),
0));
form_structure.reset(new FormStructure(form));
- EXPECT_TRUE(form_structure->IsAutoFillable());
+ EXPECT_TRUE(form_structure->IsAutoFillable(true));
ASSERT_EQ(4U, form_structure->field_count());
ASSERT_EQ(4U, form_structure->autofill_count());
@@ -925,7 +927,7 @@ TEST(FormStructureTest, ThreeAddressLinesExpedia) {
ASCIIToUTF16("text"),
0));
form_structure.reset(new FormStructure(form));
- EXPECT_TRUE(form_structure->IsAutoFillable());
+ EXPECT_TRUE(form_structure->IsAutoFillable(true));
ASSERT_EQ(4U, form_structure->field_count());
ASSERT_EQ(3U, form_structure->autofill_count());
@@ -966,7 +968,7 @@ TEST(FormStructureTest, TwoAddressLinesEbay) {
ASCIIToUTF16("text"),
0));
form_structure.reset(new FormStructure(form));
- EXPECT_TRUE(form_structure->IsAutoFillable());
+ EXPECT_TRUE(form_structure->IsAutoFillable(true));
ASSERT_EQ(3U, form_structure->field_count());
ASSERT_EQ(3U, form_structure->autofill_count());
@@ -1002,7 +1004,7 @@ TEST(FormStructureTest, HeuristicsStateWithProvince) {
ASCIIToUTF16("text"),
0));
form_structure.reset(new FormStructure(form));
- EXPECT_TRUE(form_structure->IsAutoFillable());
+ EXPECT_TRUE(form_structure->IsAutoFillable(true));
ASSERT_EQ(3U, form_structure->field_count());
ASSERT_EQ(3U, form_structure->autofill_count());
@@ -1087,7 +1089,7 @@ TEST(FormStructureTest, HeuristicsWithBilling) {
ASCIIToUTF16("text"),
0));
form_structure.reset(new FormStructure(form));
- EXPECT_TRUE(form_structure->IsAutoFillable());
+ EXPECT_TRUE(form_structure->IsAutoFillable(true));
ASSERT_EQ(11U, form_structure->field_count());
ASSERT_EQ(11U, form_structure->autofill_count());
@@ -1136,7 +1138,7 @@ TEST(FormStructureTest, ThreePartPhoneNumber) {
ASCIIToUTF16("text"),
0));
form_structure.reset(new FormStructure(form));
- EXPECT_TRUE(form_structure->IsAutoFillable());
+ EXPECT_TRUE(form_structure->IsAutoFillable(true));
ASSERT_EQ(4U, form_structure->field_count());
ASSERT_EQ(3U, form_structure->autofill_count());
@@ -1207,7 +1209,7 @@ TEST(FormStructureTest, MatchSpecificInputTypes) {
ASCIIToUTF16("submit"),
0));
form_structure.reset(new FormStructure(form));
- EXPECT_TRUE(form_structure->IsAutoFillable());
+ EXPECT_TRUE(form_structure->IsAutoFillable(true));
// Expect the correct number of fields.
ASSERT_EQ(10U, form_structure->field_count());
@@ -1266,7 +1268,7 @@ TEST(FormStructureTest, HeuristicsInfernoCC) {
ASCIIToUTF16("text"),
0));
form_structure.reset(new FormStructure(form));
- EXPECT_TRUE(form_structure->IsAutoFillable());
+ EXPECT_TRUE(form_structure->IsAutoFillable(true));
// Expect the correct number of fields.
ASSERT_EQ(5U, form_structure->field_count());