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