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.
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"
33 const std::string kAppLocale
= "en-US";
34 const AutofillManager::AutofillDownloadManagerState kDownloadState
=
35 AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER
;
39 class MockAutofillManager
: public AutofillManager
{
41 MockAutofillManager(AutofillDriver
* driver
, AutofillClient
* client
)
42 : AutofillManager(driver
, client
, kAppLocale
, kDownloadState
) {}
43 virtual ~MockAutofillManager() {}
45 MOCK_METHOD0(Reset
, void());
48 class TestContentAutofillDriver
: public ContentAutofillDriver
{
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());
57 virtual ~TestContentAutofillDriver() {}
59 virtual MockAutofillManager
* mock_autofill_manager() {
60 return static_cast<MockAutofillManager
*>(autofill_manager());
63 using ContentAutofillDriver::DidNavigateMainFrame
;
66 class ContentAutofillDriverTest
: public content::RenderViewHostTestHarness
{
68 virtual void SetUp() OVERRIDE
{
69 content::RenderViewHostTestHarness::SetUp();
71 test_autofill_client_
.reset(new TestAutofillClient());
72 driver_
.reset(new TestContentAutofillDriver(web_contents(),
73 test_autofill_client_
.get()));
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.
80 content::RenderViewHostTestHarness::TearDown();
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
);
94 Tuple2
<int, FormData
> autofill_param
;
95 if (!AutofillMsg_FillForm::Read(message
, &autofill_param
))
98 *page_id
= autofill_param
.a
;
100 *results
= autofill_param
.b
;
101 process()->sink().ClearMessages();
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
);
115 Tuple2
<int, FormData
> autofill_param
;
116 if (!AutofillMsg_PreviewForm::Read(message
, &autofill_param
))
119 *page_id
= autofill_param
.a
;
121 *results
= autofill_param
.b
;
122 process()->sink().ClearMessages();
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
);
138 Tuple1
<std::vector
<FormDataPredictions
> > autofill_param
;
139 if (!AutofillMsg_FieldTypePredictionsAvailable::Read(message
,
143 *predictions
= autofill_param
.a
;
145 process()->sink().ClearMessages();
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
);
158 Tuple1
<base::string16
> autofill_param
;
160 case AutofillMsg_FillFieldWithValue::ID
:
161 if (!AutofillMsg_FillFieldWithValue::Read(message
, &autofill_param
))
164 case AutofillMsg_PreviewFieldWithValue::ID
:
165 if (!AutofillMsg_PreviewFieldWithValue::Read(message
, &autofill_param
))
168 case AutofillMsg_AcceptDataListSuggestion::ID
:
169 if (!AutofillMsg_AcceptDataListSuggestion::Read(message
,
177 *value
= autofill_param
.a
;
178 process()->sink().ClearMessages();
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
);
190 process()->sink().ClearMessages();
194 scoped_ptr
<TestAutofillClient
> test_autofill_client_
;
195 scoped_ptr
<TestContentAutofillDriver
> driver_
;
198 TEST_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
);
206 TEST_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
);
216 TEST_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
);
225 TEST_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
);
232 int output_page_id
= 0;
233 FormData output_form_data
;
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
);
241 TEST_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
);
248 int output_page_id
= 0;
249 FormData output_form_data
;
250 EXPECT_FALSE(GetAutofillFillFormMessage(&output_page_id
, &output_form_data
));
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
);
257 TEST_F(ContentAutofillDriverTest
,
258 TypePredictionsNotSentToRendererWhenDisabled
) {
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
));
267 TEST_F(ContentAutofillDriverTest
, TypePredictionsSentToRendererWhenEnabled
) {
268 CommandLine::ForCurrentProcess()->AppendSwitch(
269 switches::kShowAutofillTypePredictions
);
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
);
279 std::vector
<FormDataPredictions
> output_type_predictions
;
280 EXPECT_TRUE(GetFieldTypePredictionsAvailable(&output_type_predictions
));
281 EXPECT_EQ(expected_type_predictions
, output_type_predictions
);
284 TEST_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
);
293 TEST_F(ContentAutofillDriverTest
, ClearFilledFormSentToRenderer
) {
294 driver_
->RendererShouldClearFilledForm();
295 EXPECT_TRUE(HasMessageMatchingID(AutofillMsg_ClearForm::ID
));
298 TEST_F(ContentAutofillDriverTest
, ClearPreviewedFormSentToRenderer
) {
299 driver_
->RendererShouldClearPreviewedForm();
300 EXPECT_TRUE(HasMessageMatchingID(AutofillMsg_ClearPreviewedForm::ID
));
303 TEST_F(ContentAutofillDriverTest
, FillFieldWithValue
) {
304 base::string16
input_value(base::ASCIIToUTF16("barqux"));
305 base::string16 output_value
;
307 driver_
->RendererShouldFillFieldWithValue(input_value
);
308 EXPECT_TRUE(GetString16FromMessageWithID(AutofillMsg_FillFieldWithValue::ID
,
310 EXPECT_EQ(input_value
, output_value
);
313 TEST_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
,
320 EXPECT_EQ(input_value
, output_value
);
323 } // namespace autofill