content_autofill_driver_unittest.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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 "chrome/test/base/chrome_render_view_host_test_harness.h"
12#include "components/autofill/content/browser/content_autofill_driver.h"
13#include "components/autofill/content/common/autofill_messages.h"
14#include "components/autofill/core/browser/autofill_external_delegate.h"
15#include "components/autofill/core/browser/autofill_manager.h"
16#include "components/autofill/core/browser/autofill_test_utils.h"
17#include "components/autofill/core/browser/test_autofill_manager_delegate.h"
18#include "components/autofill/core/common/autofill_switches.h"
19#include "components/autofill/core/common/form_data_predictions.h"
20#include "content/public/browser/browser_context.h"
21#include "content/public/browser/navigation_details.h"
22#include "content/public/browser/web_contents.h"
23#include "content/public/common/frame_navigate_params.h"
24#include "content/public/test/mock_render_process_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, AutofillManagerDelegate* delegate)
42      : AutofillManager(driver, delegate, 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                            AutofillManagerDelegate* delegate)
52      : ContentAutofillDriver(contents, delegate, kAppLocale, kDownloadState) {
53    scoped_ptr<AutofillManager> autofill_manager(
54        new MockAutofillManager(this, delegate));
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 ChromeRenderViewHostTestHarness {
67 public:
68  virtual void SetUp() OVERRIDE {
69    ChromeRenderViewHostTestHarness::SetUp();
70
71    test_manager_delegate_.reset(new TestAutofillManagerDelegate());
72    driver_.reset(new TestContentAutofillDriver(web_contents(),
73                                                test_manager_delegate_.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    ChromeRenderViewHostTestHarness::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      case AutofillMsg_AcceptPasswordAutofillSuggestion::ID:
174        if (!AutofillMsg_AcceptPasswordAutofillSuggestion::Read(
175                message, &autofill_param))
176          return false;
177        break;
178      default:
179        NOTREACHED();
180    }
181    if (value)
182      *value = autofill_param.a;
183    process()->sink().ClearMessages();
184    return true;
185  }
186
187  // Searches for a message matching |messageID| in the queue of sent IPC
188  // messages. If none is present, returns false. Otherwise, clears the queue
189  // of sent messages and returns true.
190  bool HasMessageMatchingID(uint32 messageID) {
191    const IPC::Message* message =
192        process()->sink().GetFirstMessageMatching(messageID);
193    if (!message)
194      return false;
195    process()->sink().ClearMessages();
196    return true;
197  }
198
199  scoped_ptr<TestAutofillManagerDelegate> test_manager_delegate_;
200  scoped_ptr<TestContentAutofillDriver> driver_;
201};
202
203TEST_F(ContentAutofillDriverTest, GetURLRequestContext) {
204  net::URLRequestContextGetter* request_context =
205      driver_->GetURLRequestContext();
206  net::URLRequestContextGetter* expected_request_context =
207      web_contents()->GetBrowserContext()->GetRequestContext();
208  EXPECT_EQ(request_context, expected_request_context);
209}
210
211TEST_F(ContentAutofillDriverTest, NavigatedToDifferentPage) {
212  EXPECT_CALL(*driver_->mock_autofill_manager(), Reset());
213  content::LoadCommittedDetails details = content::LoadCommittedDetails();
214  details.is_main_frame = true;
215  details.is_in_page = false;
216  ASSERT_TRUE(details.is_navigation_to_different_page());
217  content::FrameNavigateParams params = content::FrameNavigateParams();
218  driver_->DidNavigateMainFrame(details, params);
219}
220
221TEST_F(ContentAutofillDriverTest, NavigatedWithinSamePage) {
222  EXPECT_CALL(*driver_->mock_autofill_manager(), Reset()).Times(0);
223  content::LoadCommittedDetails details = content::LoadCommittedDetails();
224  details.is_main_frame = false;
225  ASSERT_TRUE(!details.is_navigation_to_different_page());
226  content::FrameNavigateParams params = content::FrameNavigateParams();
227  driver_->DidNavigateMainFrame(details, params);
228}
229
230TEST_F(ContentAutofillDriverTest, FormDataSentToRenderer_FillForm) {
231  int input_page_id = 42;
232  FormData input_form_data;
233  test::CreateTestAddressFormData(&input_form_data);
234  driver_->SendFormDataToRenderer(
235      input_page_id, AutofillDriver::FORM_DATA_ACTION_FILL, input_form_data);
236
237  int output_page_id = 0;
238  FormData output_form_data;
239  EXPECT_FALSE(
240      GetAutofillPreviewFormMessage(&output_page_id, &output_form_data));
241  EXPECT_TRUE(GetAutofillFillFormMessage(&output_page_id, &output_form_data));
242  EXPECT_EQ(input_page_id, output_page_id);
243  EXPECT_EQ(input_form_data, output_form_data);
244}
245
246TEST_F(ContentAutofillDriverTest, FormDataSentToRenderer_PreviewForm) {
247  int input_page_id = 42;
248  FormData input_form_data;
249  test::CreateTestAddressFormData(&input_form_data);
250  driver_->SendFormDataToRenderer(
251      input_page_id, AutofillDriver::FORM_DATA_ACTION_PREVIEW, input_form_data);
252
253  int output_page_id = 0;
254  FormData output_form_data;
255  EXPECT_FALSE(GetAutofillFillFormMessage(&output_page_id, &output_form_data));
256  EXPECT_TRUE(
257      GetAutofillPreviewFormMessage(&output_page_id, &output_form_data));
258  EXPECT_EQ(input_page_id, output_page_id);
259  EXPECT_EQ(input_form_data, output_form_data);
260}
261
262TEST_F(ContentAutofillDriverTest,
263       TypePredictionsNotSentToRendererWhenDisabled) {
264  FormData form;
265  test::CreateTestAddressFormData(&form);
266  FormStructure form_structure(form);
267  std::vector<FormStructure*> forms(1, &form_structure);
268  driver_->SendAutofillTypePredictionsToRenderer(forms);
269  EXPECT_FALSE(GetFieldTypePredictionsAvailable(NULL));
270}
271
272TEST_F(ContentAutofillDriverTest, TypePredictionsSentToRendererWhenEnabled) {
273  CommandLine::ForCurrentProcess()->AppendSwitch(
274      switches::kShowAutofillTypePredictions);
275
276  FormData form;
277  test::CreateTestAddressFormData(&form);
278  FormStructure form_structure(form);
279  std::vector<FormStructure*> forms(1, &form_structure);
280  std::vector<FormDataPredictions> expected_type_predictions;
281  FormStructure::GetFieldTypePredictions(forms, &expected_type_predictions);
282  driver_->SendAutofillTypePredictionsToRenderer(forms);
283
284  std::vector<FormDataPredictions> output_type_predictions;
285  EXPECT_TRUE(GetFieldTypePredictionsAvailable(&output_type_predictions));
286  EXPECT_EQ(expected_type_predictions, output_type_predictions);
287}
288
289TEST_F(ContentAutofillDriverTest, AcceptDataListSuggestion) {
290  base::string16 input_value(base::ASCIIToUTF16("barfoo"));
291  base::string16 output_value;
292  driver_->RendererShouldAcceptDataListSuggestion(input_value);
293  EXPECT_TRUE(GetString16FromMessageWithID(
294      AutofillMsg_AcceptDataListSuggestion::ID, &output_value));
295  EXPECT_EQ(input_value, output_value);
296}
297
298TEST_F(ContentAutofillDriverTest, AcceptPasswordAutofillSuggestion) {
299  base::string16 input_value(base::ASCIIToUTF16("barbaz"));
300  base::string16 output_value;
301  driver_->RendererShouldAcceptPasswordAutofillSuggestion(input_value);
302  EXPECT_TRUE(GetString16FromMessageWithID(
303      AutofillMsg_AcceptPasswordAutofillSuggestion::ID, &output_value));
304  EXPECT_EQ(input_value, output_value);
305}
306
307TEST_F(ContentAutofillDriverTest, ClearFilledFormSentToRenderer) {
308  driver_->RendererShouldClearFilledForm();
309  EXPECT_TRUE(HasMessageMatchingID(AutofillMsg_ClearForm::ID));
310}
311
312TEST_F(ContentAutofillDriverTest, ClearPreviewedFormSentToRenderer) {
313  driver_->RendererShouldClearPreviewedForm();
314  EXPECT_TRUE(HasMessageMatchingID(AutofillMsg_ClearPreviewedForm::ID));
315}
316
317TEST_F(ContentAutofillDriverTest, FillFieldWithValue) {
318  base::string16 input_value(base::ASCIIToUTF16("barqux"));
319  base::string16 output_value;
320
321  driver_->RendererShouldFillFieldWithValue(input_value);
322  EXPECT_TRUE(GetString16FromMessageWithID(AutofillMsg_FillFieldWithValue::ID,
323                                           &output_value));
324  EXPECT_EQ(input_value, output_value);
325}
326
327TEST_F(ContentAutofillDriverTest, PreviewFieldWithValue) {
328  base::string16 input_value(base::ASCIIToUTF16("barqux"));
329  base::string16 output_value;
330  driver_->RendererShouldPreviewFieldWithValue(input_value);
331  EXPECT_TRUE(GetString16FromMessageWithID(
332      AutofillMsg_PreviewFieldWithValue::ID,
333      &output_value));
334  EXPECT_EQ(input_value, output_value);
335}
336
337}  // namespace autofill
338