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