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