diff options
author | isherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-16 06:19:56 +0000 |
---|---|---|
committer | isherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-16 06:19:56 +0000 |
commit | 1866d061a07ad56c082f439d5f50301944be4170 (patch) | |
tree | 2983cc377e5fe79f41f93fa7354258bee17ec07d /chrome/browser/autofill | |
parent | e41c1da3c9b54efaa715b86aeec81a50ee86bfd4 (diff) | |
download | chromium_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.cc | 63 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_manager.h | 3 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_manager_unittest.cc | 273 | ||||
-rw-r--r-- | chrome/browser/autofill/form_structure.cc | 55 | ||||
-rw-r--r-- | chrome/browser/autofill/form_structure.h | 19 | ||||
-rw-r--r-- | chrome/browser/autofill/form_structure_unittest.cc | 48 |
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()); |