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