Home | History | Annotate | Download | only in autofill
      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 (at) example.com"));
    769   emails.push_back(ASCIIToUTF16("admin (at) 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 (at) 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 (at) example.com");
   1292   usernames.push_back("user_2 (at) example.com");
   1293   usernames.push_back("user_3 (at) example.com");
   1294   usernames.push_back("user_4 (at) 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
   1776