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