Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / components / autofill / core / browser / autofill_external_delegate_unittest.cc
1 // Copyright 2013 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 <vector>
6
7 #include "base/command_line.h"
8 #include "base/compiler_specific.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/string16.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "components/autofill/core/browser/autofill_manager.h"
13 #include "components/autofill/core/browser/popup_item_ids.h"
14 #include "components/autofill/core/browser/test_autofill_client.h"
15 #include "components/autofill/core/browser/test_autofill_driver.h"
16 #include "components/autofill/core/browser/test_autofill_external_delegate.h"
17 #include "components/autofill/core/common/autofill_switches.h"
18 #include "components/autofill/core/common/form_data.h"
19 #include "components/autofill/core/common/form_field_data.h"
20 #include "components/autofill/core/common/password_form_fill_data.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "ui/gfx/rect.h"
24
25 using base::ASCIIToUTF16;
26 using testing::_;
27
28 namespace autofill {
29
30 namespace {
31
32 // A constant value to use as the Autofill query ID.
33 const int kQueryId = 5;
34
35 // A constant value to use as an Autofill profile ID.
36 const int kAutofillProfileId = 1;
37
38 class MockAutofillDriver : public TestAutofillDriver {
39  public:
40   MockAutofillDriver() {}
41   // Mock methods to enable testability.
42   MOCK_METHOD1(RendererShouldAcceptDataListSuggestion,
43                void(const base::string16&));
44   MOCK_METHOD0(RendererShouldClearFilledForm, void());
45   MOCK_METHOD0(RendererShouldClearPreviewedForm, void());
46   MOCK_METHOD1(RendererShouldFillFieldWithValue, void(const base::string16&));
47   MOCK_METHOD1(RendererShouldPreviewFieldWithValue,
48                void(const base::string16&));
49
50  private:
51   DISALLOW_COPY_AND_ASSIGN(MockAutofillDriver);
52 };
53
54 class MockAutofillClient : public autofill::TestAutofillClient {
55  public:
56   MockAutofillClient() {}
57
58   MOCK_METHOD7(ShowAutofillPopup,
59                void(const gfx::RectF& element_bounds,
60                     base::i18n::TextDirection text_direction,
61                     const std::vector<base::string16>& values,
62                     const std::vector<base::string16>& labels,
63                     const std::vector<base::string16>& icons,
64                     const std::vector<int>& identifiers,
65                     base::WeakPtr<AutofillPopupDelegate> delegate));
66
67   MOCK_METHOD2(UpdateAutofillPopupDataListValues,
68                void(const std::vector<base::string16>& values,
69                     const std::vector<base::string16>& lables));
70
71   MOCK_METHOD0(HideAutofillPopup, void());
72
73  private:
74   DISALLOW_COPY_AND_ASSIGN(MockAutofillClient);
75 };
76
77 class MockAutofillManager : public AutofillManager {
78  public:
79   MockAutofillManager(AutofillDriver* driver, MockAutofillClient* client)
80       // Force to use the constructor designated for unit test, but we don't
81       // really need personal_data in this test so we pass a NULL pointer.
82       : AutofillManager(driver, client, NULL) {}
83   virtual ~MockAutofillManager() {}
84
85   MOCK_METHOD5(FillOrPreviewForm,
86                void(AutofillDriver::RendererFormDataAction action,
87                     int query_id,
88                     const FormData& form,
89                     const FormFieldData& field,
90                     int unique_id));
91
92  private:
93   DISALLOW_COPY_AND_ASSIGN(MockAutofillManager);
94 };
95
96 }  // namespace
97
98 class AutofillExternalDelegateUnitTest : public testing::Test {
99  protected:
100   void SetUp() override {
101     autofill_driver_.reset(new MockAutofillDriver());
102     autofill_manager_.reset(
103         new MockAutofillManager(autofill_driver_.get(), &autofill_client_));
104     external_delegate_.reset(
105         new AutofillExternalDelegate(
106             autofill_manager_.get(), autofill_driver_.get()));
107   }
108
109   void TearDown() override {
110     // Order of destruction is important as AutofillManager relies on
111     // PersonalDataManager to be around when it gets destroyed.
112     autofill_manager_.reset();
113     external_delegate_.reset();
114     autofill_driver_.reset();
115   }
116
117   // Issue an OnQuery call with the given |query_id|.
118   void IssueOnQuery(int query_id) {
119     const FormData form;
120     FormFieldData field;
121     field.is_focusable = true;
122     field.should_autocomplete = true;
123     const gfx::RectF element_bounds;
124
125     external_delegate_->OnQuery(query_id, form, field, element_bounds, true);
126   }
127
128   MockAutofillClient autofill_client_;
129   scoped_ptr<MockAutofillDriver> autofill_driver_;
130   scoped_ptr<MockAutofillManager> autofill_manager_;
131   scoped_ptr<AutofillExternalDelegate> external_delegate_;
132
133   base::MessageLoop message_loop_;
134 };
135
136 // Test that our external delegate called the virtual methods at the right time.
137 TEST_F(AutofillExternalDelegateUnitTest, TestExternalDelegateVirtualCalls) {
138   IssueOnQuery(kQueryId);
139
140   // The enums must be cast to ints to prevent compile errors on linux_rel.
141   EXPECT_CALL(
142       autofill_client_,
143       ShowAutofillPopup(_,
144                         _,
145                         _,
146                         _,
147                         _,
148                         testing::ElementsAre(
149                             kAutofillProfileId,
150                             static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
151                             static_cast<int>(POPUP_ITEM_ID_AUTOFILL_OPTIONS)),
152                         _));
153
154   // This should call ShowAutofillPopup.
155   std::vector<base::string16> autofill_item;
156   autofill_item.push_back(base::string16());
157   std::vector<int> autofill_ids;
158   autofill_ids.push_back(kAutofillProfileId);
159   external_delegate_->OnSuggestionsReturned(kQueryId,
160                                             autofill_item,
161                                             autofill_item,
162                                             autofill_item,
163                                             autofill_ids);
164
165   EXPECT_CALL(*autofill_manager_,
166               FillOrPreviewForm(
167                   AutofillDriver::FORM_DATA_ACTION_FILL, _, _, _, _));
168   EXPECT_CALL(autofill_client_, HideAutofillPopup());
169
170   // This should trigger a call to hide the popup since we've selected an
171   // option.
172   external_delegate_->DidAcceptSuggestion(autofill_item[0], autofill_ids[0]);
173 }
174
175 // Test that data list elements for a node will appear in the Autofill popup.
176 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateDataList) {
177   IssueOnQuery(kQueryId);
178
179   std::vector<base::string16> data_list_items;
180   data_list_items.push_back(base::string16());
181
182   EXPECT_CALL(
183       autofill_client_,
184       UpdateAutofillPopupDataListValues(data_list_items, data_list_items));
185
186   external_delegate_->SetCurrentDataListValues(data_list_items,
187                                                data_list_items);
188
189   // The enums must be cast to ints to prevent compile errors on linux_rel.
190   EXPECT_CALL(
191       autofill_client_,
192       ShowAutofillPopup(_,
193                         _,
194                         _,
195                         _,
196                         _,
197                         testing::ElementsAre(
198                             static_cast<int>(POPUP_ITEM_ID_DATALIST_ENTRY),
199                             static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
200                             kAutofillProfileId,
201                             static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
202                             static_cast<int>(POPUP_ITEM_ID_AUTOFILL_OPTIONS)),
203                         _));
204
205   // This should call ShowAutofillPopup.
206   std::vector<base::string16> autofill_item;
207   autofill_item.push_back(base::string16());
208   std::vector<int> autofill_ids;
209   autofill_ids.push_back(kAutofillProfileId);
210   external_delegate_->OnSuggestionsReturned(kQueryId,
211                                             autofill_item,
212                                             autofill_item,
213                                             autofill_item,
214                                             autofill_ids);
215
216   // Try calling OnSuggestionsReturned with no Autofill values and ensure
217   // the datalist items are still shown.
218   // The enum must be cast to an int to prevent compile errors on linux_rel.
219   EXPECT_CALL(
220       autofill_client_,
221       ShowAutofillPopup(
222           _,
223           _,
224           _,
225           _,
226           _,
227           testing::ElementsAre(static_cast<int>(POPUP_ITEM_ID_DATALIST_ENTRY)),
228           _));
229
230   autofill_item = std::vector<base::string16>();
231   autofill_ids = std::vector<int>();
232   external_delegate_->OnSuggestionsReturned(kQueryId,
233                                             autofill_item,
234                                             autofill_item,
235                                             autofill_item,
236                                             autofill_ids);
237 }
238
239 // Test that datalist values can get updated while a popup is showing.
240 TEST_F(AutofillExternalDelegateUnitTest, UpdateDataListWhileShowingPopup) {
241   IssueOnQuery(kQueryId);
242
243   EXPECT_CALL(autofill_client_, ShowAutofillPopup(_, _, _, _, _, _, _))
244       .Times(0);
245
246   // Make sure just setting the data list values doesn't cause the popup to
247   // appear.
248   std::vector<base::string16> data_list_items;
249   data_list_items.push_back(base::string16());
250
251   EXPECT_CALL(
252       autofill_client_,
253       UpdateAutofillPopupDataListValues(data_list_items, data_list_items));
254
255   external_delegate_->SetCurrentDataListValues(data_list_items,
256                                                data_list_items);
257
258   // The enums must be cast to ints to prevent compile errors on linux_rel.
259   EXPECT_CALL(
260       autofill_client_,
261       ShowAutofillPopup(_,
262                         _,
263                         _,
264                         _,
265                         _,
266                         testing::ElementsAre(
267                             static_cast<int>(POPUP_ITEM_ID_DATALIST_ENTRY),
268                             static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
269                             kAutofillProfileId,
270                             static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
271                             static_cast<int>(POPUP_ITEM_ID_AUTOFILL_OPTIONS)),
272                         _));
273
274   // Ensure the popup is displayed.
275   std::vector<base::string16> autofill_item;
276   autofill_item.push_back(base::string16());
277   std::vector<int> autofill_ids;
278   autofill_ids.push_back(kAutofillProfileId);
279   external_delegate_->OnSuggestionsReturned(kQueryId,
280                                             autofill_item,
281                                             autofill_item,
282                                             autofill_item,
283                                             autofill_ids);
284
285   // This would normally get called from ShowAutofillPopup, but it is mocked so
286   // we need to call OnPopupShown ourselves.
287   external_delegate_->OnPopupShown();
288
289   // Update the current data list and ensure the popup is updated.
290   data_list_items.push_back(base::string16());
291
292   // The enums must be cast to ints to prevent compile errors on linux_rel.
293   EXPECT_CALL(
294       autofill_client_,
295       UpdateAutofillPopupDataListValues(data_list_items, data_list_items));
296
297   external_delegate_->SetCurrentDataListValues(data_list_items,
298                                                data_list_items);
299 }
300
301 // Test that the Autofill popup is able to display warnings explaining why
302 // Autofill is disabled for a website.
303 // Regression test for http://crbug.com/247880
304 TEST_F(AutofillExternalDelegateUnitTest, AutofillWarnings) {
305   IssueOnQuery(kQueryId);
306
307   // The enums must be cast to ints to prevent compile errors on linux_rel.
308   EXPECT_CALL(
309       autofill_client_,
310       ShowAutofillPopup(
311           _,
312           _,
313           _,
314           _,
315           _,
316           testing::ElementsAre(static_cast<int>(POPUP_ITEM_ID_WARNING_MESSAGE)),
317           _));
318
319   // This should call ShowAutofillPopup.
320   std::vector<base::string16> autofill_item;
321   autofill_item.push_back(base::string16());
322   std::vector<int> autofill_ids;
323   autofill_ids.push_back(POPUP_ITEM_ID_WARNING_MESSAGE);
324   external_delegate_->OnSuggestionsReturned(kQueryId,
325                                             autofill_item,
326                                             autofill_item,
327                                             autofill_item,
328                                             autofill_ids);
329 }
330
331 // Test that the Autofill popup doesn't display a warning explaining why
332 // Autofill is disabled for a website when there are no Autofill suggestions.
333 // Regression test for http://crbug.com/105636
334 TEST_F(AutofillExternalDelegateUnitTest, NoAutofillWarningsWithoutSuggestions) {
335   const FormData form;
336   FormFieldData field;
337   field.is_focusable = true;
338   field.should_autocomplete = false;
339   const gfx::RectF element_bounds;
340
341   external_delegate_->OnQuery(kQueryId, form, field, element_bounds, true);
342
343   EXPECT_CALL(autofill_client_, ShowAutofillPopup(_, _, _, _, _, _, _))
344       .Times(0);
345   EXPECT_CALL(autofill_client_, HideAutofillPopup()).Times(1);
346
347   // This should not call ShowAutofillPopup.
348   std::vector<base::string16> autofill_item;
349   autofill_item.push_back(base::string16());
350   std::vector<int> autofill_ids;
351   autofill_ids.push_back(POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY);
352   external_delegate_->OnSuggestionsReturned(kQueryId,
353                                             autofill_item,
354                                             autofill_item,
355                                             autofill_item,
356                                             autofill_ids);
357 }
358
359 // Test that the Autofill delegate doesn't try and fill a form with a
360 // negative unique id.
361 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateInvalidUniqueId) {
362   // Ensure it doesn't try to preview the negative id.
363   EXPECT_CALL(*autofill_manager_, FillOrPreviewForm(_, _, _, _, _)).Times(0);
364   EXPECT_CALL(*autofill_driver_, RendererShouldClearPreviewedForm()).Times(1);
365   external_delegate_->DidSelectSuggestion(base::string16(), -1);
366
367   // Ensure it doesn't try to fill the form in with the negative id.
368   EXPECT_CALL(autofill_client_, HideAutofillPopup());
369   EXPECT_CALL(*autofill_manager_, FillOrPreviewForm(_, _, _, _, _)).Times(0);
370   external_delegate_->DidAcceptSuggestion(base::string16(), -1);
371 }
372
373 // Test that the ClearPreview call is only sent if the form was being previewed
374 // (i.e. it isn't autofilling a password).
375 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateClearPreviewedForm) {
376   // Ensure selecting a new password entries or Autofill entries will
377   // cause any previews to get cleared.
378   EXPECT_CALL(*autofill_driver_, RendererShouldClearPreviewedForm()).Times(1);
379   external_delegate_->DidSelectSuggestion(ASCIIToUTF16("baz foo"),
380                                           POPUP_ITEM_ID_PASSWORD_ENTRY);
381   EXPECT_CALL(*autofill_driver_, RendererShouldClearPreviewedForm()).Times(1);
382   EXPECT_CALL(*autofill_manager_,
383               FillOrPreviewForm(
384                   AutofillDriver::FORM_DATA_ACTION_PREVIEW, _, _, _, _));
385   external_delegate_->DidSelectSuggestion(ASCIIToUTF16("baz foo"), 1);
386
387   // Ensure selecting an autocomplete entry will cause any previews to
388   // get cleared.
389   EXPECT_CALL(*autofill_driver_, RendererShouldClearPreviewedForm()).Times(1);
390   EXPECT_CALL(*autofill_driver_, RendererShouldPreviewFieldWithValue(
391                                      ASCIIToUTF16("baz foo")));
392   external_delegate_->DidSelectSuggestion(ASCIIToUTF16("baz foo"),
393                                           POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY);
394 }
395
396 // Test that the popup is hidden once we are done editing the autofill field.
397 TEST_F(AutofillExternalDelegateUnitTest,
398        ExternalDelegateHidePopupAfterEditing) {
399   EXPECT_CALL(autofill_client_, ShowAutofillPopup(_, _, _, _, _, _, _));
400   autofill::GenerateTestAutofillPopup(external_delegate_.get());
401
402   EXPECT_CALL(autofill_client_, HideAutofillPopup());
403   external_delegate_->DidEndTextFieldEditing();
404 }
405
406 // Test that the driver is directed to accept the data list after being notified
407 // that the user accepted the data list suggestion.
408 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateAcceptSuggestion) {
409   EXPECT_CALL(autofill_client_, HideAutofillPopup());
410   base::string16 dummy_string(ASCIIToUTF16("baz qux"));
411   EXPECT_CALL(*autofill_driver_,
412               RendererShouldAcceptDataListSuggestion(dummy_string));
413   external_delegate_->DidAcceptSuggestion(dummy_string,
414                                           POPUP_ITEM_ID_DATALIST_ENTRY);
415 }
416
417 // Test that the driver is directed to clear the form after being notified that
418 // the user accepted the suggestion to clear the form.
419 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateClearForm) {
420   EXPECT_CALL(autofill_client_, HideAutofillPopup());
421   EXPECT_CALL(*autofill_driver_, RendererShouldClearFilledForm());
422
423   external_delegate_->DidAcceptSuggestion(base::string16(),
424                                           POPUP_ITEM_ID_CLEAR_FORM);
425 }
426
427 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateHideWarning) {
428   // Set up a field that shouldn't get autocompleted or display warnings.
429   const FormData form;
430   FormFieldData field;
431   field.is_focusable = true;
432   field.should_autocomplete = false;
433   const gfx::RectF element_bounds;
434
435   external_delegate_->OnQuery(kQueryId, form, field, element_bounds, false);
436
437   std::vector<base::string16> autofill_items;
438   autofill_items.push_back(base::string16());
439   std::vector<int> autofill_ids;
440   autofill_ids.push_back(POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY);
441
442   // Ensure the popup tries to hide itself, since it is not allowed to show
443   // anything.
444   EXPECT_CALL(autofill_client_, HideAutofillPopup());
445
446   external_delegate_->OnSuggestionsReturned(kQueryId,
447                                             autofill_items,
448                                             autofill_items,
449                                             autofill_items,
450                                             autofill_ids);
451 }
452
453 TEST_F(AutofillExternalDelegateUnitTest, IgnoreAutocompleteOffForAutofill) {
454   CommandLine::ForCurrentProcess()->AppendSwitch(
455       switches::kIgnoreAutocompleteOffForAutofill);
456
457   const FormData form;
458   FormFieldData field;
459   field.is_focusable = true;
460   field.should_autocomplete = false;
461   const gfx::RectF element_bounds;
462
463   external_delegate_->OnQuery(kQueryId, form, field, element_bounds, false);
464
465   std::vector<base::string16> autofill_items;
466   autofill_items.push_back(base::string16());
467   std::vector<int> autofill_ids;
468   autofill_ids.push_back(POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY);
469
470   // Ensure the popup tries to show itself, despite autocomplete="off".
471   EXPECT_CALL(autofill_client_, ShowAutofillPopup(_, _, _, _, _, _, _));
472   EXPECT_CALL(autofill_client_, HideAutofillPopup()).Times(0);
473
474   external_delegate_->OnSuggestionsReturned(kQueryId,
475                                             autofill_items,
476                                             autofill_items,
477                                             autofill_items,
478                                             autofill_ids);
479 }
480
481 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateFillFieldWithValue) {
482   EXPECT_CALL(autofill_client_, HideAutofillPopup());
483   base::string16 dummy_string(ASCIIToUTF16("baz foo"));
484   EXPECT_CALL(*autofill_driver_,
485               RendererShouldFillFieldWithValue(dummy_string));
486   external_delegate_->DidAcceptSuggestion(dummy_string,
487                                           POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY);
488 }
489
490 }  // namespace autofill