ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / components / autofill / core / browser / autofill_external_delegate_unittest.cc
blob06949156752705e9ae27361cd899205ddfc8f180
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.
5 #include <vector>
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 "base/test/histogram_tester.h"
13 #include "components/autofill/core/browser/autofill_manager.h"
14 #include "components/autofill/core/browser/autofill_metrics.h"
15 #include "components/autofill/core/browser/popup_item_ids.h"
16 #include "components/autofill/core/browser/suggestion_test_helpers.h"
17 #include "components/autofill/core/browser/test_autofill_client.h"
18 #include "components/autofill/core/browser/test_autofill_driver.h"
19 #include "components/autofill/core/browser/test_autofill_external_delegate.h"
20 #include "components/autofill/core/common/autofill_switches.h"
21 #include "components/autofill/core/common/form_data.h"
22 #include "components/autofill/core/common/form_field_data.h"
23 #include "components/autofill/core/common/password_form_fill_data.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "ui/gfx/geometry/rect.h"
28 using base::ASCIIToUTF16;
29 using testing::_;
31 namespace autofill {
33 namespace {
35 // A constant value to use as the Autofill query ID.
36 const int kQueryId = 5;
38 // A constant value to use as an Autofill profile ID.
39 const int kAutofillProfileId = 1;
41 class MockAutofillDriver : public TestAutofillDriver {
42 public:
43 MockAutofillDriver() {}
44 // Mock methods to enable testability.
45 MOCK_METHOD1(RendererShouldAcceptDataListSuggestion,
46 void(const base::string16&));
47 MOCK_METHOD0(RendererShouldClearFilledForm, void());
48 MOCK_METHOD0(RendererShouldClearPreviewedForm, void());
49 MOCK_METHOD1(RendererShouldFillFieldWithValue, void(const base::string16&));
50 MOCK_METHOD1(RendererShouldPreviewFieldWithValue,
51 void(const base::string16&));
53 private:
54 DISALLOW_COPY_AND_ASSIGN(MockAutofillDriver);
57 class MockAutofillClient : public autofill::TestAutofillClient {
58 public:
59 MockAutofillClient() {}
61 MOCK_METHOD1(ScanCreditCard,
62 void(const CreditCardScanCallback& callbacK));
64 MOCK_METHOD4(ShowAutofillPopup,
65 void(const gfx::RectF& element_bounds,
66 base::i18n::TextDirection text_direction,
67 const std::vector<Suggestion>& suggestions,
68 base::WeakPtr<AutofillPopupDelegate> delegate));
70 MOCK_METHOD2(UpdateAutofillPopupDataListValues,
71 void(const std::vector<base::string16>& values,
72 const std::vector<base::string16>& lables));
74 MOCK_METHOD0(HideAutofillPopup, void());
76 private:
77 DISALLOW_COPY_AND_ASSIGN(MockAutofillClient);
80 class MockAutofillManager : public AutofillManager {
81 public:
82 MockAutofillManager(AutofillDriver* driver, MockAutofillClient* client)
83 // Force to use the constructor designated for unit test, but we don't
84 // really need personal_data in this test so we pass a NULL pointer.
85 : AutofillManager(driver, client, NULL) {}
86 virtual ~MockAutofillManager() {}
88 MOCK_METHOD2(ShouldShowScanCreditCard,
89 bool(const FormData& form, const FormFieldData& field));
91 MOCK_METHOD5(FillOrPreviewForm,
92 void(AutofillDriver::RendererFormDataAction action,
93 int query_id,
94 const FormData& form,
95 const FormFieldData& field,
96 int unique_id));
98 MOCK_METHOD4(FillCreditCardForm,
99 void(int query_id,
100 const FormData& form,
101 const FormFieldData& field,
102 const CreditCard& credit_card));
104 private:
105 DISALLOW_COPY_AND_ASSIGN(MockAutofillManager);
108 } // namespace
110 class AutofillExternalDelegateUnitTest : public testing::Test {
111 protected:
112 void SetUp() override {
113 autofill_driver_.reset(new testing::NiceMock<MockAutofillDriver>());
114 autofill_manager_.reset(
115 new MockAutofillManager(autofill_driver_.get(), &autofill_client_));
116 external_delegate_.reset(
117 new AutofillExternalDelegate(
118 autofill_manager_.get(), autofill_driver_.get()));
121 void TearDown() override {
122 // Order of destruction is important as AutofillManager relies on
123 // PersonalDataManager to be around when it gets destroyed.
124 autofill_manager_.reset();
125 external_delegate_.reset();
126 autofill_driver_.reset();
129 // Issue an OnQuery call with the given |query_id|.
130 void IssueOnQuery(int query_id) {
131 const FormData form;
132 FormFieldData field;
133 field.is_focusable = true;
134 field.should_autocomplete = true;
135 const gfx::RectF element_bounds;
137 external_delegate_->OnQuery(query_id, form, field, element_bounds, true);
140 void IssueOnSuggestionsReturned() {
141 std::vector<Suggestion> suggestions;
142 suggestions.push_back(Suggestion());
143 suggestions[0].frontend_id = kAutofillProfileId;
144 external_delegate_->OnSuggestionsReturned(kQueryId, suggestions);
147 testing::NiceMock<MockAutofillClient> autofill_client_;
148 scoped_ptr<testing::NiceMock<MockAutofillDriver>> autofill_driver_;
149 scoped_ptr<MockAutofillManager> autofill_manager_;
150 scoped_ptr<AutofillExternalDelegate> external_delegate_;
152 base::MessageLoop message_loop_;
155 // Test that our external delegate called the virtual methods at the right time.
156 TEST_F(AutofillExternalDelegateUnitTest, TestExternalDelegateVirtualCalls) {
157 IssueOnQuery(kQueryId);
159 // The enums must be cast to ints to prevent compile errors on linux_rel.
160 EXPECT_CALL(
161 autofill_client_,
162 ShowAutofillPopup(_,
164 SuggestionVectorIdsAre(testing::ElementsAre(
165 kAutofillProfileId,
166 static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
167 static_cast<int>(POPUP_ITEM_ID_AUTOFILL_OPTIONS))),
168 _));
170 // This should call ShowAutofillPopup.
171 std::vector<Suggestion> autofill_item;
172 autofill_item.push_back(Suggestion());
173 autofill_item[0].frontend_id = kAutofillProfileId;
174 external_delegate_->OnSuggestionsReturned(kQueryId, autofill_item);
176 EXPECT_CALL(*autofill_manager_,
177 FillOrPreviewForm(
178 AutofillDriver::FORM_DATA_ACTION_FILL, _, _, _, _));
179 EXPECT_CALL(autofill_client_, HideAutofillPopup());
181 // This should trigger a call to hide the popup since we've selected an
182 // option.
183 external_delegate_->DidAcceptSuggestion(autofill_item[0].value,
184 autofill_item[0].frontend_id);
187 // Test that data list elements for a node will appear in the Autofill popup.
188 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateDataList) {
189 IssueOnQuery(kQueryId);
191 std::vector<base::string16> data_list_items;
192 data_list_items.push_back(base::string16());
194 EXPECT_CALL(
195 autofill_client_,
196 UpdateAutofillPopupDataListValues(data_list_items, data_list_items));
198 external_delegate_->SetCurrentDataListValues(data_list_items,
199 data_list_items);
201 // The enums must be cast to ints to prevent compile errors on linux_rel.
202 EXPECT_CALL(
203 autofill_client_,
204 ShowAutofillPopup(_,
206 SuggestionVectorIdsAre(testing::ElementsAre(
207 static_cast<int>(POPUP_ITEM_ID_DATALIST_ENTRY),
208 static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
209 kAutofillProfileId,
210 static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
211 static_cast<int>(POPUP_ITEM_ID_AUTOFILL_OPTIONS))),
212 _));
214 // This should call ShowAutofillPopup.
215 std::vector<Suggestion> autofill_item;
216 autofill_item.push_back(Suggestion());
217 autofill_item[0].frontend_id = kAutofillProfileId;
218 external_delegate_->OnSuggestionsReturned(kQueryId, autofill_item);
220 // Try calling OnSuggestionsReturned with no Autofill values and ensure
221 // the datalist items are still shown.
222 // The enum must be cast to an int to prevent compile errors on linux_rel.
223 EXPECT_CALL(
224 autofill_client_,
225 ShowAutofillPopup(
228 SuggestionVectorIdsAre(testing::ElementsAre(
229 static_cast<int>(POPUP_ITEM_ID_DATALIST_ENTRY))),
230 _));
232 autofill_item.clear();
233 external_delegate_->OnSuggestionsReturned(kQueryId, autofill_item);
236 // Test that datalist values can get updated while a popup is showing.
237 TEST_F(AutofillExternalDelegateUnitTest, UpdateDataListWhileShowingPopup) {
238 IssueOnQuery(kQueryId);
240 EXPECT_CALL(autofill_client_, ShowAutofillPopup(_, _, _, _))
241 .Times(0);
243 // Make sure just setting the data list values doesn't cause the popup to
244 // appear.
245 std::vector<base::string16> data_list_items;
246 data_list_items.push_back(base::string16());
248 EXPECT_CALL(
249 autofill_client_,
250 UpdateAutofillPopupDataListValues(data_list_items, data_list_items));
252 external_delegate_->SetCurrentDataListValues(data_list_items,
253 data_list_items);
255 // The enums must be cast to ints to prevent compile errors on linux_rel.
256 EXPECT_CALL(
257 autofill_client_,
258 ShowAutofillPopup(_,
260 SuggestionVectorIdsAre(testing::ElementsAre(
261 static_cast<int>(POPUP_ITEM_ID_DATALIST_ENTRY),
262 static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
263 kAutofillProfileId,
264 static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
265 static_cast<int>(POPUP_ITEM_ID_AUTOFILL_OPTIONS))),
266 _));
268 // Ensure the popup is displayed.
269 std::vector<Suggestion> autofill_item;
270 autofill_item.push_back(Suggestion());
271 autofill_item[0].frontend_id = kAutofillProfileId;
272 external_delegate_->OnSuggestionsReturned(kQueryId, autofill_item);
274 // This would normally get called from ShowAutofillPopup, but it is mocked so
275 // we need to call OnPopupShown ourselves.
276 external_delegate_->OnPopupShown();
278 // Update the current data list and ensure the popup is updated.
279 data_list_items.push_back(base::string16());
281 // The enums must be cast to ints to prevent compile errors on linux_rel.
282 EXPECT_CALL(
283 autofill_client_,
284 UpdateAutofillPopupDataListValues(data_list_items, data_list_items));
286 external_delegate_->SetCurrentDataListValues(data_list_items,
287 data_list_items);
290 // Test that the Autofill popup is able to display warnings explaining why
291 // Autofill is disabled for a website.
292 // Regression test for http://crbug.com/247880
293 TEST_F(AutofillExternalDelegateUnitTest, AutofillWarnings) {
294 IssueOnQuery(kQueryId);
296 // The enums must be cast to ints to prevent compile errors on linux_rel.
297 EXPECT_CALL(
298 autofill_client_,
299 ShowAutofillPopup(
302 SuggestionVectorIdsAre(testing::ElementsAre(
303 static_cast<int>(POPUP_ITEM_ID_WARNING_MESSAGE))),
304 _));
306 // This should call ShowAutofillPopup.
307 std::vector<Suggestion> autofill_item;
308 autofill_item.push_back(Suggestion());
309 autofill_item[0].frontend_id = POPUP_ITEM_ID_WARNING_MESSAGE;
310 external_delegate_->OnSuggestionsReturned(kQueryId, autofill_item);
313 // Test that the Autofill popup doesn't display a warning explaining why
314 // Autofill is disabled for a website when there are no Autofill suggestions.
315 // Regression test for http://crbug.com/105636
316 TEST_F(AutofillExternalDelegateUnitTest, NoAutofillWarningsWithoutSuggestions) {
317 // This test only makes sense if we're respecting autocomplete="off".
318 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
319 switches::kRespectAutocompleteOffForAutofill))
320 return;
322 const FormData form;
323 FormFieldData field;
324 field.is_focusable = true;
325 field.should_autocomplete = false;
326 const gfx::RectF element_bounds;
328 external_delegate_->OnQuery(kQueryId, form, field, element_bounds, true);
330 EXPECT_CALL(autofill_client_, ShowAutofillPopup(_, _, _, _))
331 .Times(0);
332 EXPECT_CALL(autofill_client_, HideAutofillPopup()).Times(1);
334 // This should not call ShowAutofillPopup.
335 std::vector<Suggestion> autofill_item;
336 autofill_item.push_back(Suggestion());
337 autofill_item[0].frontend_id = POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY;
338 external_delegate_->OnSuggestionsReturned(kQueryId, autofill_item);
341 // Test that the Autofill delegate doesn't try and fill a form with a
342 // negative unique id.
343 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateInvalidUniqueId) {
344 // Ensure it doesn't try to preview the negative id.
345 EXPECT_CALL(*autofill_manager_, FillOrPreviewForm(_, _, _, _, _)).Times(0);
346 EXPECT_CALL(*autofill_driver_, RendererShouldClearPreviewedForm()).Times(1);
347 external_delegate_->DidSelectSuggestion(base::string16(), -1);
349 // Ensure it doesn't try to fill the form in with the negative id.
350 EXPECT_CALL(autofill_client_, HideAutofillPopup());
351 EXPECT_CALL(*autofill_manager_, FillOrPreviewForm(_, _, _, _, _)).Times(0);
352 external_delegate_->DidAcceptSuggestion(base::string16(), -1);
355 // Test that the ClearPreview call is only sent if the form was being previewed
356 // (i.e. it isn't autofilling a password).
357 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateClearPreviewedForm) {
358 // Ensure selecting a new password entries or Autofill entries will
359 // cause any previews to get cleared.
360 EXPECT_CALL(*autofill_driver_, RendererShouldClearPreviewedForm()).Times(1);
361 external_delegate_->DidSelectSuggestion(ASCIIToUTF16("baz foo"),
362 POPUP_ITEM_ID_PASSWORD_ENTRY);
363 EXPECT_CALL(*autofill_driver_, RendererShouldClearPreviewedForm()).Times(1);
364 EXPECT_CALL(*autofill_manager_,
365 FillOrPreviewForm(
366 AutofillDriver::FORM_DATA_ACTION_PREVIEW, _, _, _, _));
367 external_delegate_->DidSelectSuggestion(ASCIIToUTF16("baz foo"), 1);
369 // Ensure selecting an autocomplete entry will cause any previews to
370 // get cleared.
371 EXPECT_CALL(*autofill_driver_, RendererShouldClearPreviewedForm()).Times(1);
372 EXPECT_CALL(*autofill_driver_, RendererShouldPreviewFieldWithValue(
373 ASCIIToUTF16("baz foo")));
374 external_delegate_->DidSelectSuggestion(ASCIIToUTF16("baz foo"),
375 POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY);
378 // Test that the popup is hidden once we are done editing the autofill field.
379 TEST_F(AutofillExternalDelegateUnitTest,
380 ExternalDelegateHidePopupAfterEditing) {
381 EXPECT_CALL(autofill_client_, ShowAutofillPopup(_, _, _, _));
382 autofill::GenerateTestAutofillPopup(external_delegate_.get());
384 EXPECT_CALL(autofill_client_, HideAutofillPopup());
385 external_delegate_->DidEndTextFieldEditing();
388 // Test that the driver is directed to accept the data list after being notified
389 // that the user accepted the data list suggestion.
390 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateAcceptSuggestion) {
391 EXPECT_CALL(autofill_client_, HideAutofillPopup());
392 base::string16 dummy_string(ASCIIToUTF16("baz qux"));
393 EXPECT_CALL(*autofill_driver_,
394 RendererShouldAcceptDataListSuggestion(dummy_string));
395 external_delegate_->DidAcceptSuggestion(dummy_string,
396 POPUP_ITEM_ID_DATALIST_ENTRY);
399 // Test that the driver is directed to clear the form after being notified that
400 // the user accepted the suggestion to clear the form.
401 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateClearForm) {
402 EXPECT_CALL(autofill_client_, HideAutofillPopup());
403 EXPECT_CALL(*autofill_driver_, RendererShouldClearFilledForm());
405 external_delegate_->DidAcceptSuggestion(base::string16(),
406 POPUP_ITEM_ID_CLEAR_FORM);
409 // Test that autofill client will scan a credit card after use accepted the
410 // suggestion to scan a credit card.
411 TEST_F(AutofillExternalDelegateUnitTest, ScanCreditCardMenuItem) {
412 EXPECT_CALL(autofill_client_, ScanCreditCard(_));
413 EXPECT_CALL(autofill_client_, HideAutofillPopup());
414 external_delegate_->DidAcceptSuggestion(base::string16(),
415 POPUP_ITEM_ID_SCAN_CREDIT_CARD);
418 TEST_F(AutofillExternalDelegateUnitTest, ScanCreditCardPromptMetricsTest) {
419 // Log that the scan card item was shown, although nothing was selected.
421 EXPECT_CALL(*autofill_manager_, ShouldShowScanCreditCard(_, _))
422 .WillOnce(testing::Return(true));
423 base::HistogramTester histogram;
424 IssueOnQuery(kQueryId);
425 IssueOnSuggestionsReturned();
426 external_delegate_->OnPopupHidden();
427 histogram.ExpectUniqueSample("Autofill.ScanCreditCardPrompt",
428 AutofillMetrics::SCAN_CARD_ITEM_SHOWN, 1);
430 // Log that the scan card item was selected.
432 EXPECT_CALL(*autofill_manager_, ShouldShowScanCreditCard(_, _))
433 .WillOnce(testing::Return(true));
434 base::HistogramTester histogram;
435 IssueOnQuery(kQueryId);
436 IssueOnSuggestionsReturned();
437 external_delegate_->DidAcceptSuggestion(base::string16(),
438 POPUP_ITEM_ID_SCAN_CREDIT_CARD);
439 histogram.ExpectBucketCount("Autofill.ScanCreditCardPrompt",
440 AutofillMetrics::SCAN_CARD_ITEM_SHOWN, 1);
441 histogram.ExpectBucketCount("Autofill.ScanCreditCardPrompt",
442 AutofillMetrics::SCAN_CARD_ITEM_SELECTED, 1);
443 histogram.ExpectBucketCount("Autofill.ScanCreditCardPrompt",
444 AutofillMetrics::SCAN_CARD_OTHER_ITEM_SELECTED,
447 // Log that something else was selected.
449 EXPECT_CALL(*autofill_manager_, ShouldShowScanCreditCard(_, _))
450 .WillOnce(testing::Return(true));
451 base::HistogramTester histogram;
452 IssueOnQuery(kQueryId);
453 IssueOnSuggestionsReturned();
454 external_delegate_->DidAcceptSuggestion(base::string16(),
455 POPUP_ITEM_ID_CLEAR_FORM);
456 histogram.ExpectBucketCount("Autofill.ScanCreditCardPrompt",
457 AutofillMetrics::SCAN_CARD_ITEM_SHOWN, 1);
458 histogram.ExpectBucketCount("Autofill.ScanCreditCardPrompt",
459 AutofillMetrics::SCAN_CARD_ITEM_SELECTED, 0);
460 histogram.ExpectBucketCount("Autofill.ScanCreditCardPrompt",
461 AutofillMetrics::SCAN_CARD_OTHER_ITEM_SELECTED,
464 // Nothing is logged when the item isn't shown.
466 EXPECT_CALL(*autofill_manager_, ShouldShowScanCreditCard(_, _))
467 .WillOnce(testing::Return(false));
468 base::HistogramTester histogram;
469 IssueOnQuery(kQueryId);
470 IssueOnSuggestionsReturned();
471 external_delegate_->DidAcceptSuggestion(base::string16(),
472 POPUP_ITEM_ID_CLEAR_FORM);
473 histogram.ExpectTotalCount("Autofill.ScanCreditCardPrompt", 0);
477 // Test that autofill manager will fill the credit card form after user scans a
478 // credit card.
479 TEST_F(AutofillExternalDelegateUnitTest, FillCreditCardForm) {
480 base::string16 card_number = base::ASCIIToUTF16("test");
481 int expiration_month = 1;
482 int expiration_year = 3000;
483 EXPECT_CALL(
484 *autofill_manager_,
485 FillCreditCardForm(
486 _, _, _, CreditCard(card_number, expiration_month, expiration_year)));
487 external_delegate_->OnCreditCardScanned(card_number, expiration_month,
488 expiration_year);
491 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateHideWarning) {
492 base::CommandLine::ForCurrentProcess()->AppendSwitch(
493 switches::kRespectAutocompleteOffForAutofill);
495 // Set up a field that shouldn't get autocompleted or display warnings.
496 const FormData form;
497 FormFieldData field;
498 field.is_focusable = true;
499 field.should_autocomplete = false;
500 const gfx::RectF element_bounds;
502 external_delegate_->OnQuery(kQueryId, form, field, element_bounds, false);
504 std::vector<Suggestion> autofill_items;
505 autofill_items.push_back(Suggestion());
506 autofill_items[0].frontend_id = POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY;
508 // Ensure the popup tries to hide itself, since it is not allowed to show
509 // anything.
510 EXPECT_CALL(autofill_client_, HideAutofillPopup());
512 external_delegate_->OnSuggestionsReturned(kQueryId, autofill_items);
515 TEST_F(AutofillExternalDelegateUnitTest, IgnoreAutocompleteOffForAutofill) {
516 const FormData form;
517 FormFieldData field;
518 field.is_focusable = true;
519 field.should_autocomplete = false;
520 const gfx::RectF element_bounds;
522 external_delegate_->OnQuery(kQueryId, form, field, element_bounds, false);
524 std::vector<Suggestion> autofill_items;
525 autofill_items.push_back(Suggestion());
526 autofill_items[0].frontend_id = POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY;
528 // Ensure the popup tries to show itself, despite autocomplete="off".
529 EXPECT_CALL(autofill_client_, ShowAutofillPopup(_, _, _, _));
530 EXPECT_CALL(autofill_client_, HideAutofillPopup()).Times(0);
532 external_delegate_->OnSuggestionsReturned(kQueryId, autofill_items);
535 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateFillFieldWithValue) {
536 EXPECT_CALL(autofill_client_, HideAutofillPopup());
537 base::string16 dummy_string(ASCIIToUTF16("baz foo"));
538 EXPECT_CALL(*autofill_driver_,
539 RendererShouldFillFieldWithValue(dummy_string));
540 external_delegate_->DidAcceptSuggestion(dummy_string,
541 POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY);
544 } // namespace autofill