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 <algorithm> 6#include <vector> 7 8#include "base/command_line.h" 9#include "base/memory/scoped_ptr.h" 10#include "base/strings/utf_string_conversions.h" 11#include "components/autofill/content/browser/content_autofill_driver.h" 12#include "components/autofill/content/common/autofill_messages.h" 13#include "components/autofill/core/browser/autofill_external_delegate.h" 14#include "components/autofill/core/browser/autofill_manager.h" 15#include "components/autofill/core/browser/autofill_test_utils.h" 16#include "components/autofill/core/browser/test_autofill_client.h" 17#include "components/autofill/core/common/autofill_switches.h" 18#include "components/autofill/core/common/form_data_predictions.h" 19#include "content/public/browser/browser_context.h" 20#include "content/public/browser/navigation_details.h" 21#include "content/public/browser/web_contents.h" 22#include "content/public/common/frame_navigate_params.h" 23#include "content/public/test/mock_render_process_host.h" 24#include "content/public/test/test_renderer_host.h" 25#include "ipc/ipc_test_sink.h" 26#include "testing/gmock/include/gmock/gmock.h" 27#include "testing/gtest/include/gtest/gtest.h" 28 29namespace autofill { 30 31namespace { 32 33const std::string kAppLocale = "en-US"; 34const AutofillManager::AutofillDownloadManagerState kDownloadState = 35 AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER; 36 37} // namespace 38 39class MockAutofillManager : public AutofillManager { 40 public: 41 MockAutofillManager(AutofillDriver* driver, AutofillClient* client) 42 : AutofillManager(driver, client, kAppLocale, kDownloadState) {} 43 virtual ~MockAutofillManager() {} 44 45 MOCK_METHOD0(Reset, void()); 46}; 47 48class TestContentAutofillDriver : public ContentAutofillDriver { 49 public: 50 TestContentAutofillDriver(content::WebContents* contents, 51 AutofillClient* client) 52 : ContentAutofillDriver(contents, client, kAppLocale, kDownloadState) { 53 scoped_ptr<AutofillManager> autofill_manager( 54 new MockAutofillManager(this, client)); 55 SetAutofillManager(autofill_manager.Pass()); 56 } 57 virtual ~TestContentAutofillDriver() {} 58 59 virtual MockAutofillManager* mock_autofill_manager() { 60 return static_cast<MockAutofillManager*>(autofill_manager()); 61 } 62 63 using ContentAutofillDriver::DidNavigateMainFrame; 64}; 65 66class ContentAutofillDriverTest : public content::RenderViewHostTestHarness { 67 public: 68 virtual void SetUp() OVERRIDE { 69 content::RenderViewHostTestHarness::SetUp(); 70 71 test_autofill_client_.reset(new TestAutofillClient()); 72 driver_.reset(new TestContentAutofillDriver(web_contents(), 73 test_autofill_client_.get())); 74 } 75 76 virtual void TearDown() OVERRIDE { 77 // Reset the driver now to cause all pref observers to be removed and avoid 78 // crashes that otherwise occur in the destructor. 79 driver_.reset(); 80 content::RenderViewHostTestHarness::TearDown(); 81 } 82 83 protected: 84 // Searches for an |AutofillMsg_FillForm| message in the queue of sent IPC 85 // messages. If none is present, returns false. Otherwise, extracts the first 86 // |AutofillMsg_FillForm| message, fills the output parameters with the values 87 // of the message's parameters, and clears the queue of sent messages. 88 bool GetAutofillFillFormMessage(int* page_id, FormData* results) { 89 const uint32 kMsgID = AutofillMsg_FillForm::ID; 90 const IPC::Message* message = 91 process()->sink().GetFirstMessageMatching(kMsgID); 92 if (!message) 93 return false; 94 Tuple2<int, FormData> autofill_param; 95 if (!AutofillMsg_FillForm::Read(message, &autofill_param)) 96 return false; 97 if (page_id) 98 *page_id = autofill_param.a; 99 if (results) 100 *results = autofill_param.b; 101 process()->sink().ClearMessages(); 102 return true; 103 } 104 105 // Searches for an |AutofillMsg_PreviewForm| message in the queue of sent IPC 106 // messages. If none is present, returns false. Otherwise, extracts the first 107 // |AutofillMsg_PreviewForm| message, fills the output parameters with the 108 // values of the message's parameters, and clears the queue of sent messages. 109 bool GetAutofillPreviewFormMessage(int* page_id, FormData* results) { 110 const uint32 kMsgID = AutofillMsg_PreviewForm::ID; 111 const IPC::Message* message = 112 process()->sink().GetFirstMessageMatching(kMsgID); 113 if (!message) 114 return false; 115 Tuple2<int, FormData> autofill_param; 116 if (!AutofillMsg_PreviewForm::Read(message, &autofill_param)) 117 return false; 118 if (page_id) 119 *page_id = autofill_param.a; 120 if (results) 121 *results = autofill_param.b; 122 process()->sink().ClearMessages(); 123 return true; 124 } 125 126 // Searches for an |AutofillMsg_FieldTypePredictionsAvailable| message in the 127 // queue of sent IPC messages. If none is present, returns false. Otherwise, 128 // extracts the first |AutofillMsg_FieldTypePredictionsAvailable| message, 129 // fills the output parameter with the values of the message's parameter, and 130 // clears the queue of sent messages. 131 bool GetFieldTypePredictionsAvailable( 132 std::vector<FormDataPredictions>* predictions) { 133 const uint32 kMsgID = AutofillMsg_FieldTypePredictionsAvailable::ID; 134 const IPC::Message* message = 135 process()->sink().GetFirstMessageMatching(kMsgID); 136 if (!message) 137 return false; 138 Tuple1<std::vector<FormDataPredictions> > autofill_param; 139 if (!AutofillMsg_FieldTypePredictionsAvailable::Read(message, 140 &autofill_param)) 141 return false; 142 if (predictions) 143 *predictions = autofill_param.a; 144 145 process()->sink().ClearMessages(); 146 return true; 147 } 148 149 // Searches for a message matching |messageID| in the queue of sent IPC 150 // messages. If none is present, returns false. Otherwise, extracts the first 151 // matching message, fills the output parameter with the string16 from the 152 // message's parameter, and clears the queue of sent messages. 153 bool GetString16FromMessageWithID(uint32 messageID, base::string16* value) { 154 const IPC::Message* message = 155 process()->sink().GetFirstMessageMatching(messageID); 156 if (!message) 157 return false; 158 Tuple1<base::string16> autofill_param; 159 switch (messageID) { 160 case AutofillMsg_FillFieldWithValue::ID: 161 if (!AutofillMsg_FillFieldWithValue::Read(message, &autofill_param)) 162 return false; 163 break; 164 case AutofillMsg_PreviewFieldWithValue::ID: 165 if (!AutofillMsg_PreviewFieldWithValue::Read(message, &autofill_param)) 166 return false; 167 break; 168 case AutofillMsg_AcceptDataListSuggestion::ID: 169 if (!AutofillMsg_AcceptDataListSuggestion::Read(message, 170 &autofill_param)) 171 return false; 172 break; 173 default: 174 NOTREACHED(); 175 } 176 if (value) 177 *value = autofill_param.a; 178 process()->sink().ClearMessages(); 179 return true; 180 } 181 182 // Searches for a message matching |messageID| in the queue of sent IPC 183 // messages. If none is present, returns false. Otherwise, clears the queue 184 // of sent messages and returns true. 185 bool HasMessageMatchingID(uint32 messageID) { 186 const IPC::Message* message = 187 process()->sink().GetFirstMessageMatching(messageID); 188 if (!message) 189 return false; 190 process()->sink().ClearMessages(); 191 return true; 192 } 193 194 scoped_ptr<TestAutofillClient> test_autofill_client_; 195 scoped_ptr<TestContentAutofillDriver> driver_; 196}; 197 198TEST_F(ContentAutofillDriverTest, GetURLRequestContext) { 199 net::URLRequestContextGetter* request_context = 200 driver_->GetURLRequestContext(); 201 net::URLRequestContextGetter* expected_request_context = 202 web_contents()->GetBrowserContext()->GetRequestContext(); 203 EXPECT_EQ(request_context, expected_request_context); 204} 205 206TEST_F(ContentAutofillDriverTest, NavigatedToDifferentPage) { 207 EXPECT_CALL(*driver_->mock_autofill_manager(), Reset()); 208 content::LoadCommittedDetails details = content::LoadCommittedDetails(); 209 details.is_main_frame = true; 210 details.is_in_page = false; 211 ASSERT_TRUE(details.is_navigation_to_different_page()); 212 content::FrameNavigateParams params = content::FrameNavigateParams(); 213 driver_->DidNavigateMainFrame(details, params); 214} 215 216TEST_F(ContentAutofillDriverTest, NavigatedWithinSamePage) { 217 EXPECT_CALL(*driver_->mock_autofill_manager(), Reset()).Times(0); 218 content::LoadCommittedDetails details = content::LoadCommittedDetails(); 219 details.is_main_frame = false; 220 ASSERT_TRUE(!details.is_navigation_to_different_page()); 221 content::FrameNavigateParams params = content::FrameNavigateParams(); 222 driver_->DidNavigateMainFrame(details, params); 223} 224 225TEST_F(ContentAutofillDriverTest, FormDataSentToRenderer_FillForm) { 226 int input_page_id = 42; 227 FormData input_form_data; 228 test::CreateTestAddressFormData(&input_form_data); 229 driver_->SendFormDataToRenderer( 230 input_page_id, AutofillDriver::FORM_DATA_ACTION_FILL, input_form_data); 231 232 int output_page_id = 0; 233 FormData output_form_data; 234 EXPECT_FALSE( 235 GetAutofillPreviewFormMessage(&output_page_id, &output_form_data)); 236 EXPECT_TRUE(GetAutofillFillFormMessage(&output_page_id, &output_form_data)); 237 EXPECT_EQ(input_page_id, output_page_id); 238 EXPECT_EQ(input_form_data, output_form_data); 239} 240 241TEST_F(ContentAutofillDriverTest, FormDataSentToRenderer_PreviewForm) { 242 int input_page_id = 42; 243 FormData input_form_data; 244 test::CreateTestAddressFormData(&input_form_data); 245 driver_->SendFormDataToRenderer( 246 input_page_id, AutofillDriver::FORM_DATA_ACTION_PREVIEW, input_form_data); 247 248 int output_page_id = 0; 249 FormData output_form_data; 250 EXPECT_FALSE(GetAutofillFillFormMessage(&output_page_id, &output_form_data)); 251 EXPECT_TRUE( 252 GetAutofillPreviewFormMessage(&output_page_id, &output_form_data)); 253 EXPECT_EQ(input_page_id, output_page_id); 254 EXPECT_EQ(input_form_data, output_form_data); 255} 256 257TEST_F(ContentAutofillDriverTest, 258 TypePredictionsNotSentToRendererWhenDisabled) { 259 FormData form; 260 test::CreateTestAddressFormData(&form); 261 FormStructure form_structure(form); 262 std::vector<FormStructure*> forms(1, &form_structure); 263 driver_->SendAutofillTypePredictionsToRenderer(forms); 264 EXPECT_FALSE(GetFieldTypePredictionsAvailable(NULL)); 265} 266 267TEST_F(ContentAutofillDriverTest, TypePredictionsSentToRendererWhenEnabled) { 268 CommandLine::ForCurrentProcess()->AppendSwitch( 269 switches::kShowAutofillTypePredictions); 270 271 FormData form; 272 test::CreateTestAddressFormData(&form); 273 FormStructure form_structure(form); 274 std::vector<FormStructure*> forms(1, &form_structure); 275 std::vector<FormDataPredictions> expected_type_predictions; 276 FormStructure::GetFieldTypePredictions(forms, &expected_type_predictions); 277 driver_->SendAutofillTypePredictionsToRenderer(forms); 278 279 std::vector<FormDataPredictions> output_type_predictions; 280 EXPECT_TRUE(GetFieldTypePredictionsAvailable(&output_type_predictions)); 281 EXPECT_EQ(expected_type_predictions, output_type_predictions); 282} 283 284TEST_F(ContentAutofillDriverTest, AcceptDataListSuggestion) { 285 base::string16 input_value(base::ASCIIToUTF16("barfoo")); 286 base::string16 output_value; 287 driver_->RendererShouldAcceptDataListSuggestion(input_value); 288 EXPECT_TRUE(GetString16FromMessageWithID( 289 AutofillMsg_AcceptDataListSuggestion::ID, &output_value)); 290 EXPECT_EQ(input_value, output_value); 291} 292 293TEST_F(ContentAutofillDriverTest, ClearFilledFormSentToRenderer) { 294 driver_->RendererShouldClearFilledForm(); 295 EXPECT_TRUE(HasMessageMatchingID(AutofillMsg_ClearForm::ID)); 296} 297 298TEST_F(ContentAutofillDriverTest, ClearPreviewedFormSentToRenderer) { 299 driver_->RendererShouldClearPreviewedForm(); 300 EXPECT_TRUE(HasMessageMatchingID(AutofillMsg_ClearPreviewedForm::ID)); 301} 302 303TEST_F(ContentAutofillDriverTest, FillFieldWithValue) { 304 base::string16 input_value(base::ASCIIToUTF16("barqux")); 305 base::string16 output_value; 306 307 driver_->RendererShouldFillFieldWithValue(input_value); 308 EXPECT_TRUE(GetString16FromMessageWithID(AutofillMsg_FillFieldWithValue::ID, 309 &output_value)); 310 EXPECT_EQ(input_value, output_value); 311} 312 313TEST_F(ContentAutofillDriverTest, PreviewFieldWithValue) { 314 base::string16 input_value(base::ASCIIToUTF16("barqux")); 315 base::string16 output_value; 316 driver_->RendererShouldPreviewFieldWithValue(input_value); 317 EXPECT_TRUE(GetString16FromMessageWithID( 318 AutofillMsg_PreviewFieldWithValue::ID, 319 &output_value)); 320 EXPECT_EQ(input_value, output_value); 321} 322 323} // namespace autofill 324