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