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