autofill_dialog_controller_browsertest.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1// Copyright (c) 2012 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 "base/bind.h"
6#include "base/command_line.h"
7#include "base/memory/ref_counted.h"
8#include "base/memory/weak_ptr.h"
9#include "base/message_loop/message_loop.h"
10#include "base/prefs/pref_service.h"
11#include "base/strings/utf_string_conversions.h"
12#include "base/time/time.h"
13#include "chrome/browser/autofill/personal_data_manager_factory.h"
14#include "chrome/browser/profiles/profile.h"
15#include "chrome/browser/ui/autofill/account_chooser_model.h"
16#include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h"
17#include "chrome/browser/ui/autofill/autofill_dialog_view.h"
18#include "chrome/browser/ui/autofill/data_model_wrapper.h"
19#include "chrome/browser/ui/autofill/tab_autofill_manager_delegate.h"
20#include "chrome/browser/ui/autofill/test_generated_credit_card_bubble_controller.h"
21#include "chrome/browser/ui/autofill/testable_autofill_dialog_view.h"
22#include "chrome/browser/ui/browser.h"
23#include "chrome/browser/ui/browser_tabstrip.h"
24#include "chrome/browser/ui/tabs/tab_strip_model.h"
25#include "chrome/common/pref_names.h"
26#include "chrome/common/url_constants.h"
27#include "chrome/test/base/in_process_browser_test.h"
28#include "chrome/test/base/ui_test_utils.h"
29#include "components/autofill/content/browser/risk/proto/fingerprint.pb.h"
30#include "components/autofill/content/browser/wallet/mock_wallet_client.h"
31#include "components/autofill/content/browser/wallet/wallet_test_util.h"
32#include "components/autofill/core/browser/autofill_metrics.h"
33#include "components/autofill/core/browser/autofill_test_utils.h"
34#include "components/autofill/core/browser/test_personal_data_manager.h"
35#include "components/autofill/core/browser/validation.h"
36#include "components/autofill/core/common/autofill_switches.h"
37#include "components/autofill/core/common/form_data.h"
38#include "components/autofill/core/common/form_field_data.h"
39#include "content/public/browser/browser_thread.h"
40#include "content/public/browser/navigation_details.h"
41#include "content/public/browser/navigation_entry.h"
42#include "content/public/browser/notification_service.h"
43#include "content/public/browser/notification_types.h"
44#include "content/public/browser/web_contents.h"
45#include "content/public/browser/web_contents_delegate.h"
46#include "content/public/common/url_constants.h"
47#include "content/public/test/browser_test_utils.h"
48#include "content/public/test/test_utils.h"
49#include "google_apis/gaia/google_service_auth_error.h"
50#include "testing/gmock/include/gmock/gmock.h"
51#include "testing/gtest/include/gtest/gtest.h"
52#include "third_party/WebKit/public/web/WebInputEvent.h"
53#include "url/gurl.h"
54
55namespace autofill {
56
57namespace {
58
59using testing::_;
60
61void MockCallback(const FormStructure*) {}
62
63class MockAutofillMetrics : public AutofillMetrics {
64 public:
65  MockAutofillMetrics()
66      : dialog_dismissal_action_(
67            static_cast<AutofillMetrics::DialogDismissalAction>(-1)) {}
68  virtual ~MockAutofillMetrics() {}
69
70  virtual void LogDialogUiDuration(
71      const base::TimeDelta& duration,
72      DialogDismissalAction dismissal_action) const OVERRIDE {
73    // Ignore constness for testing.
74    MockAutofillMetrics* mutable_this = const_cast<MockAutofillMetrics*>(this);
75    mutable_this->dialog_dismissal_action_ = dismissal_action;
76  }
77
78  AutofillMetrics::DialogDismissalAction dialog_dismissal_action() const {
79    return dialog_dismissal_action_;
80  }
81
82  MOCK_CONST_METHOD1(LogDialogDismissalState,
83                     void(DialogDismissalState state));
84
85 private:
86  AutofillMetrics::DialogDismissalAction dialog_dismissal_action_;
87
88  DISALLOW_COPY_AND_ASSIGN(MockAutofillMetrics);
89};
90
91class TestAutofillDialogController : public AutofillDialogControllerImpl {
92 public:
93  TestAutofillDialogController(
94      content::WebContents* contents,
95      const FormData& form_data,
96      const AutofillMetrics& metric_logger,
97      scoped_refptr<content::MessageLoopRunner> runner)
98      : AutofillDialogControllerImpl(contents,
99                                     form_data,
100                                     form_data.origin,
101                                     base::Bind(&MockCallback)),
102        metric_logger_(metric_logger),
103        mock_wallet_client_(
104            Profile::FromBrowserContext(contents->GetBrowserContext())->
105                GetRequestContext(), this, form_data.origin),
106        message_loop_runner_(runner),
107        use_validation_(false),
108        weak_ptr_factory_(this),
109        sign_in_user_index_(0U) {}
110
111  virtual ~TestAutofillDialogController() {}
112
113  virtual GURL SignInUrl() const OVERRIDE {
114    return GURL(chrome::kChromeUIVersionURL);
115  }
116
117  GURL SignInContinueUrl() const {
118    return GURL(content::kAboutBlankURL);
119  }
120
121  virtual void ViewClosed() OVERRIDE {
122    message_loop_runner_->Quit();
123    AutofillDialogControllerImpl::ViewClosed();
124  }
125
126  virtual base::string16 InputValidityMessage(
127      DialogSection section,
128      ServerFieldType type,
129      const base::string16& value) OVERRIDE {
130    if (!use_validation_)
131      return base::string16();
132    return AutofillDialogControllerImpl::InputValidityMessage(
133        section, type, value);
134  }
135
136  virtual ValidityMessages InputsAreValid(
137      DialogSection section,
138      const FieldValueMap& inputs) OVERRIDE {
139    if (!use_validation_)
140      return ValidityMessages();
141    return AutofillDialogControllerImpl::InputsAreValid(section, inputs);
142  }
143
144  // Saving to Chrome is tested in AutofillDialogControllerImpl unit tests.
145  // TODO(estade): test that the view defaults to saving to Chrome.
146  virtual bool ShouldOfferToSaveInChrome() const OVERRIDE {
147    return false;
148  }
149
150  void ForceFinishSubmit() {
151    DoFinishSubmit();
152  }
153
154  // Increase visibility for testing.
155  using AutofillDialogControllerImpl::view;
156  using AutofillDialogControllerImpl::input_showing_popup;
157
158  MOCK_METHOD0(LoadRiskFingerprintData, void());
159
160  virtual std::vector<DialogNotification> CurrentNotifications() OVERRIDE {
161    return notifications_;
162  }
163
164  void set_notifications(const std::vector<DialogNotification>& notifications) {
165    notifications_ = notifications;
166  }
167
168  TestPersonalDataManager* GetTestingManager() {
169    return &test_manager_;
170  }
171
172  using AutofillDialogControllerImpl::IsEditingExistingData;
173  using AutofillDialogControllerImpl::IsPayingWithWallet;
174  using AutofillDialogControllerImpl::IsSubmitPausedOn;
175  using AutofillDialogControllerImpl::OnDidLoadRiskFingerprintData;
176  using AutofillDialogControllerImpl::AccountChooserModelForTesting;
177
178  void set_use_validation(bool use_validation) {
179    use_validation_ = use_validation;
180  }
181
182  base::WeakPtr<TestAutofillDialogController> AsWeakPtr() {
183    return weak_ptr_factory_.GetWeakPtr();
184  }
185
186  wallet::MockWalletClient* GetTestingWalletClient() {
187    return &mock_wallet_client_;
188  }
189
190  void set_sign_in_user_index(size_t sign_in_user_index) {
191    sign_in_user_index_ = sign_in_user_index;
192  }
193
194 protected:
195  virtual PersonalDataManager* GetManager() const OVERRIDE {
196    return &const_cast<TestAutofillDialogController*>(this)->test_manager_;
197  }
198
199  virtual wallet::WalletClient* GetWalletClient() OVERRIDE {
200    return &mock_wallet_client_;
201  }
202
203  virtual bool IsSignInContinueUrl(const GURL& url, size_t* user_index) const
204      OVERRIDE {
205    *user_index = sign_in_user_index_;
206    return url == SignInContinueUrl();
207  }
208
209 private:
210  // To specify our own metric logger.
211  virtual const AutofillMetrics& GetMetricLogger() const OVERRIDE {
212    return metric_logger_;
213  }
214
215  const AutofillMetrics& metric_logger_;
216  TestPersonalDataManager test_manager_;
217  testing::NiceMock<wallet::MockWalletClient> mock_wallet_client_;
218  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
219  bool use_validation_;
220
221  // A list of notifications to show in the notification area of the dialog.
222  // This is used to control what |CurrentNotifications()| returns for testing.
223  std::vector<DialogNotification> notifications_;
224
225  // Allows generation of WeakPtrs, so controller liveness can be tested.
226  base::WeakPtrFactory<TestAutofillDialogController> weak_ptr_factory_;
227
228  // The user index that is assigned in IsSignInContinueUrl().
229  size_t sign_in_user_index_;
230
231  DISALLOW_COPY_AND_ASSIGN(TestAutofillDialogController);
232};
233
234// This is a copy of ui_test_utils::UrlLoadObserver, except it observes
235// NAV_ENTRY_COMMITTED instead of LOAD_STOP. This is to match the notification
236// that AutofillDialogControllerImpl observes. Since NAV_ENTRY_COMMITTED comes
237// before LOAD_STOP, and the controller deletes the web contents after receiving
238// the former, we will sometimes fail to observe a LOAD_STOP.
239// TODO(estade): Should the controller observe LOAD_STOP instead?
240class NavEntryCommittedObserver : public content::WindowedNotificationObserver {
241 public:
242  NavEntryCommittedObserver(const GURL& url,
243                            const content::NotificationSource& source)
244    : WindowedNotificationObserver(content::NOTIFICATION_NAV_ENTRY_COMMITTED,
245                                   source),
246      url_(url) {}
247
248  virtual ~NavEntryCommittedObserver() {}
249
250  // content::NotificationObserver:
251  virtual void Observe(int type,
252                       const content::NotificationSource& source,
253                       const content::NotificationDetails& details) OVERRIDE {
254    content::LoadCommittedDetails* load_details =
255        content::Details<content::LoadCommittedDetails>(details).ptr();
256    if (load_details->entry->GetVirtualURL() != url_)
257      return;
258
259    WindowedNotificationObserver::Observe(type, source, details);
260  }
261
262 private:
263  GURL url_;
264
265  DISALLOW_COPY_AND_ASSIGN(NavEntryCommittedObserver);
266};
267
268}  // namespace
269
270class AutofillDialogControllerTest : public InProcessBrowserTest {
271 public:
272  AutofillDialogControllerTest() {}
273  virtual ~AutofillDialogControllerTest() {}
274
275  virtual void SetUpOnMainThread() OVERRIDE {
276    autofill::test::DisableSystemServices(browser()->profile());
277    InitializeController();
278  }
279
280  void InitializeController() {
281    FormData form;
282    form.name = ASCIIToUTF16("TestForm");
283    form.method = ASCIIToUTF16("POST");
284    form.origin = GURL("http://example.com/form.html");
285    form.action = GURL("http://example.com/submit.html");
286    form.user_submitted = true;
287
288    FormFieldData field;
289    field.autocomplete_attribute = "shipping tel";
290    form.fields.push_back(field);
291
292    test_generated_bubble_controller_ =
293        new testing::NiceMock<TestGeneratedCreditCardBubbleController>(
294            GetActiveWebContents());
295    ASSERT_TRUE(test_generated_bubble_controller_->IsInstalled());
296
297    message_loop_runner_ = new content::MessageLoopRunner;
298    controller_ = new TestAutofillDialogController(
299        GetActiveWebContents(),
300        form,
301        metric_logger_,
302        message_loop_runner_);
303    controller_->Show();
304  }
305
306  content::WebContents* GetActiveWebContents() {
307    return browser()->tab_strip_model()->GetActiveWebContents();
308  }
309
310  const MockAutofillMetrics& metric_logger() { return metric_logger_; }
311  TestAutofillDialogController* controller() { return controller_; }
312
313  void RunMessageLoop() {
314    message_loop_runner_->Run();
315  }
316
317  // Loads an HTML page in |GetActiveWebContents()| with markup as follows:
318  // <form>|form_inner_html|</form>. After loading, emulates a click event on
319  // the page as requestAutocomplete() must be in response to a user gesture.
320  // Returns the |AutofillDialogControllerImpl| created by this invocation.
321  AutofillDialogControllerImpl* SetUpHtmlAndInvoke(
322      const std::string& form_inner_html) {
323    content::WebContents* contents = GetActiveWebContents();
324    TabAutofillManagerDelegate* delegate =
325        TabAutofillManagerDelegate::FromWebContents(contents);
326    DCHECK(!delegate->GetDialogControllerForTesting());
327
328    ui_test_utils::NavigateToURL(
329        browser(), GURL(std::string("data:text/html,") +
330        "<!doctype html>"
331        "<html>"
332          "<body>"
333            "<form>" + form_inner_html + "</form>"
334            "<script>"
335              "function send(msg) {"
336                "domAutomationController.setAutomationId(0);"
337                "domAutomationController.send(msg);"
338              "}"
339              "document.forms[0].onautocompleteerror = function(e) {"
340                "send('error: ' + e.reason);"
341              "};"
342              "document.forms[0].onautocomplete = function() {"
343                "send('success');"
344              "};"
345              "window.onclick = function() {"
346                "document.forms[0].requestAutocomplete();"
347                "send('clicked');"
348              "};"
349              "function getValueForFieldOfType(type) {"
350              "  var fields = document.getElementsByTagName('input');"
351              "  for (var i = 0; i < fields.length; i++) {"
352              "    if (fields[i].autocomplete == type) {"
353              "      send(fields[i].value);"
354              "      return;"
355              "    }"
356              "  }"
357              "  send('');"
358              "};"
359            "</script>"
360          "</body>"
361        "</html>"));
362
363    dom_message_queue_.reset(new content::DOMMessageQueue);
364
365    // Triggers the onclick handler which invokes requestAutocomplete().
366    content::SimulateMouseClick(contents, 0, blink::WebMouseEvent::ButtonLeft);
367    ExpectDomMessage("clicked");
368
369    AutofillDialogControllerImpl* controller =
370        static_cast<AutofillDialogControllerImpl*>(
371            delegate->GetDialogControllerForTesting());
372    DCHECK(controller);
373    return controller;
374  }
375
376  // Wait for a message from the DOM automation controller (from JS in the
377  // page). Requires |SetUpHtmlAndInvoke()| be called first.
378  void ExpectDomMessage(const std::string& expected) {
379    std::string message;
380    ASSERT_TRUE(dom_message_queue_->WaitForMessage(&message));
381    dom_message_queue_->ClearQueue();
382    EXPECT_EQ("\"" + expected + "\"", message);
383  }
384
385  // Returns the value filled into the first field with autocomplete attribute
386  // equal to |autocomplete_type|, or an empty string if there is no such field.
387  std::string GetValueForHTMLFieldOfType(const std::string& autocomplete_type) {
388    content::RenderViewHost* render_view_host =
389        browser()->tab_strip_model()->GetActiveWebContents()->
390        GetRenderViewHost();
391    std::string script = "getValueForFieldOfType('" + autocomplete_type + "');";
392    std::string result;
393    EXPECT_TRUE(content::ExecuteScriptAndExtractString(render_view_host, script,
394                                                       &result));
395    return result;
396  }
397
398  void AddCreditcardToProfile(Profile* profile, const CreditCard& card) {
399    PersonalDataManagerFactory::GetForProfile(profile)->AddCreditCard(card);
400    WaitForWebDB();
401  }
402
403  void AddAutofillProfileToProfile(Profile* profile,
404                                   const AutofillProfile& autofill_profile) {
405    PersonalDataManagerFactory::GetForProfile(profile)->AddProfile(
406        autofill_profile);
407    WaitForWebDB();
408  }
409
410  TestGeneratedCreditCardBubbleController* test_generated_bubble_controller() {
411    return test_generated_bubble_controller_;
412  }
413
414 private:
415  void WaitForWebDB() {
416    content::RunAllPendingInMessageLoop(content::BrowserThread::DB);
417  }
418
419  testing::NiceMock<MockAutofillMetrics> metric_logger_;
420  TestAutofillDialogController* controller_;  // Weak reference.
421  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
422  scoped_ptr<content::DOMMessageQueue> dom_message_queue_;
423
424  // Weak; owned by the active web contents.
425  TestGeneratedCreditCardBubbleController* test_generated_bubble_controller_;
426
427  DISALLOW_COPY_AND_ASSIGN(AutofillDialogControllerTest);
428};
429
430#if defined(TOOLKIT_VIEWS) || defined(OS_MACOSX)
431// Submit the form data.
432IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, Submit) {
433  controller()->GetTestableView()->SubmitForTesting();
434
435  RunMessageLoop();
436
437  EXPECT_EQ(AutofillMetrics::DIALOG_ACCEPTED,
438            metric_logger().dialog_dismissal_action());
439}
440
441// Cancel out of the dialog.
442IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, Cancel) {
443  controller()->GetTestableView()->CancelForTesting();
444
445  RunMessageLoop();
446
447  EXPECT_EQ(AutofillMetrics::DIALOG_CANCELED,
448            metric_logger().dialog_dismissal_action());
449}
450
451// Take some other action that dismisses the dialog.
452IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, Hide) {
453  controller()->Hide();
454
455  RunMessageLoop();
456
457  EXPECT_EQ(AutofillMetrics::DIALOG_CANCELED,
458            metric_logger().dialog_dismissal_action());
459}
460
461// Ensure that Hide() will only destroy the controller object after the
462// message loop has run. Otherwise, there may be read-after-free issues
463// during some tests.
464IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, DeferredDestruction) {
465  base::WeakPtr<TestAutofillDialogController> weak_ptr =
466      controller()->AsWeakPtr();
467  EXPECT_TRUE(weak_ptr.get());
468
469  controller()->Hide();
470  EXPECT_TRUE(weak_ptr.get());
471
472  RunMessageLoop();
473  EXPECT_FALSE(weak_ptr.get());
474}
475
476// Ensure that the expected metric is logged when the dialog is closed during
477// signin.
478IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, CloseDuringSignin) {
479  controller()->SignInLinkClicked();
480
481  EXPECT_CALL(metric_logger(),
482              LogDialogDismissalState(
483                  AutofillMetrics::DIALOG_CANCELED_DURING_SIGNIN));
484  controller()->GetTestableView()->CancelForTesting();
485
486  RunMessageLoop();
487
488  EXPECT_EQ(AutofillMetrics::DIALOG_CANCELED,
489            metric_logger().dialog_dismissal_action());
490}
491
492IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, FillInputFromAutofill) {
493  AutofillProfile full_profile(test::GetFullProfile());
494  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
495
496  const DetailInputs& inputs =
497      controller()->RequestedFieldsForSection(SECTION_SHIPPING);
498  const DetailInput& triggering_input = inputs[0];
499  base::string16 value = full_profile.GetRawInfo(triggering_input.type);
500  TestableAutofillDialogView* view = controller()->GetTestableView();
501  view->SetTextContentsOfInput(triggering_input,
502                               value.substr(0, value.size() / 2));
503  view->ActivateInput(triggering_input);
504
505  ASSERT_EQ(&triggering_input, controller()->input_showing_popup());
506  controller()->DidAcceptSuggestion(string16(), 0);
507
508  // All inputs should be filled.
509  AutofillProfileWrapper wrapper(&full_profile);
510  for (size_t i = 0; i < inputs.size(); ++i) {
511    EXPECT_EQ(wrapper.GetInfo(AutofillType(inputs[i].type)),
512              view->GetTextContentsOfInput(inputs[i]));
513  }
514
515  // Now simulate some user edits and try again.
516  std::vector<string16> expectations;
517  for (size_t i = 0; i < inputs.size(); ++i) {
518    base::string16 users_input = i % 2 == 0 ? base::string16()
519                                            : ASCIIToUTF16("dummy");
520    view->SetTextContentsOfInput(inputs[i], users_input);
521    // Empty inputs should be filled, others should be left alone.
522    base::string16 expectation =
523        &inputs[i] == &triggering_input || users_input.empty() ?
524        wrapper.GetInfo(AutofillType(inputs[i].type)) :
525        users_input;
526    expectations.push_back(expectation);
527  }
528
529  view->SetTextContentsOfInput(triggering_input,
530                               value.substr(0, value.size() / 2));
531  view->ActivateInput(triggering_input);
532  ASSERT_EQ(&triggering_input, controller()->input_showing_popup());
533  controller()->DidAcceptSuggestion(string16(), 0);
534
535  for (size_t i = 0; i < inputs.size(); ++i) {
536    EXPECT_EQ(expectations[i], view->GetTextContentsOfInput(inputs[i]));
537  }
538}
539
540// For now, no matter what, the country must always be US. See
541// http://crbug.com/247518
542IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
543                       FillInputFromForeignProfile) {
544  AutofillProfile full_profile(test::GetFullProfile());
545  full_profile.SetInfo(AutofillType(ADDRESS_HOME_COUNTRY),
546                       ASCIIToUTF16("France"), "en-US");
547  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
548
549  const DetailInputs& inputs =
550      controller()->RequestedFieldsForSection(SECTION_SHIPPING);
551  const DetailInput& triggering_input = inputs[0];
552  base::string16 value = full_profile.GetRawInfo(triggering_input.type);
553  TestableAutofillDialogView* view = controller()->GetTestableView();
554  view->SetTextContentsOfInput(triggering_input,
555                               value.substr(0, value.size() / 2));
556  view->ActivateInput(triggering_input);
557
558  ASSERT_EQ(&triggering_input, controller()->input_showing_popup());
559  controller()->DidAcceptSuggestion(string16(), 0);
560
561  // All inputs should be filled.
562  AutofillProfileWrapper wrapper(&full_profile);
563  for (size_t i = 0; i < inputs.size(); ++i) {
564    base::string16 expectation =
565        AutofillType(inputs[i].type).GetStorableType() == ADDRESS_HOME_COUNTRY ?
566        ASCIIToUTF16("United States") :
567        wrapper.GetInfo(AutofillType(inputs[i].type));
568    EXPECT_EQ(expectation, view->GetTextContentsOfInput(inputs[i]));
569  }
570
571  // Now simulate some user edits and try again.
572  std::vector<string16> expectations;
573  for (size_t i = 0; i < inputs.size(); ++i) {
574    base::string16 users_input = i % 2 == 0 ? base::string16()
575                                            : ASCIIToUTF16("dummy");
576    view->SetTextContentsOfInput(inputs[i], users_input);
577    // Empty inputs should be filled, others should be left alone.
578    base::string16 expectation =
579        &inputs[i] == &triggering_input || users_input.empty() ?
580        wrapper.GetInfo(AutofillType(inputs[i].type)) :
581        users_input;
582    if (AutofillType(inputs[i].type).GetStorableType() == ADDRESS_HOME_COUNTRY)
583      expectation = ASCIIToUTF16("United States");
584
585    expectations.push_back(expectation);
586  }
587
588  view->SetTextContentsOfInput(triggering_input,
589                               value.substr(0, value.size() / 2));
590  view->ActivateInput(triggering_input);
591  ASSERT_EQ(&triggering_input, controller()->input_showing_popup());
592  controller()->DidAcceptSuggestion(string16(), 0);
593
594  for (size_t i = 0; i < inputs.size(); ++i) {
595    EXPECT_EQ(expectations[i], view->GetTextContentsOfInput(inputs[i]));
596  }
597}
598
599// This test makes sure that picking a profile variant in the Autofill
600// popup works as expected.
601IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
602                       FillInputFromAutofillVariant) {
603  AutofillProfile full_profile(test::GetFullProfile());
604
605  // Set up some variant data.
606  std::vector<string16> names;
607  names.push_back(ASCIIToUTF16("John Doe"));
608  names.push_back(ASCIIToUTF16("Jane Doe"));
609  full_profile.SetRawMultiInfo(NAME_FULL, names);
610  std::vector<string16> emails;
611  emails.push_back(ASCIIToUTF16("user@example.com"));
612  emails.push_back(ASCIIToUTF16("admin@example.com"));
613  full_profile.SetRawMultiInfo(EMAIL_ADDRESS, emails);
614  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
615
616  const DetailInputs& inputs =
617      controller()->RequestedFieldsForSection(SECTION_BILLING);
618  const DetailInput& triggering_input = inputs[0];
619  EXPECT_EQ(NAME_BILLING_FULL, triggering_input.type);
620  TestableAutofillDialogView* view = controller()->GetTestableView();
621  view->ActivateInput(triggering_input);
622
623  ASSERT_EQ(&triggering_input, controller()->input_showing_popup());
624
625  // Choose the variant suggestion.
626  controller()->DidAcceptSuggestion(string16(), 1);
627
628  // All inputs should be filled.
629  AutofillProfileWrapper wrapper(
630      &full_profile, AutofillType(NAME_BILLING_FULL), 1);
631  for (size_t i = 0; i < inputs.size(); ++i) {
632    EXPECT_EQ(wrapper.GetInfo(AutofillType(inputs[i].type)),
633              view->GetTextContentsOfInput(inputs[i]));
634  }
635
636  // Make sure the wrapper applies the variant index to the right group.
637  EXPECT_EQ(names[1], wrapper.GetInfo(AutofillType(NAME_BILLING_FULL)));
638  // Make sure the wrapper doesn't apply the variant index to the wrong group.
639  EXPECT_EQ(emails[0], wrapper.GetInfo(AutofillType(EMAIL_ADDRESS)));
640}
641
642// Tests that changing the value of a CC expiration date combobox works as
643// expected when Autofill is used to fill text inputs.
644//
645// Flaky on Win7, WinXP, and Win Aura.  http://crbug.com/270314.
646#if defined(OS_WIN)
647#define MAYBE_FillComboboxFromAutofill DISABLED_FillComboboxFromAutofill
648#else
649#define MAYBE_FillComboboxFromAutofill FillComboboxFromAutofill
650#endif
651IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
652                       MAYBE_FillComboboxFromAutofill) {
653  CreditCard card1;
654  test::SetCreditCardInfo(&card1, "JJ Smith", "4111111111111111", "12", "2018");
655  controller()->GetTestingManager()->AddTestingCreditCard(&card1);
656  CreditCard card2;
657  test::SetCreditCardInfo(&card2, "B Bird", "3111111111111111", "11", "2017");
658  controller()->GetTestingManager()->AddTestingCreditCard(&card2);
659  AutofillProfile full_profile(test::GetFullProfile());
660  controller()->GetTestingManager()->AddTestingProfile(&full_profile);
661
662  const DetailInputs& inputs =
663      controller()->RequestedFieldsForSection(SECTION_CC);
664  const DetailInput& triggering_input = inputs[0];
665  base::string16 value = card1.GetRawInfo(triggering_input.type);
666  TestableAutofillDialogView* view = controller()->GetTestableView();
667  view->SetTextContentsOfInput(triggering_input,
668                               value.substr(0, value.size() / 2));
669  view->ActivateInput(triggering_input);
670
671  ASSERT_EQ(&triggering_input, controller()->input_showing_popup());
672  controller()->DidAcceptSuggestion(string16(), 0);
673
674  // All inputs should be filled.
675  AutofillCreditCardWrapper wrapper1(&card1);
676  for (size_t i = 0; i < inputs.size(); ++i) {
677    EXPECT_EQ(wrapper1.GetInfo(AutofillType(inputs[i].type)),
678              view->GetTextContentsOfInput(inputs[i]));
679  }
680
681  // Try again with different data. Only expiration date and the triggering
682  // input should be overwritten.
683  value = card2.GetRawInfo(triggering_input.type);
684  view->SetTextContentsOfInput(triggering_input,
685                               value.substr(0, value.size() / 2));
686  view->ActivateInput(triggering_input);
687  ASSERT_EQ(&triggering_input, controller()->input_showing_popup());
688  controller()->DidAcceptSuggestion(string16(), 0);
689
690  AutofillCreditCardWrapper wrapper2(&card2);
691  for (size_t i = 0; i < inputs.size(); ++i) {
692    const DetailInput& input = inputs[i];
693    if (&input == &triggering_input ||
694        input.type == CREDIT_CARD_EXP_MONTH ||
695        input.type == CREDIT_CARD_EXP_4_DIGIT_YEAR) {
696      EXPECT_EQ(wrapper2.GetInfo(AutofillType(input.type)),
697                view->GetTextContentsOfInput(input));
698    } else if (input.type == CREDIT_CARD_VERIFICATION_CODE) {
699      EXPECT_TRUE(view->GetTextContentsOfInput(input).empty());
700    } else {
701      EXPECT_EQ(wrapper1.GetInfo(AutofillType(input.type)),
702                view->GetTextContentsOfInput(input));
703    }
704  }
705
706  // Now fill from a profile. It should not overwrite any CC info.
707  const DetailInputs& billing_inputs =
708      controller()->RequestedFieldsForSection(SECTION_BILLING);
709  const DetailInput& billing_triggering_input = billing_inputs[0];
710  value = full_profile.GetRawInfo(triggering_input.type);
711  view->SetTextContentsOfInput(billing_triggering_input,
712                               value.substr(0, value.size() / 2));
713  view->ActivateInput(billing_triggering_input);
714
715  ASSERT_EQ(&billing_triggering_input, controller()->input_showing_popup());
716  controller()->DidAcceptSuggestion(string16(), 0);
717
718  for (size_t i = 0; i < inputs.size(); ++i) {
719    const DetailInput& input = inputs[i];
720    if (&input == &triggering_input ||
721        input.type == CREDIT_CARD_EXP_MONTH ||
722        input.type == CREDIT_CARD_EXP_4_DIGIT_YEAR) {
723      EXPECT_EQ(wrapper2.GetInfo(AutofillType(input.type)),
724                view->GetTextContentsOfInput(input));
725    } else if (input.type == CREDIT_CARD_VERIFICATION_CODE) {
726      EXPECT_TRUE(view->GetTextContentsOfInput(input).empty());
727    } else {
728      EXPECT_EQ(wrapper1.GetInfo(AutofillType(input.type)),
729                view->GetTextContentsOfInput(input));
730    }
731  }
732}
733
734IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, ShouldShowErrorBubble) {
735  EXPECT_TRUE(controller()->ShouldShowErrorBubble());
736
737  CreditCard card(test::GetCreditCard());
738  ASSERT_FALSE(card.IsVerified());
739  controller()->GetTestingManager()->AddTestingCreditCard(&card);
740
741  const DetailInputs& cc_inputs =
742      controller()->RequestedFieldsForSection(SECTION_CC);
743  const DetailInput& cc_number_input = cc_inputs[0];
744  ASSERT_EQ(CREDIT_CARD_NUMBER, cc_number_input.type);
745
746  TestableAutofillDialogView* view = controller()->GetTestableView();
747  view->SetTextContentsOfInput(
748      cc_number_input,
749      card.GetRawInfo(CREDIT_CARD_NUMBER).substr(0, 1));
750
751  view->ActivateInput(cc_number_input);
752  EXPECT_FALSE(controller()->ShouldShowErrorBubble());
753
754  controller()->FocusMoved();
755  EXPECT_TRUE(controller()->ShouldShowErrorBubble());
756}
757
758// Ensure that expired cards trigger invalid suggestions.
759IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, ExpiredCard) {
760  CreditCard verified_card(test::GetCreditCard());
761  verified_card.set_origin("Chrome settings");
762  ASSERT_TRUE(verified_card.IsVerified());
763  controller()->GetTestingManager()->AddTestingCreditCard(&verified_card);
764
765  CreditCard expired_card(test::GetCreditCard());
766  expired_card.set_origin("Chrome settings");
767  expired_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2007"));
768  ASSERT_TRUE(expired_card.IsVerified());
769  ASSERT_FALSE(
770      autofill::IsValidCreditCardExpirationDate(
771          expired_card.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR),
772          expired_card.GetRawInfo(CREDIT_CARD_EXP_MONTH),
773          base::Time::Now()));
774  controller()->GetTestingManager()->AddTestingCreditCard(&expired_card);
775
776  ui::MenuModel* model = controller()->MenuModelForSection(SECTION_CC);
777  ASSERT_EQ(4, model->GetItemCount());
778
779  ASSERT_TRUE(model->IsItemCheckedAt(0));
780  EXPECT_FALSE(controller()->IsEditingExistingData(SECTION_CC));
781
782  model->ActivatedAt(1);
783  ASSERT_TRUE(model->IsItemCheckedAt(1));
784  EXPECT_TRUE(controller()->IsEditingExistingData(SECTION_CC));
785}
786
787// Notifications with long message text should not make the dialog bigger.
788IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, LongNotifications) {
789  const gfx::Size no_notification_size =
790      controller()->GetTestableView()->GetSize();
791  ASSERT_GT(no_notification_size.width(), 0);
792
793  std::vector<DialogNotification> notifications;
794  notifications.push_back(
795      DialogNotification(DialogNotification::DEVELOPER_WARNING, ASCIIToUTF16(
796          "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do "
797          "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim "
798          "ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut "
799          "aliquip ex ea commodo consequat. Duis aute irure dolor in "
800          "reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla "
801          "pariatur. Excepteur sint occaecat cupidatat non proident, sunt in "
802          "culpa qui officia deserunt mollit anim id est laborum.")));
803  controller()->set_notifications(notifications);
804  controller()->view()->UpdateNotificationArea();
805
806  EXPECT_EQ(no_notification_size.width(),
807            controller()->GetTestableView()->GetSize().width());
808}
809
810// http://crbug.com/318526
811#if defined(OS_MACOSX)
812#define MAYBE_AutocompleteEvent DISABLED_AutocompleteEvent
813#else
814#define MAYBE_AutocompleteEvent AutocompleteEvent
815#endif
816IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, MAYBE_AutocompleteEvent) {
817  AutofillDialogControllerImpl* controller =
818      SetUpHtmlAndInvoke("<input autocomplete='cc-name'>");
819
820  AddCreditcardToProfile(controller->profile(), test::GetVerifiedCreditCard());
821  AddAutofillProfileToProfile(controller->profile(),
822                              test::GetVerifiedProfile());
823
824  TestableAutofillDialogView* view = controller->GetTestableView();
825  view->SetTextContentsOfSuggestionInput(SECTION_CC, ASCIIToUTF16("123"));
826  view->SubmitForTesting();
827  ExpectDomMessage("success");
828}
829
830// http://crbug.com/318526
831#if defined(OS_MACOSX)
832#define MAYBE_AutocompleteErrorEventReasonInvalid \
833    DISABLED_AutocompleteErrorEventReasonInvalid
834#else
835#define MAYBE_AutocompleteErrorEventReasonInvalid \
836    AutocompleteErrorEventReasonInvalid
837#endif
838IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
839                       MAYBE_AutocompleteErrorEventReasonInvalid) {
840  AutofillDialogControllerImpl* controller =
841      SetUpHtmlAndInvoke("<input autocomplete='cc-name' pattern='.*zebra.*'>");
842
843  const CreditCard& credit_card = test::GetVerifiedCreditCard();
844  ASSERT_TRUE(
845    credit_card.GetRawInfo(CREDIT_CARD_NAME).find(ASCIIToUTF16("zebra")) ==
846        base::string16::npos);
847  AddCreditcardToProfile(controller->profile(), credit_card);
848  AddAutofillProfileToProfile(controller->profile(),
849                              test::GetVerifiedProfile());
850
851  TestableAutofillDialogView* view = controller->GetTestableView();
852  view->SetTextContentsOfSuggestionInput(SECTION_CC, ASCIIToUTF16("123"));
853  view->SubmitForTesting();
854  ExpectDomMessage("error: invalid");
855}
856
857// http://crbug.com/318526
858#if defined(OS_MACOSX)
859#define MAYBE_AutocompleteErrorEventReasonCancel \
860    DISABLED_AutocompleteErrorEventReasonCancel
861#else
862#define MAYBE_AutocompleteErrorEventReasonCancel \
863    AutocompleteErrorEventReasonCancel
864#endif
865IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
866                       MAYBE_AutocompleteErrorEventReasonCancel) {
867  SetUpHtmlAndInvoke("<input autocomplete='cc-name'>")->GetTestableView()->
868      CancelForTesting();
869  ExpectDomMessage("error: cancel");
870}
871
872IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, NoCvcSegfault) {
873  controller()->set_use_validation(true);
874
875  CreditCard credit_card(test::GetVerifiedCreditCard());
876  controller()->GetTestingManager()->AddTestingCreditCard(&credit_card);
877  EXPECT_FALSE(controller()->IsEditingExistingData(SECTION_CC));
878
879  ASSERT_NO_FATAL_FAILURE(
880      controller()->GetTestableView()->SubmitForTesting());
881}
882
883// Flaky on Win7, WinXP, and Win Aura.  http://crbug.com/270314.
884#if defined(OS_WIN)
885#define MAYBE_PreservedSections DISABLED_PreservedSections
886#else
887#define MAYBE_PreservedSections PreservedSections
888#endif
889IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, MAYBE_PreservedSections) {
890  controller()->set_use_validation(true);
891
892  TestableAutofillDialogView* view = controller()->GetTestableView();
893
894  {
895    // Create some valid inputted billing data.
896    const DetailInput& cc_number =
897        controller()->RequestedFieldsForSection(SECTION_CC)[0];
898    DCHECK_EQ(cc_number.type, CREDIT_CARD_NUMBER);
899    view->SetTextContentsOfInput(cc_number, ASCIIToUTF16("4111111111111111"));
900  }
901
902  // Create some invalid, manually inputted shipping data.
903  const DetailInput& shipping_zip =
904      controller()->RequestedFieldsForSection(SECTION_SHIPPING)[5];
905  ASSERT_EQ(ADDRESS_HOME_ZIP, shipping_zip.type);
906  view->SetTextContentsOfInput(shipping_zip, ASCIIToUTF16("shipping zip"));
907
908  // Switch to Wallet by simulating a successful server response.
909  controller()->OnDidFetchWalletCookieValue(std::string());
910  controller()->OnDidGetWalletItems(
911      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED));
912  ASSERT_TRUE(controller()->IsPayingWithWallet());
913
914  {
915    // The valid data should be preserved.
916    const DetailInput& cc_number =
917        controller()->RequestedFieldsForSection(SECTION_CC_BILLING)[0];
918    EXPECT_EQ(cc_number.type, CREDIT_CARD_NUMBER);
919    EXPECT_EQ(ASCIIToUTF16("4111111111111111"),
920              view->GetTextContentsOfInput(cc_number));
921  }
922
923  // The invalid data should be dropped.
924  EXPECT_TRUE(view->GetTextContentsOfInput(shipping_zip).empty());
925
926  // Switch back to Autofill.
927  ui::MenuModel* account_chooser = controller()->MenuModelForAccountChooser();
928  account_chooser->ActivatedAt(account_chooser->GetItemCount() - 1);
929  ASSERT_FALSE(controller()->IsPayingWithWallet());
930
931  {
932    // The valid data should still be preserved when switched back.
933    const DetailInput& cc_number =
934        controller()->RequestedFieldsForSection(SECTION_CC)[0];
935    EXPECT_EQ(cc_number.type, CREDIT_CARD_NUMBER);
936    EXPECT_EQ(ASCIIToUTF16("4111111111111111"),
937              view->GetTextContentsOfInput(cc_number));
938  }
939}
940#endif  // defined(TOOLKIT_VIEWS) || defined(OS_MACOSX)
941
942IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
943                       GeneratedCardLastFourAfterVerifyCvv) {
944  controller()->OnDidFetchWalletCookieValue(std::string());
945
946  scoped_ptr<wallet::WalletItems> wallet_items =
947      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
948  wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
949  wallet_items->AddAddress(wallet::GetTestShippingAddress());
950
951  base::string16 last_four =
952      wallet_items->instruments()[0]->TypeAndLastFourDigits();
953  controller()->OnDidGetWalletItems(wallet_items.Pass());
954
955  TestableAutofillDialogView* test_view = controller()->GetTestableView();
956  EXPECT_FALSE(test_view->IsShowingOverlay());
957  EXPECT_CALL(*controller(), LoadRiskFingerprintData());
958  controller()->OnAccept();
959  EXPECT_TRUE(test_view->IsShowingOverlay());
960
961  EXPECT_CALL(*controller()->GetTestingWalletClient(), GetFullWallet(_));
962  scoped_ptr<risk::Fingerprint> fingerprint(new risk::Fingerprint());
963  fingerprint->mutable_machine_characteristics()->mutable_screen_size()->
964      set_width(1024);
965  controller()->OnDidLoadRiskFingerprintData(fingerprint.Pass());
966
967  controller()->OnDidGetFullWallet(
968      wallet::GetTestFullWalletWithRequiredActions(
969          std::vector<wallet::RequiredAction>(1, wallet::VERIFY_CVV)));
970
971  ASSERT_TRUE(controller()->IsSubmitPausedOn(wallet::VERIFY_CVV));
972
973  std::string fake_cvc("123");
974  test_view->SetTextContentsOfSuggestionInput(SECTION_CC_BILLING,
975                                              ASCIIToUTF16(fake_cvc));
976
977  EXPECT_FALSE(test_view->IsShowingOverlay());
978  EXPECT_CALL(*controller()->GetTestingWalletClient(),
979              AuthenticateInstrument(_, fake_cvc));
980  controller()->OnAccept();
981  EXPECT_TRUE(test_view->IsShowingOverlay());
982
983  EXPECT_CALL(*controller()->GetTestingWalletClient(), GetFullWallet(_));
984  controller()->OnDidAuthenticateInstrument(true);
985  controller()->OnDidGetFullWallet(wallet::GetTestFullWallet());
986  controller()->ForceFinishSubmit();
987
988  RunMessageLoop();
989
990  EXPECT_EQ(1, test_generated_bubble_controller()->bubbles_shown());
991  EXPECT_EQ(last_four, test_generated_bubble_controller()->backing_card_name());
992}
993
994// Simulates the user signing in to the dialog from the inline web contents.
995IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, SimulateSuccessfulSignIn) {
996  browser()->profile()->GetPrefs()->SetBoolean(
997      ::prefs::kAutofillDialogPayWithoutWallet,
998      true);
999
1000  InitializeController();
1001
1002  controller()->OnDidFetchWalletCookieValue(std::string());
1003  controller()->OnDidGetWalletItems(
1004      wallet::GetTestWalletItemsWithRequiredAction(wallet::GAIA_AUTH));
1005
1006  NavEntryCommittedObserver sign_in_page_observer(
1007      controller()->SignInUrl(),
1008      content::NotificationService::AllSources());
1009
1010  // Simulate a user clicking "Sign In" (which loads dialog's web contents).
1011  controller()->SignInLinkClicked();
1012  EXPECT_TRUE(controller()->ShouldShowSignInWebView());
1013
1014  TestableAutofillDialogView* view = controller()->GetTestableView();
1015  content::WebContents* sign_in_contents = view->GetSignInWebContents();
1016  ASSERT_TRUE(sign_in_contents);
1017
1018  sign_in_page_observer.Wait();
1019
1020  NavEntryCommittedObserver continue_page_observer(
1021      controller()->SignInContinueUrl(),
1022      content::NotificationService::AllSources());
1023
1024  EXPECT_EQ(sign_in_contents->GetURL(), controller()->SignInUrl());
1025
1026  AccountChooserModel* account_chooser_model =
1027      controller()->AccountChooserModelForTesting();
1028  EXPECT_FALSE(account_chooser_model->WalletIsSelected());
1029
1030  sign_in_contents->GetController().LoadURL(
1031      controller()->SignInContinueUrl(),
1032      content::Referrer(),
1033      content::PAGE_TRANSITION_FORM_SUBMIT,
1034      std::string());
1035
1036  EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems());
1037  continue_page_observer.Wait();
1038  content::RunAllPendingInMessageLoop();
1039
1040  EXPECT_FALSE(controller()->ShouldShowSignInWebView());
1041
1042  controller()->OnDidGetWalletItems(
1043      wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED));
1044
1045  // Wallet should now be selected and Chrome shouldn't have crashed (which can
1046  // happen if the WebContents is deleted while proccessing a nav entry commit).
1047  EXPECT_TRUE(account_chooser_model->WalletIsSelected());
1048}
1049
1050IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AddAccount) {
1051  InitializeController();
1052
1053  controller()->OnDidFetchWalletCookieValue(std::string());
1054  std::vector<std::string> usernames;
1055  usernames.push_back("user_0@example.com");
1056  controller()->OnDidGetWalletItems(
1057      wallet::GetTestWalletItemsWithUsers(usernames, 0));
1058
1059  // Switch to Autofill.
1060  AccountChooserModel* account_chooser_model =
1061      controller()->AccountChooserModelForTesting();
1062  account_chooser_model->ActivatedAt(
1063      account_chooser_model->GetItemCount() - 1);
1064
1065  NavEntryCommittedObserver sign_in_page_observer(
1066      controller()->SignInUrl(),
1067      content::NotificationService::AllSources());
1068
1069  // Simulate a user clicking "add account".
1070  account_chooser_model->ActivatedAt(
1071      account_chooser_model->GetItemCount() - 2);
1072  EXPECT_TRUE(controller()->ShouldShowSignInWebView());
1073
1074  TestableAutofillDialogView* view = controller()->GetTestableView();
1075  content::WebContents* sign_in_contents = view->GetSignInWebContents();
1076  ASSERT_TRUE(sign_in_contents);
1077
1078  sign_in_page_observer.Wait();
1079
1080  NavEntryCommittedObserver continue_page_observer(
1081      controller()->SignInContinueUrl(),
1082      content::NotificationService::AllSources());
1083
1084  EXPECT_EQ(sign_in_contents->GetURL(), controller()->SignInUrl());
1085
1086  EXPECT_FALSE(account_chooser_model->WalletIsSelected());
1087
1088  // User signs into new account, account 3.
1089  controller()->set_sign_in_user_index(3U);
1090  sign_in_contents->GetController().LoadURL(
1091      controller()->SignInContinueUrl(),
1092      content::Referrer(),
1093      content::PAGE_TRANSITION_FORM_SUBMIT,
1094      std::string());
1095
1096  EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems());
1097  continue_page_observer.Wait();
1098  content::RunAllPendingInMessageLoop();
1099
1100  EXPECT_FALSE(controller()->ShouldShowSignInWebView());
1101  EXPECT_EQ(3U, controller()->GetTestingWalletClient()->user_index());
1102
1103  usernames.push_back("user_1@example.com");
1104  usernames.push_back("user_2@example.com");
1105  usernames.push_back("user_3@example.com");
1106  usernames.push_back("user_4@example.com");
1107  // Curveball: wallet items comes back with user 4 selected.
1108  controller()->OnDidGetWalletItems(
1109      wallet::GetTestWalletItemsWithUsers(usernames, 4U));
1110
1111  EXPECT_TRUE(account_chooser_model->WalletIsSelected());
1112  EXPECT_EQ(4U, account_chooser_model->GetActiveWalletAccountIndex());
1113  EXPECT_EQ(4U, controller()->GetTestingWalletClient()->user_index());
1114}
1115
1116// http://crbug.com/318526
1117#if defined(OS_MACOSX)
1118#define MAYBE_FillFormIncludesCVC DISABLED_FillFormIncludesCVC
1119#else
1120#define MAYBE_FillFormIncludesCVC FillFormIncludesCVC
1121#endif
1122// Verify that filling a form works correctly, including filling the CVC when
1123// that is requested separately.
1124IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1125                       MAYBE_FillFormIncludesCVC) {
1126  AutofillDialogControllerImpl* controller =
1127      SetUpHtmlAndInvoke("<input autocomplete='cc-csc'>");
1128
1129  AddCreditcardToProfile(controller->profile(), test::GetVerifiedCreditCard());
1130  AddAutofillProfileToProfile(controller->profile(),
1131                              test::GetVerifiedProfile());
1132
1133  TestableAutofillDialogView* view = controller->GetTestableView();
1134  view->SetTextContentsOfSuggestionInput(SECTION_CC, ASCIIToUTF16("123"));
1135  view->SubmitForTesting();
1136  ExpectDomMessage("success");
1137  EXPECT_EQ("123", GetValueForHTMLFieldOfType("cc-csc"));
1138}
1139
1140IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AddNewClearsComboboxes) {
1141  // Ensure the input under test is a combobox.
1142  ASSERT_TRUE(
1143      controller()->ComboboxModelForAutofillType(CREDIT_CARD_EXP_MONTH));
1144
1145  // Set up an expired card.
1146  CreditCard card;
1147  test::SetCreditCardInfo(&card, "Roy Demeo", "4111111111111111", "8", "2013");
1148  card.set_origin("Chrome settings");
1149  ASSERT_TRUE(card.IsVerified());
1150
1151  // Add the card and check that there's a menu for that section.
1152  controller()->GetTestingManager()->AddTestingCreditCard(&card);
1153  ASSERT_TRUE(controller()->MenuModelForSection(SECTION_CC));
1154
1155  // Select the invalid, suggested card from the menu.
1156  controller()->MenuModelForSection(SECTION_CC)->ActivatedAt(0);
1157  EXPECT_TRUE(controller()->IsEditingExistingData(SECTION_CC));
1158
1159  const DetailInputs& inputs =
1160      controller()->RequestedFieldsForSection(SECTION_CC);
1161  const DetailInput& cc_exp_month = inputs[1];
1162  ASSERT_EQ(CREDIT_CARD_EXP_MONTH, cc_exp_month.type);
1163
1164  // Get the contents of the combobox of the credit card's expiration month.
1165  TestableAutofillDialogView* view = controller()->GetTestableView();
1166  base::string16 cc_exp_month_text = view->GetTextContentsOfInput(cc_exp_month);
1167
1168  // Select "New X..." from the suggestion menu to clear the section's inputs.
1169  controller()->MenuModelForSection(SECTION_CC)->ActivatedAt(1);
1170  EXPECT_FALSE(controller()->IsEditingExistingData(SECTION_CC));
1171
1172  // Ensure that the credit card expiration month has changed.
1173  EXPECT_NE(cc_exp_month_text, view->GetTextContentsOfInput(cc_exp_month));
1174}
1175
1176IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, TabOpensToJustRight) {
1177  ASSERT_TRUE(browser()->is_type_tabbed());
1178
1179  // Tabs should currently be: / rAc() \.
1180  content::WebContents* dialog_invoker = controller()->GetWebContents();
1181  EXPECT_EQ(dialog_invoker, GetActiveWebContents());
1182
1183  TabStripModel* tab_strip = browser()->tab_strip_model();
1184  ASSERT_EQ(1, tab_strip->count());
1185  EXPECT_EQ(0, tab_strip->GetIndexOfWebContents(dialog_invoker));
1186
1187  // Open a tab to about:blank in the background at the end of the tab strip.
1188  chrome::AddTabAt(browser(), GURL(), -1, false);
1189  // Tabs should now be: / rAc() \/ blank \.
1190  EXPECT_EQ(2, tab_strip->count());
1191  EXPECT_EQ(0, tab_strip->active_index());
1192  EXPECT_EQ(dialog_invoker, GetActiveWebContents());
1193
1194  content::WebContents* blank_tab = tab_strip->GetWebContentsAt(1);
1195
1196  // Simulate clicking "Manage X...".
1197  controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1198  // Tab should now be: / rAc() \/ manage 1 \/ blank \.
1199  EXPECT_EQ(3, tab_strip->count());
1200  int dialog_index = tab_strip->GetIndexOfWebContents(dialog_invoker);
1201  EXPECT_EQ(0, dialog_index);
1202  EXPECT_EQ(1, tab_strip->active_index());
1203  EXPECT_EQ(2, tab_strip->GetIndexOfWebContents(blank_tab));
1204
1205  content::WebContents* first_manage_tab = tab_strip->GetWebContentsAt(1);
1206
1207  // Re-activate the dialog's tab (like a user would have to).
1208  tab_strip->ActivateTabAt(dialog_index, true);
1209  EXPECT_EQ(dialog_invoker, GetActiveWebContents());
1210
1211  // Simulate clicking "Manage X...".
1212  controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1213  // Tabs should now be: / rAc() \/ manage 2 \/ manage 1 \/ blank \.
1214  EXPECT_EQ(4, tab_strip->count());
1215  EXPECT_EQ(0, tab_strip->GetIndexOfWebContents(dialog_invoker));
1216  EXPECT_EQ(1, tab_strip->active_index());
1217  EXPECT_EQ(2, tab_strip->GetIndexOfWebContents(first_manage_tab));
1218  EXPECT_EQ(3, tab_strip->GetIndexOfWebContents(blank_tab));
1219}
1220
1221}  // namespace autofill
1222