Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / autofill / autofill_dialog_controller_browsertest.cc
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/logging.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/time/time.h"
14 #include "chrome/browser/autofill/personal_data_manager_factory.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/ui/autofill/account_chooser_model.h"
17 #include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h"
18 #include "chrome/browser/ui/autofill/autofill_dialog_i18n_input.h"
19 #include "chrome/browser/ui/autofill/autofill_dialog_view.h"
20 #include "chrome/browser/ui/autofill/autofill_dialog_view_tester.h"
21 #include "chrome/browser/ui/autofill/chrome_autofill_client.h"
22 #include "chrome/browser/ui/autofill/data_model_wrapper.h"
23 #include "chrome/browser/ui/autofill/mock_address_validator.h"
24 #include "chrome/browser/ui/autofill/test_generated_credit_card_bubble_controller.h"
25 #include "chrome/browser/ui/browser.h"
26 #include "chrome/browser/ui/browser_tabstrip.h"
27 #include "chrome/browser/ui/tabs/tab_strip_model.h"
28 #include "chrome/common/chrome_switches.h"
29 #include "chrome/common/pref_names.h"
30 #include "chrome/common/url_constants.h"
31 #include "chrome/test/base/in_process_browser_test.h"
32 #include "chrome/test/base/ui_test_utils.h"
33 #include "components/autofill/content/browser/risk/proto/fingerprint.pb.h"
34 #include "components/autofill/content/browser/wallet/gaia_account.h"
35 #include "components/autofill/content/browser/wallet/mock_wallet_client.h"
36 #include "components/autofill/content/browser/wallet/wallet_service_url.h"
37 #include "components/autofill/content/browser/wallet/wallet_test_util.h"
38 #include "components/autofill/core/browser/autofill_metrics.h"
39 #include "components/autofill/core/browser/autofill_test_utils.h"
40 #include "components/autofill/core/browser/test_personal_data_manager.h"
41 #include "components/autofill/core/browser/validation.h"
42 #include "components/autofill/core/common/autofill_switches.h"
43 #include "components/autofill/core/common/form_data.h"
44 #include "components/autofill/core/common/form_field_data.h"
45 #include "content/public/browser/browser_thread.h"
46 #include "content/public/browser/interstitial_page.h"
47 #include "content/public/browser/navigation_details.h"
48 #include "content/public/browser/navigation_entry.h"
49 #include "content/public/browser/notification_service.h"
50 #include "content/public/browser/notification_types.h"
51 #include "content/public/browser/page_navigator.h"
52 #include "content/public/browser/web_contents.h"
53 #include "content/public/browser/web_contents_delegate.h"
54 #include "content/public/common/content_switches.h"
55 #include "content/public/common/referrer.h"
56 #include "content/public/common/url_constants.h"
57 #include "content/public/test/browser_test_utils.h"
58 #include "content/public/test/test_utils.h"
59 #include "google_apis/gaia/google_service_auth_error.h"
60 #include "net/test/spawned_test_server/spawned_test_server.h"
61 #include "testing/gmock/include/gmock/gmock.h"
62 #include "testing/gtest/include/gtest/gtest.h"
63 #include "third_party/WebKit/public/web/WebInputEvent.h"
64 #include "ui/base/page_transition_types.h"
65 #include "ui/base/window_open_disposition.h"
66 #include "url/gurl.h"
67
68 #if defined(OS_WIN)
69 #include "base/win/windows_version.h"
70 #elif defined(OS_MACOSX)
71 #include "base/mac/mac_util.h"
72 #include "base/mac/scoped_nsautorelease_pool.h"
73 #include "chrome/browser/ui/cocoa/run_loop_testing.h"
74 #endif
75
76 using base::ASCIIToUTF16;
77
78 namespace autofill {
79
80 namespace {
81
82 using testing::Return;
83 using testing::_;
84
85 void MockCallback(AutofillClient::RequestAutocompleteResult,
86                   const base::string16& message,
87                   const FormStructure*) {
88 }
89
90 class MockAutofillMetrics : public AutofillMetrics {
91  public:
92   MockAutofillMetrics()
93       : dialog_dismissal_action_(static_cast<DialogDismissalAction>(-1)) {}
94   virtual ~MockAutofillMetrics() {}
95
96   virtual void LogDialogUiDuration(
97       const base::TimeDelta& duration,
98       DialogDismissalAction dismissal_action) const OVERRIDE {
99     // Ignore constness for testing.
100     MockAutofillMetrics* mutable_this = const_cast<MockAutofillMetrics*>(this);
101     mutable_this->dialog_dismissal_action_ = dismissal_action;
102   }
103
104   AutofillMetrics::DialogDismissalAction dialog_dismissal_action() const {
105     return dialog_dismissal_action_;
106   }
107
108   MOCK_CONST_METHOD1(LogDialogDismissalState,
109                      void(DialogDismissalState state));
110
111  private:
112   DialogDismissalAction dialog_dismissal_action_;
113
114   DISALLOW_COPY_AND_ASSIGN(MockAutofillMetrics);
115 };
116
117 class TestAutofillDialogController : public AutofillDialogControllerImpl {
118  public:
119   TestAutofillDialogController(
120       content::WebContents* contents,
121       const FormData& form_data,
122       const AutofillMetrics& metric_logger,
123       scoped_refptr<content::MessageLoopRunner> runner)
124       : AutofillDialogControllerImpl(contents,
125                                      form_data,
126                                      form_data.origin,
127                                      base::Bind(&MockCallback)),
128         metric_logger_(metric_logger),
129         mock_wallet_client_(
130             Profile::FromBrowserContext(contents->GetBrowserContext())->
131                 GetRequestContext(), this, form_data.origin),
132         message_loop_runner_(runner),
133         use_validation_(false),
134         sign_in_user_index_(0U),
135         weak_ptr_factory_(this) {
136     test_manager_.Init(
137         NULL,
138         Profile::FromBrowserContext(contents->GetBrowserContext())->GetPrefs(),
139         false);
140   }
141
142   virtual ~TestAutofillDialogController() {}
143
144   virtual GURL SignInUrl() const OVERRIDE {
145     return GURL(chrome::kChromeUIVersionURL);
146   }
147
148   virtual void ViewClosed() OVERRIDE {
149     message_loop_runner_->Quit();
150     AutofillDialogControllerImpl::ViewClosed();
151   }
152
153   virtual base::string16 InputValidityMessage(
154       DialogSection section,
155       ServerFieldType type,
156       const base::string16& value) OVERRIDE {
157     if (!use_validation_)
158       return base::string16();
159     return AutofillDialogControllerImpl::InputValidityMessage(
160         section, type, value);
161   }
162
163   virtual ValidityMessages InputsAreValid(
164       DialogSection section,
165       const FieldValueMap& inputs) OVERRIDE {
166     if (!use_validation_)
167       return ValidityMessages();
168     return AutofillDialogControllerImpl::InputsAreValid(section, inputs);
169   }
170
171   // Saving to Chrome is tested in AutofillDialogControllerImpl unit tests.
172   // TODO(estade): test that the view defaults to saving to Chrome.
173   virtual bool ShouldOfferToSaveInChrome() const OVERRIDE {
174     return true;
175   }
176
177   void ForceFinishSubmit() {
178     DoFinishSubmit();
179   }
180
181   // Increase visibility for testing.
182   using AutofillDialogControllerImpl::view;
183   using AutofillDialogControllerImpl::popup_input_type;
184
185   MOCK_METHOD0(LoadRiskFingerprintData, void());
186
187   virtual std::vector<DialogNotification> CurrentNotifications() OVERRIDE {
188     return notifications_;
189   }
190
191   void set_notifications(const std::vector<DialogNotification>& notifications) {
192     notifications_ = notifications;
193   }
194
195   TestPersonalDataManager* GetTestingManager() {
196     return &test_manager_;
197   }
198
199   MockAddressValidator* GetMockValidator() {
200     return &mock_validator_;
201   }
202
203   using AutofillDialogControllerImpl::IsEditingExistingData;
204   using AutofillDialogControllerImpl::IsManuallyEditingSection;
205   using AutofillDialogControllerImpl::IsPayingWithWallet;
206   using AutofillDialogControllerImpl::IsSubmitPausedOn;
207   using AutofillDialogControllerImpl::OnDidLoadRiskFingerprintData;
208   using AutofillDialogControllerImpl::AccountChooserModelForTesting;
209   using AutofillDialogControllerImpl::
210       ClearLastWalletItemsFetchTimestampForTesting;
211
212   void set_use_validation(bool use_validation) {
213     use_validation_ = use_validation;
214   }
215
216   base::WeakPtr<TestAutofillDialogController> AsWeakPtr() {
217     return weak_ptr_factory_.GetWeakPtr();
218   }
219
220   wallet::MockWalletClient* GetTestingWalletClient() {
221     return &mock_wallet_client_;
222   }
223
224   void set_sign_in_user_index(size_t sign_in_user_index) {
225     sign_in_user_index_ = sign_in_user_index;
226   }
227
228  protected:
229   virtual PersonalDataManager* GetManager() const OVERRIDE {
230     return &const_cast<TestAutofillDialogController*>(this)->test_manager_;
231   }
232
233   virtual AddressValidator* GetValidator() OVERRIDE {
234     return &mock_validator_;
235   }
236
237   virtual wallet::WalletClient* GetWalletClient() OVERRIDE {
238     return &mock_wallet_client_;
239   }
240
241   virtual bool IsSignInContinueUrl(const GURL& url, size_t* user_index) const
242       OVERRIDE {
243     *user_index = sign_in_user_index_;
244     return url == wallet::GetSignInContinueUrl();
245   }
246
247  private:
248   // To specify our own metric logger.
249   virtual const AutofillMetrics& GetMetricLogger() const OVERRIDE {
250     return metric_logger_;
251   }
252
253   const AutofillMetrics& metric_logger_;
254   TestPersonalDataManager test_manager_;
255   testing::NiceMock<MockAddressValidator> mock_validator_;
256   testing::NiceMock<wallet::MockWalletClient> mock_wallet_client_;
257   scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
258   bool use_validation_;
259
260   // A list of notifications to show in the notification area of the dialog.
261   // This is used to control what |CurrentNotifications()| returns for testing.
262   std::vector<DialogNotification> notifications_;
263
264   // The user index that is assigned in IsSignInContinueUrl().
265   size_t sign_in_user_index_;
266
267   // Allows generation of WeakPtrs, so controller liveness can be tested.
268   base::WeakPtrFactory<TestAutofillDialogController> weak_ptr_factory_;
269
270   DISALLOW_COPY_AND_ASSIGN(TestAutofillDialogController);
271 };
272
273 // This is a copy of ui_test_utils::UrlLoadObserver, except it observes
274 // NAV_ENTRY_COMMITTED instead of LOAD_STOP. This is to match the notification
275 // that AutofillDialogControllerImpl observes. Since NAV_ENTRY_COMMITTED comes
276 // before LOAD_STOP, and the controller deletes the web contents after receiving
277 // the former, we will sometimes fail to observe a LOAD_STOP.
278 // TODO(estade): Should the controller observe LOAD_STOP instead?
279 class NavEntryCommittedObserver : public content::WindowedNotificationObserver {
280  public:
281   NavEntryCommittedObserver(const GURL& url,
282                             const content::NotificationSource& source)
283     : WindowedNotificationObserver(content::NOTIFICATION_NAV_ENTRY_COMMITTED,
284                                    source),
285       url_(url) {}
286
287   virtual ~NavEntryCommittedObserver() {}
288
289   // content::NotificationObserver:
290   virtual void Observe(int type,
291                        const content::NotificationSource& source,
292                        const content::NotificationDetails& details) OVERRIDE {
293     content::LoadCommittedDetails* load_details =
294         content::Details<content::LoadCommittedDetails>(details).ptr();
295     if (load_details->entry->GetVirtualURL() != url_)
296       return;
297
298     WindowedNotificationObserver::Observe(type, source, details);
299   }
300
301  private:
302   GURL url_;
303
304   DISALLOW_COPY_AND_ASSIGN(NavEntryCommittedObserver);
305 };
306
307 }  // namespace
308
309 class AutofillDialogControllerTest : public InProcessBrowserTest {
310  public:
311   AutofillDialogControllerTest() : controller_(NULL) {}
312   virtual ~AutofillDialogControllerTest() {}
313
314   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
315     command_line->AppendSwitch(::switches::kReduceSecurityForTesting);
316   }
317
318   virtual void SetUpOnMainThread() OVERRIDE {
319     autofill::test::DisableSystemServices(browser()->profile()->GetPrefs());
320     InitializeController();
321   }
322
323  protected:
324   bool SectionHasField(DialogSection section, ServerFieldType type) {
325     const DetailInputs& fields =
326         controller()->RequestedFieldsForSection(section);
327     for (size_t i = 0; i < fields.size(); ++i) {
328       if (type == fields[i].type)
329         return true;
330     }
331     return false;
332   }
333
334   // A helper function that cycles the MessageLoop, and on Mac, the Cocoa run
335   // loop. It also drains the NSAutoreleasePool.
336   void CycleRunLoops() {
337     content::RunAllPendingInMessageLoop();
338 #if defined(OS_MACOSX)
339     chrome::testing::NSRunLoopRunAllPending();
340     AutoreleasePool()->Recycle();
341 #endif
342   }
343
344   void InitializeControllerWithoutShowing() {
345     if (controller_)
346       controller_->Hide();
347
348     FormData form;
349     form.name = ASCIIToUTF16("TestForm");
350     form.user_submitted = true;
351
352     FormFieldData field;
353     field.autocomplete_attribute = "shipping tel";
354     form.fields.push_back(field);
355
356     FormFieldData cc;
357     cc.autocomplete_attribute = "cc-number";
358     form.fields.push_back(cc);
359
360     test_generated_bubble_controller_ =
361         new testing::NiceMock<TestGeneratedCreditCardBubbleController>(
362             GetActiveWebContents());
363     ASSERT_TRUE(test_generated_bubble_controller_->IsInstalled());
364
365     message_loop_runner_ = new content::MessageLoopRunner;
366     controller_ = new TestAutofillDialogController(
367         GetActiveWebContents(),
368         form,
369         metric_logger_,
370         message_loop_runner_);
371   }
372
373   void InitializeController() {
374     InitializeControllerWithoutShowing();
375     controller_->Show();
376     CycleRunLoops();  // Ensures dialog is fully visible.
377   }
378
379   content::WebContents* GetActiveWebContents() {
380     return browser()->tab_strip_model()->GetActiveWebContents();
381   }
382
383   content::RenderViewHost* GetRenderViewHost() {
384     return GetActiveWebContents()->GetRenderViewHost();
385   }
386
387   scoped_ptr<AutofillDialogViewTester> GetViewTester() {
388     return AutofillDialogViewTester::For(controller()->view()).Pass();
389   }
390
391   const MockAutofillMetrics& metric_logger() { return metric_logger_; }
392   TestAutofillDialogController* controller() { return controller_; }
393
394   void RunMessageLoop() {
395     message_loop_runner_->Run();
396   }
397
398   // Loads an HTML page in |GetActiveWebContents()| with markup as follows:
399   // <form>|form_inner_html|</form>. After loading, emulates a click event on
400   // the page as requestAutocomplete() must be in response to a user gesture.
401   // Returns the |AutofillDialogControllerImpl| created by this invocation.
402   AutofillDialogControllerImpl* SetUpHtmlAndInvoke(
403       const std::string& form_inner_html) {
404     content::WebContents* contents = GetActiveWebContents();
405     ChromeAutofillClient* client =
406         ChromeAutofillClient::FromWebContents(contents);
407     CHECK(!client->GetDialogControllerForTesting());
408
409     ui_test_utils::NavigateToURL(
410         browser(), GURL(std::string("data:text/html,") +
411         "<!doctype html>"
412         "<html>"
413           "<body>"
414             "<form>" + form_inner_html + "</form>"
415             "<script>"
416               "var invalidEvents = [];"
417               "function recordInvalid(e) {"
418                 "if (e.type != 'invalid') throw 'only invalid events allowed';"
419                 "invalidEvents.push(e);"
420               "}"
421               "function send(msg) {"
422                 "domAutomationController.setAutomationId(0);"
423                 "domAutomationController.send(msg);"
424               "}"
425               "document.forms[0].onautocompleteerror = function(e) {"
426                 "send('error: ' + e.reason);"
427               "};"
428               "document.forms[0].onautocomplete = function() {"
429                 "send('success');"
430               "};"
431               "window.onclick = function() {"
432                 "var inputs = document.forms[0].querySelectorAll('input');"
433                 "for (var i = 0; i < inputs.length; ++i) {"
434                   "inputs[i].oninvalid = recordInvalid;"
435                 "}"
436                 "document.forms[0].requestAutocomplete();"
437                 "send('clicked');"
438               "};"
439               "function loadIframe() {"
440               "  var iframe = document.createElement('iframe');"
441               "  iframe.onload = function() {"
442               "    send('iframe loaded');"
443               "  };"
444               "  iframe.src = 'about:blank';"
445               "  document.body.appendChild(iframe);"
446               "}"
447               "function getValueForFieldOfType(type) {"
448               "  var fields = document.getElementsByTagName('input');"
449               "  for (var i = 0; i < fields.length; i++) {"
450               "    if (fields[i].autocomplete == type) {"
451               "      send(fields[i].value);"
452               "      return;"
453               "    }"
454               "  }"
455               "  send('');"
456               "};"
457             "</script>"
458           "</body>"
459         "</html>"));
460
461     InitiateDialog();
462     AutofillDialogControllerImpl* controller =
463         static_cast<AutofillDialogControllerImpl*>(
464             client->GetDialogControllerForTesting());
465     return controller;
466   }
467
468   // Loads an html page on a provided server, the causes it to launch rAc.
469   // Returns whether rAc succesfully launched.
470   bool RunTestPage(const net::SpawnedTestServer& server) {
471     GURL url = server.GetURL(
472         "files/request_autocomplete/test_page.html");
473     ui_test_utils::NavigateToURL(browser(), url);
474
475     // Pass through the broken SSL interstitial, if any.
476     content::WebContents* contents = GetActiveWebContents();
477     content::InterstitialPage* interstitial_page =
478         contents->GetInterstitialPage();
479     if (interstitial_page) {
480       ui_test_utils::UrlLoadObserver observer(
481           url,
482           content::Source<content::NavigationController>(
483               &contents->GetController()));
484       interstitial_page->Proceed();
485       observer.Wait();
486     }
487
488     InitiateDialog();
489
490     ChromeAutofillClient* client =
491         ChromeAutofillClient::FromWebContents(contents);
492     AutofillDialogControllerImpl* controller =
493         static_cast<AutofillDialogControllerImpl*>(
494             client->GetDialogControllerForTesting());
495     return !!controller;
496   }
497
498   // Wait for a message from the DOM automation controller (from JS in the
499   // page). Requires |SetUpHtmlAndInvoke()| be called first.
500   void ExpectDomMessage(const std::string& expected) {
501     std::string message;
502     ASSERT_TRUE(dom_message_queue_->WaitForMessage(&message));
503     dom_message_queue_->ClearQueue();
504     EXPECT_EQ("\"" + expected + "\"", message);
505   }
506
507   void InitiateDialog() {
508     dom_message_queue_.reset(new content::DOMMessageQueue);
509
510     // Triggers the onclick handler which invokes requestAutocomplete().
511     content::WebContents* contents = GetActiveWebContents();
512     content::SimulateMouseClick(contents, 0, blink::WebMouseEvent::ButtonLeft);
513     ExpectDomMessage("clicked");
514   }
515
516   // Returns the value filled into the first field with autocomplete attribute
517   // equal to |autocomplete_type|, or an empty string if there is no such field.
518   std::string GetValueForHTMLFieldOfType(const std::string& autocomplete_type) {
519     std::string script = "getValueForFieldOfType('" + autocomplete_type + "');";
520     std::string result;
521     EXPECT_TRUE(content::ExecuteScriptAndExtractString(GetRenderViewHost(),
522                                                        script,
523                                                        &result));
524     return result;
525   }
526
527   void AddCreditcardToProfile(Profile* profile, const CreditCard& card) {
528     PersonalDataManagerFactory::GetForProfile(profile)->AddCreditCard(card);
529     WaitForWebDB();
530   }
531
532   void AddAutofillProfileToProfile(Profile* profile,
533                                    const AutofillProfile& autofill_profile) {
534     PersonalDataManagerFactory::GetForProfile(profile)->AddProfile(
535         autofill_profile);
536     WaitForWebDB();
537   }
538
539   TestGeneratedCreditCardBubbleController* test_generated_bubble_controller() {
540     return test_generated_bubble_controller_;
541   }
542
543  private:
544   void WaitForWebDB() {
545     content::RunAllPendingInMessageLoop(content::BrowserThread::DB);
546   }
547
548   testing::NiceMock<MockAutofillMetrics> metric_logger_;
549   TestAutofillDialogController* controller_;  // Weak reference.
550   scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
551   scoped_ptr<content::DOMMessageQueue> dom_message_queue_;
552
553   // Weak; owned by the active web contents.
554   TestGeneratedCreditCardBubbleController* test_generated_bubble_controller_;
555
556   DISALLOW_COPY_AND_ASSIGN(AutofillDialogControllerTest);
557 };
558
559 // Submit the form data.
560 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, Submit) {
561   GetViewTester()->SubmitForTesting();
562   RunMessageLoop();
563
564   EXPECT_EQ(AutofillMetrics::DIALOG_ACCEPTED,
565             metric_logger().dialog_dismissal_action());
566 }
567
568 // Cancel out of the dialog.
569 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, Cancel) {
570   EXPECT_CALL(metric_logger(),
571               LogDialogDismissalState(
572                   AutofillMetrics::DIALOG_CANCELED_NO_INVALID_FIELDS));
573
574   GetViewTester()->CancelForTesting();
575   RunMessageLoop();
576
577   EXPECT_EQ(AutofillMetrics::DIALOG_CANCELED,
578             metric_logger().dialog_dismissal_action());
579 }
580
581 // Take some other action that dismisses the dialog.
582 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, Hide) {
583   EXPECT_CALL(metric_logger(),
584               LogDialogDismissalState(
585                   AutofillMetrics::DIALOG_CANCELED_NO_INVALID_FIELDS));
586   controller()->Hide();
587
588   RunMessageLoop();
589
590   EXPECT_EQ(AutofillMetrics::DIALOG_CANCELED,
591             metric_logger().dialog_dismissal_action());
592 }
593
594 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, CancelWithSuggestions) {
595   EXPECT_CALL(metric_logger(),
596               LogDialogDismissalState(
597                   AutofillMetrics::DIALOG_CANCELED_NO_EDITS));
598
599   CreditCard card(test::GetVerifiedCreditCard());
600   controller()->GetTestingManager()->AddTestingCreditCard(&card);
601   AutofillProfile profile(test::GetVerifiedProfile());
602   controller()->GetTestingManager()->AddTestingProfile(&profile);
603
604   EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_CC));
605   EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_BILLING));
606   EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
607
608   GetViewTester()->CancelForTesting();
609   RunMessageLoop();
610
611   EXPECT_EQ(AutofillMetrics::DIALOG_CANCELED,
612             metric_logger().dialog_dismissal_action());
613 }
614
615 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AcceptWithSuggestions) {
616   EXPECT_CALL(metric_logger(),
617               LogDialogDismissalState(
618                   AutofillMetrics::DIALOG_ACCEPTED_EXISTING_AUTOFILL_DATA));
619
620   CreditCard card(test::GetVerifiedCreditCard());
621   controller()->GetTestingManager()->AddTestingCreditCard(&card);
622   AutofillProfile profile(test::GetVerifiedProfile());
623   controller()->GetTestingManager()->AddTestingProfile(&profile);
624
625   EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_CC));
626   EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_BILLING));
627   EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
628
629   GetViewTester()->SubmitForTesting();
630   RunMessageLoop();
631
632   EXPECT_EQ(AutofillMetrics::DIALOG_ACCEPTED,
633             metric_logger().dialog_dismissal_action());
634 }
635
636 // Ensure that Hide() will only destroy the controller object after the
637 // message loop has run. Otherwise, there may be read-after-free issues
638 // during some tests.
639 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, DeferredDestruction) {
640   base::WeakPtr<TestAutofillDialogController> weak_ptr =
641       controller()->AsWeakPtr();
642   EXPECT_TRUE(weak_ptr.get());
643
644   controller()->Hide();
645   EXPECT_TRUE(weak_ptr.get());
646
647   RunMessageLoop();
648   EXPECT_FALSE(weak_ptr.get());
649 }
650
651 // Ensure that the expected metric is logged when the dialog is closed during
652 // signin.
653 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, CloseDuringSignin) {
654   controller()->SignInLinkClicked();
655
656   EXPECT_CALL(metric_logger(),
657               LogDialogDismissalState(
658                   AutofillMetrics::DIALOG_CANCELED_DURING_SIGNIN));
659   GetViewTester()->CancelForTesting();
660
661   RunMessageLoop();
662
663   EXPECT_EQ(AutofillMetrics::DIALOG_CANCELED,
664             metric_logger().dialog_dismissal_action());
665 }
666
667 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, FillInputFromAutofill) {
668   AutofillProfile full_profile(test::GetFullProfile());
669   const base::string16 formatted_phone(ASCIIToUTF16("+1 (310) 555 1234"));
670   full_profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, formatted_phone);
671   controller()->GetTestingManager()->AddTestingProfile(&full_profile);
672
673   // Dialog is already asking for a new billing address.
674   EXPECT_TRUE(controller()->IsManuallyEditingSection(SECTION_BILLING));
675
676   // Select "Add new shipping address...".
677   ui::MenuModel* model = controller()->MenuModelForSection(SECTION_SHIPPING);
678   model->ActivatedAt(model->GetItemCount() - 2);
679   ASSERT_TRUE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
680
681   // Enter something in a shipping input.
682   const DetailInputs& inputs =
683       controller()->RequestedFieldsForSection(SECTION_SHIPPING);
684   const ServerFieldType triggering_type = inputs[0].type;
685   base::string16 value = full_profile.GetRawInfo(triggering_type);
686   scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
687   view->SetTextContentsOfInput(triggering_type,
688                                value.substr(0, value.size() / 2));
689   view->ActivateInput(triggering_type);
690
691   ASSERT_EQ(triggering_type, controller()->popup_input_type());
692   controller()->DidAcceptSuggestion(base::string16(), 0);
693
694   // All inputs should be filled.
695   AutofillProfileWrapper wrapper(&full_profile);
696   for (size_t i = 0; i < inputs.size(); ++i) {
697     EXPECT_EQ(wrapper.GetInfoForDisplay(AutofillType(inputs[i].type)),
698               view->GetTextContentsOfInput(inputs[i].type));
699
700     // Double check the correct formatting is used for the phone number.
701     if (inputs[i].type == PHONE_HOME_WHOLE_NUMBER)
702       EXPECT_EQ(formatted_phone, view->GetTextContentsOfInput(inputs[i].type));
703   }
704
705   // Inputs from the other section (billing) should be left alone.
706   const DetailInputs& other_section_inputs =
707       controller()->RequestedFieldsForSection(SECTION_BILLING);
708   for (size_t i = 0; i < inputs.size(); ++i) {
709     base::string16 input_value =
710         view->GetTextContentsOfInput(other_section_inputs[i].type);
711     // If there's a combobox, the string should be non-empty.
712     if (controller()->ComboboxModelForAutofillType(
713             other_section_inputs[i].type)) {
714       EXPECT_NE(base::string16(), input_value);
715     } else {
716       EXPECT_EQ(base::string16(), input_value);
717     }
718   }
719
720   // Now simulate some user edits and try again.
721   std::vector<base::string16> expectations;
722   for (size_t i = 0; i < inputs.size(); ++i) {
723     if (controller()->ComboboxModelForAutofillType(inputs[i].type)) {
724       expectations.push_back(base::string16());
725       continue;
726     }
727     base::string16 users_input = i % 2 == 0 ? base::string16()
728                                             : ASCIIToUTF16("dummy");
729     view->SetTextContentsOfInput(inputs[i].type, users_input);
730     // Empty inputs should be filled, others should be left alone.
731     base::string16 expectation =
732         inputs[i].type == triggering_type || users_input.empty() ?
733         wrapper.GetInfoForDisplay(AutofillType(inputs[i].type)) :
734         users_input;
735     expectations.push_back(expectation);
736   }
737
738   view->SetTextContentsOfInput(triggering_type,
739                                value.substr(0, value.size() / 2));
740   view->ActivateInput(triggering_type);
741   ASSERT_EQ(triggering_type, controller()->popup_input_type());
742   controller()->DidAcceptSuggestion(base::string16(), 0);
743
744   for (size_t i = 0; i < inputs.size(); ++i) {
745     if (controller()->ComboboxModelForAutofillType(inputs[i].type))
746       continue;
747     EXPECT_EQ(expectations[i], view->GetTextContentsOfInput(inputs[i].type));
748   }
749
750   EXPECT_CALL(metric_logger(),
751               LogDialogDismissalState(
752                   AutofillMetrics::DIALOG_ACCEPTED_SAVE_TO_AUTOFILL));
753   view->SubmitForTesting();
754 }
755
756 // This test makes sure that picking a profile variant in the Autofill
757 // popup works as expected.
758 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
759                        FillInputFromAutofillVariant) {
760   AutofillProfile full_profile(test::GetFullProfile());
761
762   // Set up some variant data.
763   std::vector<base::string16> names;
764   names.push_back(ASCIIToUTF16("John Doe"));
765   names.push_back(ASCIIToUTF16("Jane Doe"));
766   full_profile.SetRawMultiInfo(NAME_FULL, names);
767   std::vector<base::string16> emails;
768   emails.push_back(ASCIIToUTF16("user@example.com"));
769   emails.push_back(ASCIIToUTF16("admin@example.com"));
770   full_profile.SetRawMultiInfo(EMAIL_ADDRESS, emails);
771   controller()->GetTestingManager()->AddTestingProfile(&full_profile);
772
773   const DetailInputs& inputs =
774       controller()->RequestedFieldsForSection(SECTION_BILLING);
775   const ServerFieldType triggering_type = inputs[0].type;
776   EXPECT_EQ(NAME_BILLING_FULL, triggering_type);
777   scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
778   view->ActivateInput(triggering_type);
779
780   ASSERT_EQ(triggering_type, controller()->popup_input_type());
781
782   // Choose the variant suggestion.
783   controller()->DidAcceptSuggestion(base::string16(), 1);
784
785   // All inputs should be filled.
786   AutofillProfileWrapper wrapper(
787       &full_profile, AutofillType(NAME_BILLING_FULL), 1);
788   for (size_t i = 0; i < inputs.size(); ++i) {
789     EXPECT_EQ(wrapper.GetInfoForDisplay(AutofillType(inputs[i].type)),
790               view->GetTextContentsOfInput(inputs[i].type));
791   }
792
793   // Make sure the wrapper applies the variant index to the right group.
794   EXPECT_EQ(names[1], wrapper.GetInfo(AutofillType(NAME_BILLING_FULL)));
795   // Make sure the wrapper doesn't apply the variant index to the wrong group.
796   EXPECT_EQ(emails[0], wrapper.GetInfo(AutofillType(EMAIL_ADDRESS)));
797 }
798
799 // Tests that changing the value of a CC expiration date combobox works as
800 // expected when Autofill is used to fill text inputs.
801 //
802 // Flaky on Win7, WinXP, and Win Aura.  http://crbug.com/270314.
803 #if defined(OS_WIN)
804 #define MAYBE_FillComboboxFromAutofill DISABLED_FillComboboxFromAutofill
805 #else
806 #define MAYBE_FillComboboxFromAutofill FillComboboxFromAutofill
807 #endif
808 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
809                        MAYBE_FillComboboxFromAutofill) {
810   CreditCard card1;
811   test::SetCreditCardInfo(&card1, "JJ Smith", "4111111111111111", "12", "2018");
812   controller()->GetTestingManager()->AddTestingCreditCard(&card1);
813   CreditCard card2;
814   test::SetCreditCardInfo(&card2, "B Bird", "3111111111111111", "11", "2017");
815   controller()->GetTestingManager()->AddTestingCreditCard(&card2);
816   AutofillProfile full_profile(test::GetFullProfile());
817   controller()->GetTestingManager()->AddTestingProfile(&full_profile);
818
819   const DetailInputs& inputs =
820       controller()->RequestedFieldsForSection(SECTION_CC);
821   const ServerFieldType triggering_type = inputs[0].type;
822   base::string16 value = card1.GetRawInfo(triggering_type);
823   scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
824   view->SetTextContentsOfInput(triggering_type,
825                                value.substr(0, value.size() / 2));
826   view->ActivateInput(triggering_type);
827
828   ASSERT_EQ(triggering_type, controller()->popup_input_type());
829   controller()->DidAcceptSuggestion(base::string16(), 0);
830
831   // All inputs should be filled.
832   AutofillCreditCardWrapper wrapper1(&card1);
833   for (size_t i = 0; i < inputs.size(); ++i) {
834     EXPECT_EQ(wrapper1.GetInfo(AutofillType(inputs[i].type)),
835               view->GetTextContentsOfInput(inputs[i].type));
836   }
837
838   // Try again with different data. Only expiration date and the triggering
839   // input should be overwritten.
840   value = card2.GetRawInfo(triggering_type);
841   view->SetTextContentsOfInput(triggering_type,
842                                value.substr(0, value.size() / 2));
843   view->ActivateInput(triggering_type);
844   ASSERT_EQ(triggering_type, controller()->popup_input_type());
845   controller()->DidAcceptSuggestion(base::string16(), 0);
846
847   AutofillCreditCardWrapper wrapper2(&card2);
848   for (size_t i = 0; i < inputs.size(); ++i) {
849     const ServerFieldType type = inputs[i].type;
850     if (type == triggering_type ||
851         type == CREDIT_CARD_EXP_MONTH ||
852         type == CREDIT_CARD_EXP_4_DIGIT_YEAR) {
853       EXPECT_EQ(wrapper2.GetInfo(AutofillType(type)),
854                 view->GetTextContentsOfInput(type));
855     } else if (type == CREDIT_CARD_VERIFICATION_CODE) {
856       EXPECT_TRUE(view->GetTextContentsOfInput(type).empty());
857     } else {
858       EXPECT_EQ(wrapper1.GetInfo(AutofillType(type)),
859                 view->GetTextContentsOfInput(type));
860     }
861   }
862
863   // Now fill from a profile. It should not overwrite any CC info.
864   const DetailInputs& billing_inputs =
865       controller()->RequestedFieldsForSection(SECTION_BILLING);
866   const ServerFieldType billing_triggering_type = billing_inputs[0].type;
867   value = full_profile.GetRawInfo(triggering_type);
868   view->SetTextContentsOfInput(billing_triggering_type,
869                                value.substr(0, value.size() / 2));
870   view->ActivateInput(billing_triggering_type);
871
872   ASSERT_EQ(billing_triggering_type, controller()->popup_input_type());
873   controller()->DidAcceptSuggestion(base::string16(), 0);
874
875   for (size_t i = 0; i < inputs.size(); ++i) {
876     const ServerFieldType type = inputs[i].type;
877     if (type == triggering_type ||
878         type == CREDIT_CARD_EXP_MONTH ||
879         type == CREDIT_CARD_EXP_4_DIGIT_YEAR) {
880       EXPECT_EQ(wrapper2.GetInfo(AutofillType(type)),
881                 view->GetTextContentsOfInput(type));
882     } else if (type == CREDIT_CARD_VERIFICATION_CODE) {
883       EXPECT_TRUE(view->GetTextContentsOfInput(type).empty());
884     } else {
885       EXPECT_EQ(wrapper1.GetInfo(AutofillType(type)),
886                 view->GetTextContentsOfInput(type));
887     }
888   }
889 }
890
891 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, ShouldShowErrorBubble) {
892   controller()->set_use_validation(true);
893   EXPECT_TRUE(controller()->ShouldShowErrorBubble());
894
895   CreditCard card(test::GetCreditCard());
896   ASSERT_FALSE(card.IsVerified());
897   controller()->GetTestingManager()->AddTestingCreditCard(&card);
898
899   EXPECT_TRUE(controller()->IsManuallyEditingSection(SECTION_CC));
900   scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
901   view->SetTextContentsOfInput(
902       CREDIT_CARD_NUMBER,
903       card.GetRawInfo(CREDIT_CARD_NUMBER).substr(0, 1));
904
905   view->ActivateInput(CREDIT_CARD_NUMBER);
906   EXPECT_FALSE(controller()->ShouldShowErrorBubble());
907
908   controller()->FocusMoved();
909   EXPECT_TRUE(controller()->ShouldShowErrorBubble());
910
911   EXPECT_CALL(metric_logger(),
912               LogDialogDismissalState(
913                   AutofillMetrics::DIALOG_CANCELED_WITH_INVALID_FIELDS));
914   controller()->Hide();
915 }
916
917 // Ensure that expired cards trigger invalid suggestions.
918 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, ExpiredCard) {
919   CreditCard verified_card(test::GetCreditCard());
920   verified_card.set_origin("Chrome settings");
921   ASSERT_TRUE(verified_card.IsVerified());
922   controller()->GetTestingManager()->AddTestingCreditCard(&verified_card);
923
924   CreditCard expired_card(test::GetCreditCard());
925   expired_card.set_origin("Chrome settings");
926   expired_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2007"));
927   ASSERT_TRUE(expired_card.IsVerified());
928   ASSERT_FALSE(
929       autofill::IsValidCreditCardExpirationDate(
930           expired_card.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR),
931           expired_card.GetRawInfo(CREDIT_CARD_EXP_MONTH),
932           base::Time::Now()));
933   controller()->GetTestingManager()->AddTestingCreditCard(&expired_card);
934
935   ui::MenuModel* model = controller()->MenuModelForSection(SECTION_CC);
936   ASSERT_EQ(4, model->GetItemCount());
937
938   ASSERT_TRUE(model->IsItemCheckedAt(0));
939   EXPECT_FALSE(controller()->IsEditingExistingData(SECTION_CC));
940
941   model->ActivatedAt(1);
942   ASSERT_TRUE(model->IsItemCheckedAt(1));
943   EXPECT_TRUE(controller()->IsEditingExistingData(SECTION_CC));
944 }
945
946 // Notifications with long message text should not make the dialog bigger.
947 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, LongNotifications) {
948   const gfx::Size no_notification_size = GetViewTester()->GetSize();
949   ASSERT_GT(no_notification_size.width(), 0);
950
951   std::vector<DialogNotification> notifications;
952   notifications.push_back(
953       DialogNotification(DialogNotification::DEVELOPER_WARNING, ASCIIToUTF16(
954           "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do "
955           "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim "
956           "ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut "
957           "aliquip ex ea commodo consequat. Duis aute irure dolor in "
958           "reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla "
959           "pariatur. Excepteur sint occaecat cupidatat non proident, sunt in "
960           "culpa qui officia deserunt mollit anim id est laborum.")));
961   controller()->set_notifications(notifications);
962   controller()->view()->UpdateNotificationArea();
963
964   EXPECT_EQ(no_notification_size.width(),
965             GetViewTester()->GetSize().width());
966 }
967
968 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AutocompleteEvent) {
969   AutofillDialogControllerImpl* controller =
970       SetUpHtmlAndInvoke("<input autocomplete='cc-name'>");
971   ASSERT_TRUE(controller);
972
973   AddCreditcardToProfile(controller->profile(), test::GetVerifiedCreditCard());
974   AddAutofillProfileToProfile(controller->profile(),
975                               test::GetVerifiedProfile());
976
977   scoped_ptr<AutofillDialogViewTester> view =
978       AutofillDialogViewTester::For(
979           static_cast<TestAutofillDialogController*>(controller)->view());
980   view->SetTextContentsOfSuggestionInput(SECTION_CC, ASCIIToUTF16("123"));
981   view->SubmitForTesting();
982   ExpectDomMessage("success");
983 }
984
985 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
986                        AutocompleteErrorEventReasonInvalid) {
987   AutofillDialogControllerImpl* controller =
988       SetUpHtmlAndInvoke("<input autocomplete='cc-name' pattern='.*zebra.*'>");
989   ASSERT_TRUE(controller);
990
991   const CreditCard& credit_card = test::GetVerifiedCreditCard();
992   ASSERT_TRUE(
993       credit_card.GetRawInfo(CREDIT_CARD_NAME).find(ASCIIToUTF16("zebra")) ==
994           base::string16::npos);
995   AddCreditcardToProfile(controller->profile(), credit_card);
996   AddAutofillProfileToProfile(controller->profile(),
997                               test::GetVerifiedProfile());
998
999   scoped_ptr<AutofillDialogViewTester> view =
1000       AutofillDialogViewTester::For(
1001           static_cast<TestAutofillDialogController*>(controller)->view());
1002   view->SetTextContentsOfSuggestionInput(SECTION_CC, ASCIIToUTF16("123"));
1003   view->SubmitForTesting();
1004   ExpectDomMessage("error: invalid");
1005
1006   int invalid_count = -1;
1007   ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
1008       GetRenderViewHost(), "send(invalidEvents.length);", &invalid_count));
1009   EXPECT_EQ(1, invalid_count);
1010
1011   std::string invalid_type;
1012   ASSERT_TRUE(content::ExecuteScriptAndExtractString(
1013       GetRenderViewHost(),
1014       "send(invalidEvents[0].target.autocomplete);",
1015       &invalid_type));
1016   EXPECT_EQ("cc-name", invalid_type);
1017 }
1018
1019 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1020                        AutocompleteErrorEventReasonCancel) {
1021   AutofillDialogControllerImpl* controller =
1022       SetUpHtmlAndInvoke("<input autocomplete='cc-name'>");
1023   ASSERT_TRUE(controller);
1024   AutofillDialogViewTester::For(
1025       static_cast<TestAutofillDialogController*>(controller)->view())->
1026           CancelForTesting();
1027   ExpectDomMessage("error: cancel");
1028 }
1029
1030 // http://crbug.com/318526
1031 #if defined(OS_MACOSX)
1032 #define MAYBE_ErrorWithFrameNavigation DISABLED_ErrorWithFrameNavigation
1033 #else
1034 #define MAYBE_ErrorWithFrameNavigation ErrorWithFrameNavigation
1035 #endif
1036 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1037                        MAYBE_ErrorWithFrameNavigation) {
1038   AutofillDialogControllerImpl* controller =
1039       SetUpHtmlAndInvoke("<input autocomplete='cc-name'>");
1040   ASSERT_TRUE(controller);
1041
1042   std::string unused;
1043   ASSERT_TRUE(content::ExecuteScriptAndExtractString(GetRenderViewHost(),
1044                                                      "loadIframe();",
1045                                                      &unused));
1046   ExpectDomMessage("iframe loaded");
1047
1048   AutofillDialogViewTester::For(
1049       static_cast<TestAutofillDialogController*>(controller)->view())->
1050           CancelForTesting();
1051   ExpectDomMessage("error: cancel");
1052 }
1053
1054 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, NoCvcSegfault) {
1055   controller()->set_use_validation(true);
1056
1057   CreditCard credit_card(test::GetVerifiedCreditCard());
1058   controller()->GetTestingManager()->AddTestingCreditCard(&credit_card);
1059   EXPECT_FALSE(controller()->IsEditingExistingData(SECTION_CC));
1060
1061   ASSERT_NO_FATAL_FAILURE(GetViewTester()->SubmitForTesting());
1062 }
1063
1064 // Flaky on Win7, WinXP, and Win Aura.  http://crbug.com/270314.
1065 #if defined(OS_WIN)
1066 #define MAYBE_PreservedSections DISABLED_PreservedSections
1067 #else
1068 #define MAYBE_PreservedSections PreservedSections
1069 #endif
1070 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, MAYBE_PreservedSections) {
1071   controller()->set_use_validation(true);
1072
1073   scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1074   view->SetTextContentsOfInput(CREDIT_CARD_NUMBER,
1075                                ASCIIToUTF16("4111111111111111"));
1076
1077   // Create some invalid, manually inputted shipping data.
1078   view->SetTextContentsOfInput(ADDRESS_HOME_ZIP, ASCIIToUTF16("shipping zip"));
1079
1080   // Switch to Wallet by simulating a successful server response.
1081   controller()->OnDidFetchWalletCookieValue(std::string());
1082   controller()->OnDidGetWalletItems(
1083       wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED));
1084   ASSERT_TRUE(controller()->IsPayingWithWallet());
1085
1086   // The valid data should be preserved.
1087   EXPECT_EQ(ASCIIToUTF16("4111111111111111"),
1088             view->GetTextContentsOfInput(CREDIT_CARD_NUMBER));
1089
1090   // The invalid data should be dropped.
1091   EXPECT_TRUE(view->GetTextContentsOfInput(ADDRESS_HOME_ZIP).empty());
1092
1093   // Switch back to Autofill.
1094   ui::MenuModel* account_chooser = controller()->MenuModelForAccountChooser();
1095   account_chooser->ActivatedAt(account_chooser->GetItemCount() - 1);
1096   ASSERT_FALSE(controller()->IsPayingWithWallet());
1097
1098   // The valid data should still be preserved when switched back.
1099   EXPECT_EQ(ASCIIToUTF16("4111111111111111"),
1100             view->GetTextContentsOfInput(CREDIT_CARD_NUMBER));
1101 }
1102
1103 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1104                        GeneratedCardLastFourAfterVerifyCvv) {
1105   controller()->OnDidFetchWalletCookieValue(std::string());
1106
1107   scoped_ptr<wallet::WalletItems> wallet_items =
1108       wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1109   wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1110   wallet_items->AddAddress(wallet::GetTestShippingAddress());
1111
1112   base::string16 last_four =
1113       wallet_items->instruments()[0]->TypeAndLastFourDigits();
1114   controller()->OnDidGetWalletItems(wallet_items.Pass());
1115
1116   scoped_ptr<AutofillDialogViewTester> test_view = GetViewTester();
1117   EXPECT_FALSE(test_view->IsShowingOverlay());
1118   EXPECT_CALL(*controller(), LoadRiskFingerprintData());
1119   controller()->OnAccept();
1120   EXPECT_TRUE(test_view->IsShowingOverlay());
1121
1122   EXPECT_CALL(*controller()->GetTestingWalletClient(), GetFullWallet(_));
1123   scoped_ptr<risk::Fingerprint> fingerprint(new risk::Fingerprint());
1124   fingerprint->mutable_machine_characteristics()->mutable_screen_size()->
1125       set_width(1024);
1126   controller()->OnDidLoadRiskFingerprintData(fingerprint.Pass());
1127
1128   controller()->OnDidGetFullWallet(
1129       wallet::GetTestFullWalletWithRequiredActions(
1130           std::vector<wallet::RequiredAction>(1, wallet::VERIFY_CVV)));
1131
1132   ASSERT_TRUE(controller()->IsSubmitPausedOn(wallet::VERIFY_CVV));
1133
1134   std::string fake_cvc("123");
1135   test_view->SetTextContentsOfSuggestionInput(SECTION_CC_BILLING,
1136                                               ASCIIToUTF16(fake_cvc));
1137
1138   EXPECT_FALSE(test_view->IsShowingOverlay());
1139   EXPECT_CALL(*controller()->GetTestingWalletClient(),
1140               AuthenticateInstrument(_, fake_cvc));
1141   controller()->OnAccept();
1142   EXPECT_TRUE(test_view->IsShowingOverlay());
1143
1144   EXPECT_CALL(metric_logger(),
1145               LogDialogDismissalState(
1146                   AutofillMetrics::DIALOG_ACCEPTED_EXISTING_WALLET_DATA));
1147
1148   EXPECT_CALL(*controller()->GetTestingWalletClient(), GetFullWallet(_));
1149   controller()->OnDidAuthenticateInstrument(true);
1150   controller()->OnDidGetFullWallet(wallet::GetTestFullWallet());
1151   controller()->ForceFinishSubmit();
1152
1153   RunMessageLoop();
1154
1155   EXPECT_EQ(1, test_generated_bubble_controller()->bubbles_shown());
1156   EXPECT_EQ(last_four, test_generated_bubble_controller()->backing_card_name());
1157 }
1158
1159 // Simulates the user signing in to the dialog from the inline web contents.
1160 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, SimulateSuccessfulSignIn) {
1161 #if defined(OS_WIN)
1162   // TODO(msw): Fix potential flakiness on Windows XP; http://crbug.com/333641
1163   if (base::win::GetVersion() <= base::win::VERSION_XP)
1164     return;
1165 #endif
1166   browser()->profile()->GetPrefs()->SetBoolean(
1167       ::prefs::kAutofillDialogPayWithoutWallet,
1168       true);
1169
1170   InitializeController();
1171
1172   controller()->OnDidFetchWalletCookieValue(std::string());
1173   controller()->OnDidGetWalletItems(
1174       wallet::GetTestWalletItemsWithRequiredAction(wallet::GAIA_AUTH));
1175
1176   NavEntryCommittedObserver sign_in_page_observer(
1177       controller()->SignInUrl(),
1178       content::NotificationService::AllSources());
1179
1180   // Simulate a user clicking "Sign In" (which loads dialog's web contents).
1181   controller()->SignInLinkClicked();
1182   EXPECT_TRUE(controller()->ShouldShowSignInWebView());
1183
1184   scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1185   content::WebContents* sign_in_contents = view->GetSignInWebContents();
1186   ASSERT_TRUE(sign_in_contents);
1187
1188   sign_in_page_observer.Wait();
1189
1190   NavEntryCommittedObserver continue_page_observer(
1191       wallet::GetSignInContinueUrl(),
1192       content::NotificationService::AllSources());
1193
1194   EXPECT_EQ(sign_in_contents->GetURL(), controller()->SignInUrl());
1195
1196   AccountChooserModel* account_chooser_model =
1197       controller()->AccountChooserModelForTesting();
1198   EXPECT_FALSE(account_chooser_model->WalletIsSelected());
1199
1200   content::OpenURLParams params(wallet::GetSignInContinueUrl(),
1201                                 content::Referrer(),
1202                                 CURRENT_TAB,
1203                                 ui::PAGE_TRANSITION_LINK,
1204                                 true);
1205
1206   sign_in_contents->GetDelegate()->OpenURLFromTab(sign_in_contents, params);
1207
1208   EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems(_, _));
1209   continue_page_observer.Wait();
1210   content::RunAllPendingInMessageLoop();
1211
1212   EXPECT_FALSE(controller()->ShouldShowSignInWebView());
1213
1214   scoped_ptr<wallet::WalletItems> wallet_items =
1215       wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1216   wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
1217   controller()->OnDidGetWalletItems(wallet_items.Pass());
1218
1219   // Wallet should now be selected and Chrome shouldn't have crashed (which can
1220   // happen if the WebContents is deleted while proccessing a nav entry commit).
1221   EXPECT_TRUE(account_chooser_model->WalletIsSelected());
1222   EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_CC_BILLING));
1223   EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
1224
1225   EXPECT_CALL(metric_logger(),
1226               LogDialogDismissalState(
1227                   AutofillMetrics::DIALOG_ACCEPTED_EXISTING_WALLET_DATA));
1228   view->SubmitForTesting();
1229   controller()->OnDidGetFullWallet(wallet::GetTestFullWallet());
1230   controller()->ForceFinishSubmit();
1231 }
1232
1233 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AddAccount) {
1234 #if defined(OS_WIN)
1235   // TODO(msw): Fix potential flakiness on Windows XP; http://crbug.com/333641
1236   if (base::win::GetVersion() <= base::win::VERSION_XP)
1237     return;
1238 #endif
1239
1240   controller()->OnDidFetchWalletCookieValue(std::string());
1241   std::vector<std::string> usernames;
1242   usernames.push_back("user_0@example.com");
1243   controller()->OnDidGetWalletItems(
1244       wallet::GetTestWalletItemsWithUsers(usernames, 0));
1245
1246   // Switch to Autofill.
1247   AccountChooserModel* account_chooser_model =
1248       controller()->AccountChooserModelForTesting();
1249   account_chooser_model->ActivatedAt(
1250       account_chooser_model->GetItemCount() - 1);
1251
1252   NavEntryCommittedObserver sign_in_page_observer(
1253       controller()->SignInUrl(),
1254       content::NotificationService::AllSources());
1255
1256   // Simulate a user clicking "add account".
1257   account_chooser_model->ActivatedAt(
1258       account_chooser_model->GetItemCount() - 2);
1259   EXPECT_TRUE(controller()->ShouldShowSignInWebView());
1260
1261   scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1262   content::WebContents* sign_in_contents = view->GetSignInWebContents();
1263   ASSERT_TRUE(sign_in_contents);
1264
1265   sign_in_page_observer.Wait();
1266
1267   NavEntryCommittedObserver continue_page_observer(
1268       wallet::GetSignInContinueUrl(),
1269       content::NotificationService::AllSources());
1270
1271   EXPECT_EQ(sign_in_contents->GetURL(), controller()->SignInUrl());
1272
1273   EXPECT_FALSE(account_chooser_model->WalletIsSelected());
1274
1275   // User signs into new account, account 3.
1276   controller()->set_sign_in_user_index(3U);
1277   content::OpenURLParams params(wallet::GetSignInContinueUrl(),
1278                                 content::Referrer(),
1279                                 CURRENT_TAB,
1280                                 ui::PAGE_TRANSITION_LINK,
1281                                 true);
1282   sign_in_contents->GetDelegate()->OpenURLFromTab(sign_in_contents, params);
1283
1284   EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems(_, _));
1285   continue_page_observer.Wait();
1286   content::RunAllPendingInMessageLoop();
1287
1288   EXPECT_FALSE(controller()->ShouldShowSignInWebView());
1289   EXPECT_EQ(3U, controller()->GetTestingWalletClient()->user_index());
1290
1291   usernames.push_back("user_1@example.com");
1292   usernames.push_back("user_2@example.com");
1293   usernames.push_back("user_3@example.com");
1294   usernames.push_back("user_4@example.com");
1295   // Curveball: wallet items comes back with user 4 selected.
1296   controller()->OnDidGetWalletItems(
1297       wallet::GetTestWalletItemsWithUsers(usernames, 4U));
1298
1299   EXPECT_TRUE(account_chooser_model->WalletIsSelected());
1300   EXPECT_EQ(4U, account_chooser_model->GetActiveWalletAccountIndex());
1301   EXPECT_EQ(4U, controller()->GetTestingWalletClient()->user_index());
1302 }
1303
1304 // Verify that filling a form works correctly, including filling the CVC when
1305 // that is requested separately.
1306 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1307                        FillFormIncludesCVC) {
1308   AutofillDialogControllerImpl* controller =
1309       SetUpHtmlAndInvoke("<input autocomplete='cc-csc'>");
1310   ASSERT_TRUE(controller);
1311
1312   AddCreditcardToProfile(controller->profile(), test::GetVerifiedCreditCard());
1313   AddAutofillProfileToProfile(controller->profile(),
1314                               test::GetVerifiedProfile());
1315
1316   scoped_ptr<AutofillDialogViewTester> view =
1317       AutofillDialogViewTester::For(
1318           static_cast<TestAutofillDialogController*>(controller)->view());
1319   view->SetTextContentsOfSuggestionInput(SECTION_CC, ASCIIToUTF16("123"));
1320   view->SubmitForTesting();
1321   ExpectDomMessage("success");
1322   EXPECT_EQ("123", GetValueForHTMLFieldOfType("cc-csc"));
1323 }
1324
1325 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AddNewClearsComboboxes) {
1326   // Ensure the input under test is a combobox.
1327   ASSERT_TRUE(
1328       controller()->ComboboxModelForAutofillType(CREDIT_CARD_EXP_MONTH));
1329
1330   // Set up an expired card.
1331   CreditCard card;
1332   test::SetCreditCardInfo(&card, "Roy Demeo", "4111111111111111", "8", "2013");
1333   card.set_origin("Chrome settings");
1334   ASSERT_TRUE(card.IsVerified());
1335
1336   // Add the card and check that there's a menu for that section.
1337   controller()->GetTestingManager()->AddTestingCreditCard(&card);
1338   ASSERT_TRUE(controller()->MenuModelForSection(SECTION_CC));
1339
1340   // Select the invalid, suggested card from the menu.
1341   controller()->MenuModelForSection(SECTION_CC)->ActivatedAt(0);
1342   EXPECT_TRUE(controller()->IsEditingExistingData(SECTION_CC));
1343
1344   // Get the contents of the combobox of the credit card's expiration month.
1345   scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1346   base::string16 cc_exp_month_text =
1347       view->GetTextContentsOfInput(CREDIT_CARD_EXP_MONTH);
1348
1349   // Select "New X..." from the suggestion menu to clear the section's inputs.
1350   controller()->MenuModelForSection(SECTION_CC)->ActivatedAt(1);
1351   EXPECT_FALSE(controller()->IsEditingExistingData(SECTION_CC));
1352
1353   // Ensure that the credit card expiration month has changed.
1354   EXPECT_NE(cc_exp_month_text,
1355             view->GetTextContentsOfInput(CREDIT_CARD_EXP_MONTH));
1356 }
1357
1358 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, TabOpensToJustRight) {
1359   ASSERT_TRUE(browser()->is_type_tabbed());
1360
1361   // Tabs should currently be: / rAc() \.
1362   content::WebContents* dialog_invoker = controller()->GetWebContents();
1363   EXPECT_EQ(dialog_invoker, GetActiveWebContents());
1364
1365   TabStripModel* tab_strip = browser()->tab_strip_model();
1366   ASSERT_EQ(1, tab_strip->count());
1367   EXPECT_EQ(0, tab_strip->GetIndexOfWebContents(dialog_invoker));
1368
1369   // Open a tab to about:blank in the background at the end of the tab strip.
1370   chrome::AddTabAt(browser(), GURL(), -1, false);
1371   // Tabs should now be: / rAc() \/ blank \.
1372   EXPECT_EQ(2, tab_strip->count());
1373   EXPECT_EQ(0, tab_strip->active_index());
1374   EXPECT_EQ(dialog_invoker, GetActiveWebContents());
1375
1376   content::WebContents* blank_tab = tab_strip->GetWebContentsAt(1);
1377
1378   // Simulate clicking "Manage X...".
1379   controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1380   // Tab should now be: / rAc() \/ manage 1 \/ blank \.
1381   EXPECT_EQ(3, tab_strip->count());
1382   int dialog_index = tab_strip->GetIndexOfWebContents(dialog_invoker);
1383   EXPECT_EQ(0, dialog_index);
1384   EXPECT_EQ(1, tab_strip->active_index());
1385   EXPECT_EQ(2, tab_strip->GetIndexOfWebContents(blank_tab));
1386
1387   content::WebContents* first_manage_tab = tab_strip->GetWebContentsAt(1);
1388
1389   // Re-activate the dialog's tab (like a user would have to).
1390   tab_strip->ActivateTabAt(dialog_index, true);
1391   EXPECT_EQ(dialog_invoker, GetActiveWebContents());
1392
1393   // Simulate clicking "Manage X...".
1394   controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1395   // Tabs should now be: / rAc() \/ manage 2 \/ manage 1 \/ blank \.
1396   EXPECT_EQ(4, tab_strip->count());
1397   EXPECT_EQ(0, tab_strip->GetIndexOfWebContents(dialog_invoker));
1398   EXPECT_EQ(1, tab_strip->active_index());
1399   EXPECT_EQ(2, tab_strip->GetIndexOfWebContents(first_manage_tab));
1400   EXPECT_EQ(3, tab_strip->GetIndexOfWebContents(blank_tab));
1401 }
1402
1403 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1404                        SignInWebViewOpensLinksInNewTab) {
1405   controller()->OnDidFetchWalletCookieValue(std::string());
1406   controller()->OnDidGetWalletItems(
1407       wallet::GetTestWalletItemsWithRequiredAction(wallet::GAIA_AUTH));
1408
1409   NavEntryCommittedObserver sign_in_page_observer(
1410       controller()->SignInUrl(),
1411       content::NotificationService::AllSources());
1412
1413   controller()->SignInLinkClicked();
1414
1415   content::WebContents* sign_in_contents =
1416       GetViewTester()->GetSignInWebContents();
1417   ASSERT_TRUE(sign_in_contents);
1418
1419   sign_in_page_observer.Wait();
1420
1421   content::OpenURLParams params(GURL("http://google.com"),
1422                                 content::Referrer(),
1423                                 CURRENT_TAB,
1424                                 ui::PAGE_TRANSITION_LINK,
1425                                 true);
1426   params.user_gesture = true;
1427
1428   int num_tabs = browser()->tab_strip_model()->count();
1429   sign_in_contents->GetDelegate()->OpenURLFromTab(sign_in_contents, params);
1430   EXPECT_EQ(num_tabs + 1, browser()->tab_strip_model()->count());
1431 }
1432
1433 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, RefreshOnManageTabClose) {
1434   ASSERT_TRUE(browser()->is_type_tabbed());
1435
1436   // GetWalletItems(_, _) is called when controller() is created in SetUp().
1437   EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems(_, _));
1438   controller()->OnDidFetchWalletCookieValue(std::string());
1439   controller()->OnDidGetWalletItems(
1440       wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED));
1441
1442   content::WebContents* dialog_invoker = controller()->GetWebContents();
1443   ChromeAutofillClient::FromWebContents(dialog_invoker)
1444       ->SetDialogControllerForTesting(controller()->AsWeakPtr());
1445
1446   // Open a new tab by selecting "Manage my shipping details..." in Wallet mode.
1447   EXPECT_EQ(1, browser()->tab_strip_model()->count());
1448   controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1449   EXPECT_EQ(2, browser()->tab_strip_model()->count());
1450   ASSERT_NE(dialog_invoker, GetActiveWebContents());
1451
1452   // Closing the tab opened by "Manage my shipping details..." should refresh
1453   // the dialog.
1454   controller()->ClearLastWalletItemsFetchTimestampForTesting();
1455   EXPECT_CALL(*controller()->GetTestingWalletClient(), GetWalletItems(_, _));
1456   GetActiveWebContents()->Close();
1457 }
1458
1459 // Changes from Wallet to Autofill and verifies that the combined billing/cc
1460 // sections are showing (or not) at the correct times.
1461 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1462                        ChangingDataSourceShowsCorrectSections) {
1463   scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1464   EXPECT_TRUE(view->IsShowingSection(SECTION_CC));
1465   EXPECT_TRUE(view->IsShowingSection(SECTION_BILLING));
1466   EXPECT_FALSE(view->IsShowingSection(SECTION_CC_BILLING));
1467
1468   // Switch the dialog to paying with Wallet.
1469   controller()->OnDidFetchWalletCookieValue(std::string());
1470   controller()->OnDidGetWalletItems(
1471       wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED));
1472   ASSERT_TRUE(controller()->IsPayingWithWallet());
1473
1474   EXPECT_FALSE(view->IsShowingSection(SECTION_CC));
1475   EXPECT_FALSE(view->IsShowingSection(SECTION_BILLING));
1476   EXPECT_TRUE(view->IsShowingSection(SECTION_CC_BILLING));
1477
1478   // Now switch back to Autofill to ensure this direction works as well.
1479   ui::MenuModel* account_chooser = controller()->MenuModelForAccountChooser();
1480   account_chooser->ActivatedAt(account_chooser->GetItemCount() - 1);
1481
1482   EXPECT_TRUE(view->IsShowingSection(SECTION_CC));
1483   EXPECT_TRUE(view->IsShowingSection(SECTION_BILLING));
1484   EXPECT_FALSE(view->IsShowingSection(SECTION_CC_BILLING));
1485 }
1486
1487 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1488                        DoesWorkOnHttpWithFlag) {
1489   net::SpawnedTestServer http_server(
1490       net::SpawnedTestServer::TYPE_HTTP,
1491       net::SpawnedTestServer::kLocalhost,
1492       base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1493   ASSERT_TRUE(http_server.Start());
1494   EXPECT_TRUE(RunTestPage(http_server));
1495 }
1496
1497 // Like the parent test, but doesn't add the --reduce-security-for-testing flag.
1498 class AutofillDialogControllerSecurityTest :
1499     public AutofillDialogControllerTest {
1500  public:
1501   AutofillDialogControllerSecurityTest() {}
1502   virtual ~AutofillDialogControllerSecurityTest() {}
1503
1504   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1505     CHECK(!command_line->HasSwitch(::switches::kReduceSecurityForTesting));
1506   }
1507
1508   typedef net::BaseTestServer::SSLOptions SSLOptions;
1509
1510  private:
1511   DISALLOW_COPY_AND_ASSIGN(AutofillDialogControllerSecurityTest);
1512 };
1513
1514 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerSecurityTest,
1515                        DoesntWorkOnHttp) {
1516   net::SpawnedTestServer http_server(
1517       net::SpawnedTestServer::TYPE_HTTP,
1518       net::SpawnedTestServer::kLocalhost,
1519       base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1520   ASSERT_TRUE(http_server.Start());
1521   EXPECT_FALSE(RunTestPage(http_server));
1522 }
1523
1524 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerSecurityTest,
1525                        DoesWorkOnHttpWithFlags) {
1526   net::SpawnedTestServer https_server(
1527       net::SpawnedTestServer::TYPE_HTTPS,
1528       SSLOptions(SSLOptions::CERT_OK),
1529       base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1530   ASSERT_TRUE(https_server.Start());
1531   EXPECT_TRUE(RunTestPage(https_server));
1532 }
1533
1534 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerSecurityTest,
1535                        DoesntWorkOnBrokenHttps) {
1536   net::SpawnedTestServer https_server(
1537       net::SpawnedTestServer::TYPE_HTTPS,
1538       SSLOptions(SSLOptions::CERT_EXPIRED),
1539       base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1540   ASSERT_TRUE(https_server.Start());
1541   EXPECT_FALSE(RunTestPage(https_server));
1542 }
1543
1544 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1545                        CountryChangeRebuildsSection) {
1546   EXPECT_FALSE(SectionHasField(SECTION_BILLING, ADDRESS_BILLING_SORTING_CODE));
1547   EXPECT_FALSE(SectionHasField(SECTION_SHIPPING, ADDRESS_HOME_SORTING_CODE));
1548
1549   // Select "Add new shipping address...".
1550   controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(1);
1551
1552   // Add some valid user input that should be preserved when country changes.
1553   scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1554   view->SetTextContentsOfInput(NAME_FULL, ASCIIToUTF16("B. Loblaw"));
1555
1556   // Change both sections' countries.
1557   view->SetTextContentsOfInput(ADDRESS_BILLING_COUNTRY, ASCIIToUTF16("France"));
1558   view->ActivateInput(ADDRESS_BILLING_COUNTRY);
1559   view->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("Belarus"));
1560   view->ActivateInput(ADDRESS_HOME_COUNTRY);
1561
1562   // Verify the name is still there.
1563   EXPECT_EQ(ASCIIToUTF16("B. Loblaw"), view->GetTextContentsOfInput(NAME_FULL));
1564
1565   EXPECT_TRUE(SectionHasField(SECTION_BILLING, ADDRESS_BILLING_SORTING_CODE));
1566   EXPECT_TRUE(SectionHasField(SECTION_SHIPPING, ADDRESS_HOME_SORTING_CODE));
1567 }
1568
1569 // Changing the data source to or from Wallet preserves the shipping country,
1570 // but not the billing country because Wallet only supports US billing
1571 // addresses.
1572 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1573                        ChangingDataSourcePreservesCountry) {
1574   InitializeControllerWithoutShowing();
1575   controller()->GetTestingManager()->set_default_country_code("CA");
1576   controller()->Show();
1577   CycleRunLoops();
1578
1579   AutofillProfile verified_profile(test::GetVerifiedProfile());
1580   controller()->GetTestingManager()->AddTestingProfile(&verified_profile);
1581
1582   CreditCard verified_card(test::GetVerifiedCreditCard());
1583   controller()->GetTestingManager()->AddTestingCreditCard(&verified_card);
1584   EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
1585
1586   controller()->OnDidFetchWalletCookieValue(std::string());
1587   scoped_ptr<wallet::WalletItems> items =
1588       wallet::GetTestWalletItems(wallet::AMEX_DISALLOWED);
1589   items->AddAccount(wallet::GetTestGaiaAccount());
1590   items->AddInstrument(wallet::GetTestMaskedInstrument());
1591   items->AddAddress(wallet::GetTestShippingAddress());
1592   controller()->OnDidGetWalletItems(items.Pass());
1593
1594   EXPECT_TRUE(controller()->IsPayingWithWallet());
1595
1596   // Select "Add new shipping address...".
1597   controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1598   EXPECT_TRUE(controller()->IsManuallyEditingSection(SECTION_SHIPPING));
1599
1600   // Default shipping country matches PDM's default, but default billing is
1601   // always US in Wallet mode.
1602   scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1603   ASSERT_EQ(ASCIIToUTF16("Canada"),
1604             view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1605   ASSERT_EQ(ASCIIToUTF16("United States"),
1606             view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1607
1608   // Switch the shipping country.
1609   view->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("Belarus"));
1610   EXPECT_EQ(ASCIIToUTF16("Belarus"),
1611             view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1612   view->ActivateInput(ADDRESS_HOME_COUNTRY);
1613
1614   // Switch to using Autofill instead of Wallet.
1615   ui::MenuModel* account_chooser = controller()->MenuModelForAccountChooser();
1616   account_chooser->ActivatedAt(account_chooser->GetItemCount() - 1);
1617
1618   EXPECT_FALSE(controller()->IsPayingWithWallet());
1619
1620   // Shipping country should have stayed the same.
1621   EXPECT_EQ(ASCIIToUTF16("Belarus"),
1622             view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1623   ASSERT_TRUE(SectionHasField(SECTION_SHIPPING, ADDRESS_HOME_SORTING_CODE));
1624
1625   controller()->MenuModelForSection(SECTION_BILLING)->ActivatedAt(1);
1626   view->SetTextContentsOfInput(ADDRESS_BILLING_COUNTRY,
1627                                ASCIIToUTF16("Belarus"));
1628   view->ActivateInput(ADDRESS_BILLING_COUNTRY);
1629   EXPECT_EQ(ASCIIToUTF16("Belarus"),
1630             view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1631   ASSERT_TRUE(SectionHasField(SECTION_BILLING, ADDRESS_BILLING_SORTING_CODE));
1632
1633   // Switch back to Wallet. Country should go back to US.
1634   account_chooser->ActivatedAt(0);
1635   EXPECT_EQ(ASCIIToUTF16("United States"),
1636             view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1637   ASSERT_FALSE(
1638       SectionHasField(SECTION_CC_BILLING, ADDRESS_BILLING_SORTING_CODE));
1639
1640   // Make sure shipping is still on Belarus.
1641   EXPECT_EQ(ASCIIToUTF16("Belarus"),
1642             view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1643   ASSERT_TRUE(SectionHasField(SECTION_SHIPPING, ADDRESS_HOME_SORTING_CODE));
1644 }
1645
1646 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, AddNewResetsCountry) {
1647   AutofillProfile verified_profile(test::GetVerifiedProfile());
1648   controller()->GetTestingManager()->AddTestingProfile(&verified_profile);
1649
1650   // Select "Add new billing/shipping address...".
1651   controller()->MenuModelForSection(SECTION_BILLING)->ActivatedAt(1);
1652   controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1653
1654   scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1655   ASSERT_EQ(ASCIIToUTF16("United States"),
1656             view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1657   ASSERT_EQ(ASCIIToUTF16("United States"),
1658             view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1659
1660   // Switch both billing and shipping countries.
1661   view->SetTextContentsOfInput(ADDRESS_BILLING_COUNTRY, ASCIIToUTF16("Brazil"));
1662   view->ActivateInput(ADDRESS_BILLING_COUNTRY);
1663   view->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("France"));
1664   view->ActivateInput(ADDRESS_HOME_COUNTRY);
1665
1666   // Select "Add new billing/shipping address...".
1667   controller()->MenuModelForSection(SECTION_BILLING)->ActivatedAt(1);
1668   controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(2);
1669
1670   EXPECT_EQ(ASCIIToUTF16("United States"),
1671             view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1672   EXPECT_EQ(ASCIIToUTF16("United States"),
1673             view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1674 }
1675
1676 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1677                        FillingFormRebuildsInputs) {
1678   AutofillProfile full_profile(test::GetFullProfile());
1679   full_profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("DE"));
1680   controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1681
1682   // Select "Add new shipping address...".
1683   controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(1);
1684
1685   scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1686   ASSERT_EQ(ASCIIToUTF16("United States"),
1687             view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1688   ASSERT_EQ(ASCIIToUTF16("United States"),
1689             view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1690
1691   const ServerFieldType input_type = EMAIL_ADDRESS;
1692   base::string16 name = full_profile.GetRawInfo(input_type);
1693   view->SetTextContentsOfInput(input_type, name.substr(0, name.size() / 2));
1694   view->ActivateInput(input_type);
1695   ASSERT_EQ(input_type, controller()->popup_input_type());
1696   controller()->DidAcceptSuggestion(base::string16(), 0);
1697
1698   EXPECT_EQ(ASCIIToUTF16("Germany"),
1699             view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1700   EXPECT_EQ(ASCIIToUTF16("United States"),
1701             view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1702 }
1703
1704 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1705                        FillingFormPreservesChangedCountry) {
1706   AutofillProfile full_profile(test::GetFullProfile());
1707   full_profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("DE"));
1708   controller()->GetTestingManager()->AddTestingProfile(&full_profile);
1709
1710   // Select "Add new shipping address...".
1711   controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(1);
1712
1713   scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1714   view->SetTextContentsOfInput(ADDRESS_BILLING_COUNTRY, ASCIIToUTF16("France"));
1715   view->ActivateInput(ADDRESS_BILLING_COUNTRY);
1716   view->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("Belarus"));
1717   view->ActivateInput(ADDRESS_HOME_COUNTRY);
1718
1719   base::string16 name = full_profile.GetRawInfo(NAME_FULL);
1720   view->SetTextContentsOfInput(NAME_FULL, name.substr(0, name.size() / 2));
1721   view->ActivateInput(NAME_FULL);
1722   ASSERT_EQ(NAME_FULL, controller()->popup_input_type());
1723   controller()->DidAcceptSuggestion(base::string16(), 0);
1724
1725   EXPECT_EQ(ASCIIToUTF16("France"),
1726             view->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY));
1727   EXPECT_EQ(ASCIIToUTF16("Belarus"),
1728             view->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY));
1729 }
1730
1731 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, RulesLoaded) {
1732   // Select "Add new shipping address...".
1733   controller()->MenuModelForSection(SECTION_SHIPPING)->ActivatedAt(1);
1734   controller()->set_use_validation(true);
1735
1736   EXPECT_CALL(*controller()->GetMockValidator(),
1737               ValidateAddress(CountryCodeMatcher("DE"), _, _)).Times(2).
1738               WillOnce(Return(AddressValidator::RULES_NOT_READY));
1739
1740   // Validation should occur on country change and see the rules haven't loaded.
1741   scoped_ptr<AutofillDialogViewTester> view = GetViewTester();
1742   view->SetTextContentsOfInput(ADDRESS_HOME_ZIP, ASCIIToUTF16("123"));
1743   view->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("Germany"));
1744   view->ActivateInput(ADDRESS_HOME_COUNTRY);
1745
1746   // Different country loaded, validation should not occur.
1747   controller()->OnAddressValidationRulesLoaded("FR", true);
1748
1749   // Relevant country loaded, validation should occur.
1750   controller()->OnAddressValidationRulesLoaded("DE", true);
1751
1752   // Relevant country loaded but revalidation already happened, no further
1753   // validation should occur.
1754   controller()->OnAddressValidationRulesLoaded("DE", false);
1755
1756   // Cancelling the dialog causes additional validation to see if the user
1757   // cancelled with invalid fields, so verify and clear here.
1758   testing::Mock::VerifyAndClearExpectations(controller()->GetMockValidator());
1759 }
1760
1761 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest,
1762                        TransactionAmount) {
1763   std::string html(
1764       "<input type='number' step='0.01'"
1765       "   autocomplete='transaction-amount' value='24'>"
1766       "<input autocomplete='transaction-currency' value='USD'>"
1767       "<input autocomplete='cc-csc'>");
1768   AutofillDialogControllerImpl* controller = SetUpHtmlAndInvoke(html);
1769   ASSERT_TRUE(controller);
1770
1771   EXPECT_EQ(ASCIIToUTF16("24"), controller->transaction_amount_);
1772   EXPECT_EQ(ASCIIToUTF16("USD"), controller->transaction_currency_);
1773 }
1774
1775 }  // namespace autofill