1// Copyright 2014 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 "base/macros.h" 6#include "base/memory/ref_counted.h" 7#include "base/message_loop/message_loop.h" 8#include "base/prefs/pref_service.h" 9#include "base/strings/utf_string_conversions.h" 10#include "chrome/browser/autofill/personal_data_manager_factory.h" 11#include "chrome/browser/profiles/profile.h" 12#include "chrome/browser/ui/browser.h" 13#include "chrome/browser/ui/tabs/tab_strip_model.h" 14#include "chrome/test/base/in_process_browser_test.h" 15#include "chrome/test/base/ui_test_utils.h" 16#include "components/autofill/core/browser/autofill_profile.h" 17#include "components/autofill/core/browser/autofill_test_utils.h" 18#include "components/autofill/core/browser/personal_data_manager.h" 19#include "components/autofill/core/browser/personal_data_manager_observer.h" 20#include "components/autofill/core/common/autofill_pref_names.h" 21#include "content/public/test/browser_test_utils.h" 22#include "content/public/test/test_utils.h" 23#include "net/url_request/test_url_fetcher_factory.h" 24#include "testing/gtest/include/gtest/gtest.h" 25 26namespace autofill { 27namespace { 28 29// TODO(isherman): Similar classes are defined in a few other Autofill browser 30// tests. It would be good to factor out the shared code into a helper file. 31class WindowedPersonalDataManagerObserver : public PersonalDataManagerObserver { 32 public: 33 explicit WindowedPersonalDataManagerObserver(Profile* profile) 34 : profile_(profile), 35 message_loop_runner_(new content::MessageLoopRunner){ 36 PersonalDataManagerFactory::GetForProfile(profile_)->AddObserver(this); 37 } 38 virtual ~WindowedPersonalDataManagerObserver() {} 39 40 // Waits for the PersonalDataManager's list of profiles to be updated. 41 void Wait() { 42 message_loop_runner_->Run(); 43 PersonalDataManagerFactory::GetForProfile(profile_)->RemoveObserver(this); 44 } 45 46 // PersonalDataManagerObserver: 47 virtual void OnPersonalDataChanged() OVERRIDE { 48 message_loop_runner_->Quit(); 49 } 50 51 private: 52 Profile* profile_; 53 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; 54}; 55 56class WindowedNetworkObserver : public net::TestURLFetcher::DelegateForTests { 57 public: 58 explicit WindowedNetworkObserver(const std::string& expected_upload_data) 59 : factory_(new net::TestURLFetcherFactory), 60 expected_upload_data_(expected_upload_data), 61 message_loop_runner_(new content::MessageLoopRunner) { 62 factory_->SetDelegateForTests(this); 63 } 64 ~WindowedNetworkObserver() {} 65 66 // Waits for a network request with the |expected_upload_data_|. 67 void Wait() { 68 message_loop_runner_->Run(); 69 factory_.reset(); 70 } 71 72 // net::TestURLFetcher::DelegateForTests: 73 virtual void OnRequestStart(int fetcher_id) OVERRIDE { 74 net::TestURLFetcher* fetcher = factory_->GetFetcherByID(fetcher_id); 75 if (fetcher->upload_data() == expected_upload_data_) 76 message_loop_runner_->Quit(); 77 78 // Not interested in any further status updates from this fetcher. 79 fetcher->SetDelegateForTests(NULL); 80 } 81 virtual void OnChunkUpload(int fetcher_id) OVERRIDE {} 82 virtual void OnRequestEnd(int fetcher_id) OVERRIDE {} 83 84 private: 85 // Mocks out network requests. 86 scoped_ptr<net::TestURLFetcherFactory> factory_; 87 88 const std::string expected_upload_data_; 89 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; 90 91 DISALLOW_COPY_AND_ASSIGN(WindowedNetworkObserver); 92}; 93 94} // namespace 95 96class AutofillServerTest : public InProcessBrowserTest { 97 public: 98 virtual void SetUpOnMainThread() OVERRIDE { 99 // Disable interactions with the Mac Keychain. 100 PrefService* pref_service = browser()->profile()->GetPrefs(); 101 test::DisableSystemServices(pref_service); 102 103 // Enable uploads, and load a new tab to force the AutofillDownloadManager 104 // to update its cached view of the prefs. 105 pref_service->SetDouble(prefs::kAutofillPositiveUploadRate, 1.0); 106 pref_service->SetDouble(prefs::kAutofillNegativeUploadRate, 1.0); 107 AddBlankTabAndShow(browser()); 108 } 109}; 110 111// Regression test for http://crbug.com/177419 112IN_PROC_BROWSER_TEST_F(AutofillServerTest, 113 QueryAndUploadBothIncludeFieldsWithAutocompleteOff) { 114 // Seed some test Autofill profile data, as upload requests are only made when 115 // there is local data available to use as a baseline. 116 WindowedPersonalDataManagerObserver personal_data_observer( 117 browser()->profile()); 118 PersonalDataManagerFactory::GetForProfile(browser()->profile()) 119 ->AddProfile(test::GetFullProfile()); 120 personal_data_observer.Wait(); 121 122 // Load the test page. Expect a query request upon loading the page. 123 const char kDataURIPrefix[] = "data:text/html;charset=utf-8,"; 124 const char kFormHtml[] = 125 "<form id='test_form'>" 126 " <input id='one'>" 127 " <input id='two' autocomplete='off'>" 128 " <input id='three'>" 129 " <input id='four' autocomplete='off'>" 130 " <input type='submit'>" 131 "</form>" 132 "<script>" 133 " document.onclick = function() {" 134 " document.getElementById('test_form').submit();" 135 " };" 136 "</script>"; 137 const char kQueryRequest[] = 138 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" 139 "<autofillquery clientversion=\"6.1.1715.1442/en (GGLL)\">" 140 "<form signature=\"15916856893790176210\">" 141 "<field signature=\"2594484045\"/>" 142 "<field signature=\"2750915947\"/>" 143 "<field signature=\"3494787134\"/>" 144 "<field signature=\"1236501728\"/>" 145 "</form>" 146 "</autofillquery>"; 147 WindowedNetworkObserver query_network_observer(kQueryRequest); 148 ui_test_utils::NavigateToURL( 149 browser(), GURL(std::string(kDataURIPrefix) + kFormHtml)); 150 query_network_observer.Wait(); 151 152 // Submit the form, using a simulated mouse click because form submissions not 153 // triggered by user gestures are ignored. Expect an upload request upon form 154 // submission, with form fields matching those from the query request. 155 const char kUploadRequest[] = 156 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" 157 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\"" 158 " formsignature=\"15916856893790176210\"" 159 " autofillused=\"false\"" 160 " datapresent=\"1f7e0003780000080004\">" 161 "<field signature=\"2594484045\" autofilltype=\"2\"/>" 162 "<field signature=\"2750915947\" autofilltype=\"2\"/>" 163 "<field signature=\"3494787134\" autofilltype=\"2\"/>" 164 "<field signature=\"1236501728\" autofilltype=\"2\"/>" 165 "</autofillupload>"; 166 WindowedNetworkObserver upload_network_observer(kUploadRequest); 167 content::WebContents* web_contents = 168 browser()->tab_strip_model()->GetActiveWebContents(); 169 content::SimulateMouseClick( 170 web_contents, 0, blink::WebMouseEvent::ButtonLeft); 171 upload_network_observer.Wait(); 172} 173 174} // namespace autofill 175