Home | History | Annotate | Download | only in browser
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <vector>
      6 
      7 #include "base/memory/ref_counted.h"
      8 #include "base/prefs/testing_pref_service.h"
      9 #include "base/run_loop.h"
     10 #include "base/strings/string16.h"
     11 #include "base/strings/utf_string_conversions.h"
     12 #include "base/synchronization/waitable_event.h"
     13 #include "chrome/browser/webdata/web_data_service_factory.h"
     14 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
     15 #include "chrome/test/base/testing_profile.h"
     16 #include "components/autofill/core/browser/autocomplete_history_manager.h"
     17 #include "components/autofill/core/browser/autofill_external_delegate.h"
     18 #include "components/autofill/core/browser/autofill_manager.h"
     19 #include "components/autofill/core/browser/test_autofill_driver.h"
     20 #include "components/autofill/core/browser/test_autofill_manager_delegate.h"
     21 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
     22 #include "components/autofill/core/common/form_data.h"
     23 #include "components/webdata/common/web_data_service_test_util.h"
     24 #include "content/public/test/test_browser_thread.h"
     25 #include "content/public/test/test_utils.h"
     26 #include "testing/gmock/include/gmock/gmock.h"
     27 #include "testing/gtest/include/gtest/gtest.h"
     28 #include "ui/gfx/rect.h"
     29 
     30 using content::WebContents;
     31 using testing::_;
     32 
     33 namespace autofill {
     34 
     35 namespace {
     36 
     37 class MockWebDataService : public AutofillWebDataService {
     38  public:
     39   MockWebDataService()
     40       : AutofillWebDataService() {
     41     current_mock_web_data_service_ = this;
     42   }
     43 
     44   MOCK_METHOD1(AddFormFields, void(const std::vector<FormFieldData>&));
     45 
     46   static scoped_refptr<MockWebDataService> GetCurrent() {
     47     if (!current_mock_web_data_service_) {
     48       return new MockWebDataService();
     49     }
     50     return current_mock_web_data_service_;
     51   }
     52 
     53  protected:
     54   virtual ~MockWebDataService() {}
     55 
     56  private:
     57   // Keep track of the most recently created instance, so that it can be
     58   // associated with the current profile when Build() is called.
     59   static MockWebDataService* current_mock_web_data_service_;
     60 };
     61 
     62 MockWebDataService* MockWebDataService::current_mock_web_data_service_ = NULL;
     63 
     64 class MockWebDataServiceWrapperCurrent : public MockWebDataServiceWrapperBase {
     65  public:
     66   static BrowserContextKeyedService* Build(content::BrowserContext* profile) {
     67     return new MockWebDataServiceWrapperCurrent();
     68   }
     69 
     70   MockWebDataServiceWrapperCurrent() {}
     71 
     72   virtual scoped_refptr<AutofillWebDataService> GetAutofillWebData() OVERRIDE {
     73     return MockWebDataService::GetCurrent();
     74   }
     75 
     76  private:
     77   DISALLOW_COPY_AND_ASSIGN(MockWebDataServiceWrapperCurrent);
     78 };
     79 
     80 class MockAutofillManagerDelegate
     81     : public autofill::TestAutofillManagerDelegate {
     82  public:
     83   MockAutofillManagerDelegate() {}
     84   virtual ~MockAutofillManagerDelegate() {}
     85   virtual PrefService* GetPrefs() OVERRIDE { return &prefs_; }
     86 
     87  private:
     88   TestingPrefServiceSimple prefs_;
     89 
     90   DISALLOW_COPY_AND_ASSIGN(MockAutofillManagerDelegate);
     91 };
     92 
     93 }  // namespace
     94 
     95 class AutocompleteHistoryManagerTest : public ChromeRenderViewHostTestHarness {
     96  protected:
     97   virtual void SetUp() OVERRIDE {
     98     ChromeRenderViewHostTestHarness::SetUp();
     99     web_data_service_ = new MockWebDataService();
    100     WebDataServiceFactory::GetInstance()->SetTestingFactory(
    101         profile(), MockWebDataServiceWrapperCurrent::Build);
    102     autofill_driver_.reset(new TestAutofillDriver(web_contents()));
    103     autocomplete_manager_.reset(
    104         new AutocompleteHistoryManager(autofill_driver_.get(),
    105                                        &manager_delegate));
    106   }
    107 
    108   virtual void TearDown() OVERRIDE {
    109     autocomplete_manager_.reset();
    110     web_data_service_ = NULL;
    111     ChromeRenderViewHostTestHarness::TearDown();
    112   }
    113 
    114   scoped_refptr<MockWebDataService> web_data_service_;
    115   scoped_ptr<AutocompleteHistoryManager> autocomplete_manager_;
    116   scoped_ptr<AutofillDriver> autofill_driver_;
    117   MockAutofillManagerDelegate manager_delegate;
    118 };
    119 
    120 // Tests that credit card numbers are not sent to the WebDatabase to be saved.
    121 TEST_F(AutocompleteHistoryManagerTest, CreditCardNumberValue) {
    122   FormData form;
    123   form.name = ASCIIToUTF16("MyForm");
    124   form.method = ASCIIToUTF16("POST");
    125   form.origin = GURL("http://myform.com/form.html");
    126   form.action = GURL("http://myform.com/submit.html");
    127   form.user_submitted = true;
    128 
    129   // Valid Visa credit card number pulled from the paypal help site.
    130   FormFieldData valid_cc;
    131   valid_cc.label = ASCIIToUTF16("Credit Card");
    132   valid_cc.name = ASCIIToUTF16("ccnum");
    133   valid_cc.value = ASCIIToUTF16("4012888888881881");
    134   valid_cc.form_control_type = "text";
    135   form.fields.push_back(valid_cc);
    136 
    137   EXPECT_CALL(*web_data_service_.get(), AddFormFields(_)).Times(0);
    138   autocomplete_manager_->OnFormSubmitted(form);
    139 }
    140 
    141 // Contrary test to AutocompleteHistoryManagerTest.CreditCardNumberValue.  The
    142 // value being submitted is not a valid credit card number, so it will be sent
    143 // to the WebDatabase to be saved.
    144 TEST_F(AutocompleteHistoryManagerTest, NonCreditCardNumberValue) {
    145   FormData form;
    146   form.name = ASCIIToUTF16("MyForm");
    147   form.method = ASCIIToUTF16("POST");
    148   form.origin = GURL("http://myform.com/form.html");
    149   form.action = GURL("http://myform.com/submit.html");
    150   form.user_submitted = true;
    151 
    152   // Invalid credit card number.
    153   FormFieldData invalid_cc;
    154   invalid_cc.label = ASCIIToUTF16("Credit Card");
    155   invalid_cc.name = ASCIIToUTF16("ccnum");
    156   invalid_cc.value = ASCIIToUTF16("4580123456789012");
    157   invalid_cc.form_control_type = "text";
    158   form.fields.push_back(invalid_cc);
    159 
    160   EXPECT_CALL(*(web_data_service_.get()), AddFormFields(_)).Times(1);
    161   autocomplete_manager_->OnFormSubmitted(form);
    162 }
    163 
    164 // Tests that SSNs are not sent to the WebDatabase to be saved.
    165 TEST_F(AutocompleteHistoryManagerTest, SSNValue) {
    166   FormData form;
    167   form.name = ASCIIToUTF16("MyForm");
    168   form.method = ASCIIToUTF16("POST");
    169   form.origin = GURL("http://myform.com/form.html");
    170   form.action = GURL("http://myform.com/submit.html");
    171   form.user_submitted = true;
    172 
    173   FormFieldData ssn;
    174   ssn.label = ASCIIToUTF16("Social Security Number");
    175   ssn.name = ASCIIToUTF16("ssn");
    176   ssn.value = ASCIIToUTF16("078-05-1120");
    177   ssn.form_control_type = "text";
    178   form.fields.push_back(ssn);
    179 
    180   EXPECT_CALL(*web_data_service_.get(), AddFormFields(_)).Times(0);
    181   autocomplete_manager_->OnFormSubmitted(form);
    182 }
    183 
    184 // Verify that autocomplete text is saved for search fields.
    185 TEST_F(AutocompleteHistoryManagerTest, SearchField) {
    186   FormData form;
    187   form.name = ASCIIToUTF16("MyForm");
    188   form.method = ASCIIToUTF16("POST");
    189   form.origin = GURL("http://myform.com/form.html");
    190   form.action = GURL("http://myform.com/submit.html");
    191   form.user_submitted = true;
    192 
    193   // Search field.
    194   FormFieldData search_field;
    195   search_field.label = ASCIIToUTF16("Search");
    196   search_field.name = ASCIIToUTF16("search");
    197   search_field.value = ASCIIToUTF16("my favorite query");
    198   search_field.form_control_type = "search";
    199   form.fields.push_back(search_field);
    200 
    201   EXPECT_CALL(*(web_data_service_.get()), AddFormFields(_)).Times(1);
    202   autocomplete_manager_->OnFormSubmitted(form);
    203 }
    204 
    205 namespace {
    206 
    207 class MockAutofillExternalDelegate : public AutofillExternalDelegate {
    208  public:
    209   MockAutofillExternalDelegate(content::WebContents* web_contents,
    210                                AutofillManager* autofill_manager,
    211                                AutofillDriver* autofill_driver)
    212       : AutofillExternalDelegate(web_contents, autofill_manager,
    213                                  autofill_driver) {}
    214   virtual ~MockAutofillExternalDelegate() {}
    215 
    216   MOCK_METHOD5(OnSuggestionsReturned,
    217                void(int query_id,
    218                     const std::vector<base::string16>& autofill_values,
    219                     const std::vector<base::string16>& autofill_labels,
    220                     const std::vector<base::string16>& autofill_icons,
    221                     const std::vector<int>& autofill_unique_ids));
    222 
    223  private:
    224   DISALLOW_COPY_AND_ASSIGN(MockAutofillExternalDelegate);
    225 };
    226 
    227 class AutocompleteHistoryManagerNoIPC : public AutocompleteHistoryManager {
    228   public:
    229    AutocompleteHistoryManagerNoIPC(AutofillDriver* driver,
    230                                    AutofillManagerDelegate* delegate)
    231        : AutocompleteHistoryManager(driver, delegate) {
    232      // Ensure that IPC is not sent during the test.
    233      set_send_ipc(false);
    234    }
    235 
    236   using AutocompleteHistoryManager::SendSuggestions;
    237 };
    238 
    239 }  // namespace
    240 
    241 // Make sure our external delegate is called at the right time.
    242 TEST_F(AutocompleteHistoryManagerTest, ExternalDelegate) {
    243   AutocompleteHistoryManagerNoIPC autocomplete_history_manager(
    244       autofill_driver_.get(), &manager_delegate);
    245 
    246   scoped_ptr<AutofillManager> autofill_manager(new AutofillManager(
    247       autofill_driver_.get(),
    248       &manager_delegate,
    249       "en-US",
    250       AutofillManager::ENABLE_AUTOFILL_DOWNLOAD_MANAGER));
    251 
    252   MockAutofillExternalDelegate external_delegate(web_contents(),
    253                                                  autofill_manager.get(),
    254                                                  autofill_driver_.get());
    255   autocomplete_history_manager.SetExternalDelegate(&external_delegate);
    256 
    257   // Should trigger a call to OnSuggestionsReturned, verified by the mock.
    258   EXPECT_CALL(external_delegate, OnSuggestionsReturned(_, _, _, _, _));
    259   autocomplete_history_manager.SendSuggestions(NULL);
    260 }
    261 
    262 }  // namespace autofill
    263