autofill_dialog_controller_unittest.cc revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
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/guid.h" 6#include "base/memory/scoped_ptr.h" 7#include "base/message_loop.h" 8#include "base/prefs/pref_service.h" 9#include "base/utf_string_conversions.h" 10#include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h" 11#include "chrome/browser/ui/autofill/autofill_dialog_view.h" 12#include "chrome/common/pref_names.h" 13#include "chrome/test/base/testing_profile.h" 14#include "components/autofill/browser/autofill_common_test.h" 15#include "components/autofill/browser/autofill_metrics.h" 16#include "components/autofill/browser/test_personal_data_manager.h" 17#include "components/autofill/browser/wallet/full_wallet.h" 18#include "components/autofill/browser/wallet/instrument.h" 19#include "components/autofill/browser/wallet/wallet_address.h" 20#include "components/autofill/browser/wallet/wallet_client.h" 21#include "components/autofill/browser/wallet/wallet_test_util.h" 22#include "components/autofill/common/form_data.h" 23#include "content/public/browser/web_contents.h" 24#include "content/public/test/test_browser_thread.h" 25#include "content/public/test/web_contents_tester.h" 26#include "testing/gmock/include/gmock/gmock.h" 27#include "testing/gtest/include/gtest/gtest.h" 28 29#if defined(OS_WIN) 30#include "ui/base/win/scoped_ole_initializer.h" 31#endif 32 33using testing::_; 34 35namespace autofill { 36 37namespace { 38 39const char kFakeEmail[] = "user@example.com"; 40const char* kFieldsFromPage[] = { "email", "cc-number", "billing region", 41 "shipping region" }; 42const char kSettingsOrigin[] = "Chrome settings"; 43 44using content::BrowserThread; 45 46class TestAutofillDialogView : public AutofillDialogView { 47 public: 48 TestAutofillDialogView() {} 49 virtual ~TestAutofillDialogView() {} 50 51 virtual void Show() OVERRIDE {} 52 virtual void Hide() OVERRIDE {} 53 virtual void UpdateNotificationArea() OVERRIDE {} 54 virtual void UpdateAccountChooser() OVERRIDE {} 55 virtual void UpdateButtonStrip() OVERRIDE {} 56 virtual void UpdateDetailArea() OVERRIDE {} 57 virtual void UpdateSection(DialogSection section) OVERRIDE {} 58 virtual void FillSection(DialogSection section, 59 const DetailInput& originating_input) OVERRIDE {}; 60 virtual void GetUserInput(DialogSection section, DetailOutputMap* output) 61 OVERRIDE { 62 *output = outputs_[section]; 63 } 64 65 virtual string16 GetCvc() OVERRIDE { return string16(); } 66 virtual bool SaveDetailsLocally() OVERRIDE { return true; } 67 virtual const content::NavigationController* ShowSignIn() OVERRIDE { 68 return NULL; 69 } 70 virtual void HideSignIn() OVERRIDE {} 71 virtual void UpdateProgressBar(double value) OVERRIDE {} 72 73 MOCK_METHOD0(ModelChanged, void()); 74 75 void SetUserInput(DialogSection section, const DetailOutputMap& map) { 76 outputs_[section] = map; 77 } 78 79 private: 80 std::map<DialogSection, DetailOutputMap> outputs_; 81 82 DISALLOW_COPY_AND_ASSIGN(TestAutofillDialogView); 83}; 84 85class TestWalletClient : public wallet::WalletClient { 86 public: 87 TestWalletClient(net::URLRequestContextGetter* context, 88 wallet::WalletClientDelegate* delegate) 89 : wallet::WalletClient(context, delegate) {} 90 virtual ~TestWalletClient() {} 91 92 MOCK_METHOD3(AcceptLegalDocuments, 93 void(const std::vector<wallet::WalletItems::LegalDocument*>& documents, 94 const std::string& google_transaction_id, 95 const GURL& source_url)); 96 97 MOCK_METHOD3(AuthenticateInstrument, 98 void(const std::string& instrument_id, 99 const std::string& card_verification_number, 100 const std::string& obfuscated_gaia_id)); 101 102 MOCK_METHOD1(GetFullWallet, 103 void(const wallet::WalletClient::FullWalletRequest& request)); 104 105 MOCK_METHOD2(SaveAddress, 106 void(const wallet::Address& address, const GURL& source_url)); 107 108 MOCK_METHOD3(SaveInstrument, 109 void(const wallet::Instrument& instrument, 110 const std::string& obfuscated_gaia_id, 111 const GURL& source_url)); 112 113 MOCK_METHOD4(SaveInstrumentAndAddress, 114 void(const wallet::Instrument& instrument, 115 const wallet::Address& address, 116 const std::string& obfuscated_gaia_id, 117 const GURL& source_url)); 118 119 private: 120 DISALLOW_COPY_AND_ASSIGN(TestWalletClient); 121}; 122 123// Bring over command-ids from AccountChooserModel. 124class TestAccountChooserModel : public AccountChooserModel { 125 public: 126 TestAccountChooserModel(AccountChooserModelDelegate* delegate, 127 PrefService* prefs, 128 const AutofillMetrics& metric_logger) 129 : AccountChooserModel(delegate, prefs, metric_logger, 130 DIALOG_TYPE_REQUEST_AUTOCOMPLETE) {} 131 virtual ~TestAccountChooserModel() {} 132 133 using AccountChooserModel::kActiveWalletItemId; 134 using AccountChooserModel::kAutofillItemId; 135 136 private: 137 DISALLOW_COPY_AND_ASSIGN(TestAccountChooserModel); 138}; 139 140class TestAutofillDialogController 141 : public AutofillDialogControllerImpl, 142 public base::SupportsWeakPtr<TestAutofillDialogController> { 143 public: 144 TestAutofillDialogController( 145 content::WebContents* contents, 146 const FormData& form_structure, 147 const GURL& source_url, 148 const AutofillMetrics& metric_logger, 149 const DialogType dialog_type, 150 const base::Callback<void(const FormStructure*, 151 const std::string&)>& callback) 152 : AutofillDialogControllerImpl(contents, 153 form_structure, 154 source_url, 155 dialog_type, 156 callback), 157 metric_logger_(metric_logger), 158 test_wallet_client_( 159 Profile::FromBrowserContext(contents->GetBrowserContext())-> 160 GetRequestContext(), this), 161 is_first_run_(true) {} 162 virtual ~TestAutofillDialogController() {} 163 164 virtual AutofillDialogView* CreateView() OVERRIDE { 165 return new testing::NiceMock<TestAutofillDialogView>(); 166 } 167 168 void Init(content::BrowserContext* browser_context) { 169 test_manager_.Init(browser_context); 170 } 171 172 TestAutofillDialogView* GetView() { 173 return static_cast<TestAutofillDialogView*>(view()); 174 } 175 176 TestPersonalDataManager* GetTestingManager() { 177 return &test_manager_; 178 } 179 180 TestWalletClient* GetTestingWalletClient() { 181 return &test_wallet_client_; 182 } 183 184 void set_is_first_run(bool is_first_run) { is_first_run_ = is_first_run; } 185 186 const GURL& open_tab_url() { return open_tab_url_; } 187 188 protected: 189 virtual PersonalDataManager* GetManager() OVERRIDE { 190 return &test_manager_; 191 } 192 193 virtual wallet::WalletClient* GetWalletClient() OVERRIDE { 194 return &test_wallet_client_; 195 } 196 197 virtual bool IsFirstRun() const OVERRIDE { 198 return is_first_run_; 199 } 200 201 virtual void OpenTabWithUrl(const GURL& url) OVERRIDE { 202 open_tab_url_ = url; 203 } 204 205 private: 206 // To specify our own metric logger. 207 virtual const AutofillMetrics& GetMetricLogger() const OVERRIDE { 208 return metric_logger_; 209 } 210 211 const AutofillMetrics& metric_logger_; 212 TestPersonalDataManager test_manager_; 213 testing::NiceMock<TestWalletClient> test_wallet_client_; 214 bool is_first_run_; 215 GURL open_tab_url_; 216 217 DISALLOW_COPY_AND_ASSIGN(TestAutofillDialogController); 218}; 219 220class AutofillDialogControllerTest : public testing::Test { 221 public: 222 AutofillDialogControllerTest() 223 : ui_thread_(BrowserThread::UI, &loop_), 224 file_thread_(BrowserThread::FILE), 225 file_blocking_thread_(BrowserThread::FILE_USER_BLOCKING), 226 io_thread_(BrowserThread::IO) { 227 file_thread_.Start(); 228 file_blocking_thread_.Start(); 229 io_thread_.StartIOThread(); 230 } 231 232 virtual ~AutofillDialogControllerTest() {} 233 234 // testing::Test implementation: 235 virtual void SetUp() OVERRIDE { 236 FormData form_data; 237 for (size_t i = 0; i < arraysize(kFieldsFromPage); ++i) { 238 FormFieldData field; 239 field.autocomplete_attribute = kFieldsFromPage[i]; 240 form_data.fields.push_back(field); 241 } 242 243 profile()->CreateRequestContext(); 244 test_web_contents_.reset( 245 content::WebContentsTester::CreateTestWebContents(profile(), NULL)); 246 247 base::Callback<void(const FormStructure*, const std::string&)> callback = 248 base::Bind(&AutofillDialogControllerTest::FinishedCallback, 249 base::Unretained(this)); 250 controller_ = (new TestAutofillDialogController( 251 test_web_contents_.get(), 252 form_data, 253 GURL(), 254 metric_logger_, 255 DIALOG_TYPE_REQUEST_AUTOCOMPLETE, 256 callback))->AsWeakPtr(); 257 controller_->Init(profile()); 258 controller_->Show(); 259 controller_->OnUserNameFetchSuccess(kFakeEmail); 260 } 261 262 virtual void TearDown() OVERRIDE { 263 if (controller_) 264 controller_->ViewClosed(); 265 } 266 267 protected: 268 static scoped_ptr<wallet::FullWallet> CreateFullWalletWithVerifyCvv() { 269 base::DictionaryValue dict; 270 scoped_ptr<base::ListValue> list(new base::ListValue()); 271 list->AppendString("verify_cvv"); 272 dict.Set("required_action", list.release()); 273 return wallet::FullWallet::CreateFullWallet(dict); 274 } 275 276 void FillCreditCardInputs() { 277 DetailOutputMap cc_outputs; 278 const DetailInputs& cc_inputs = 279 controller()->RequestedFieldsForSection(SECTION_CC); 280 for (size_t i = 0; i < cc_inputs.size(); ++i) { 281 cc_outputs[&cc_inputs[i]] = ASCIIToUTF16("11"); 282 } 283 controller()->GetView()->SetUserInput(SECTION_CC, cc_outputs); 284 } 285 286 std::vector<DialogNotification> NotificationsOfType( 287 DialogNotification::Type type) { 288 std::vector<DialogNotification> right_type; 289 const std::vector<DialogNotification>& notifications = 290 controller()->CurrentNotifications(); 291 for (size_t i = 0; i < notifications.size(); ++i) { 292 if (notifications[i].type() == type) 293 right_type.push_back(notifications[i]); 294 } 295 return right_type; 296 } 297 298 void SwitchToAutofill() { 299 controller_->MenuModelForAccountChooser()->ActivatedAt( 300 TestAccountChooserModel::kAutofillItemId); 301 } 302 303 void SwitchToWallet() { 304 controller_->MenuModelForAccountChooser()->ActivatedAt( 305 TestAccountChooserModel::kActiveWalletItemId); 306 } 307 308 TestAutofillDialogController* controller() { return controller_; } 309 310 TestingProfile* profile() { return &profile_; } 311 312 const FormStructure* form_structure() { return form_structure_; } 313 314 private: 315 void FinishedCallback(const FormStructure* form_structure, 316 const std::string& google_transaction_id) { 317 form_structure_ = form_structure; 318 } 319 320#if defined(OS_WIN) 321 // http://crbug.com/227221 322 ui::ScopedOleInitializer ole_initializer_; 323#endif 324 325 // A bunch of threads are necessary for classes like TestWebContents and 326 // URLRequestContextGetter not to fall over. 327 base::MessageLoopForUI loop_; 328 content::TestBrowserThread ui_thread_; 329 content::TestBrowserThread file_thread_; 330 content::TestBrowserThread file_blocking_thread_; 331 content::TestBrowserThread io_thread_; 332 TestingProfile profile_; 333 334 // The controller owns itself. 335 base::WeakPtr<TestAutofillDialogController> controller_; 336 337 scoped_ptr<content::WebContents> test_web_contents_; 338 339 // Must outlive the controller. 340 AutofillMetrics metric_logger_; 341 342 // Returned when the dialog closes successfully. 343 const FormStructure* form_structure_; 344 345 DISALLOW_COPY_AND_ASSIGN(AutofillDialogControllerTest); 346}; 347 348} // namespace 349 350// This test makes sure nothing falls over when fields are being validity- 351// checked. 352TEST_F(AutofillDialogControllerTest, ValidityCheck) { 353 const DialogSection sections[] = { 354 SECTION_EMAIL, 355 SECTION_CC, 356 SECTION_BILLING, 357 SECTION_CC_BILLING, 358 SECTION_SHIPPING 359 }; 360 361 for (size_t i = 0; i < arraysize(sections); ++i) { 362 DialogSection section = sections[i]; 363 const DetailInputs& shipping_inputs = 364 controller()->RequestedFieldsForSection(section); 365 for (DetailInputs::const_iterator iter = shipping_inputs.begin(); 366 iter != shipping_inputs.end(); ++iter) { 367 controller()->InputIsValid(iter->type, string16()); 368 } 369 } 370} 371 372TEST_F(AutofillDialogControllerTest, AutofillProfiles) { 373 ui::MenuModel* shipping_model = 374 controller()->MenuModelForSection(SECTION_SHIPPING); 375 // Since the PersonalDataManager is empty, this should only have the 376 // "use billing", "add new" and "manage" menu items. 377 EXPECT_EQ(3, shipping_model->GetItemCount()); 378 // On the other hand, the other models should be NULL when there's no 379 // suggestion. 380 EXPECT_FALSE(controller()->MenuModelForSection(SECTION_CC)); 381 EXPECT_FALSE(controller()->MenuModelForSection(SECTION_BILLING)); 382 EXPECT_FALSE(controller()->MenuModelForSection(SECTION_EMAIL)); 383 384 EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(2); 385 386 // Empty profiles are ignored. 387 AutofillProfile empty_profile(base::GenerateGUID(), kSettingsOrigin); 388 empty_profile.SetRawInfo(NAME_FULL, ASCIIToUTF16("John Doe")); 389 controller()->GetTestingManager()->AddTestingProfile(&empty_profile); 390 shipping_model = controller()->MenuModelForSection(SECTION_SHIPPING); 391 EXPECT_EQ(3, shipping_model->GetItemCount()); 392 EXPECT_FALSE(controller()->MenuModelForSection(SECTION_EMAIL)); 393 394 // A full profile should be picked up. 395 AutofillProfile full_profile(test::GetFullProfile()); 396 full_profile.set_origin(kSettingsOrigin); 397 full_profile.SetRawInfo(ADDRESS_HOME_LINE2, string16()); 398 controller()->GetTestingManager()->AddTestingProfile(&full_profile); 399 shipping_model = controller()->MenuModelForSection(SECTION_SHIPPING); 400 EXPECT_EQ(4, shipping_model->GetItemCount()); 401 EXPECT_TRUE(!!controller()->MenuModelForSection(SECTION_EMAIL)); 402} 403 404TEST_F(AutofillDialogControllerTest, AutofillProfileVariants) { 405 EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1); 406 ui::MenuModel* email_model = 407 controller()->MenuModelForSection(SECTION_EMAIL); 408 EXPECT_FALSE(email_model); 409 410 // Set up some variant data. 411 AutofillProfile full_profile(test::GetFullProfile()); 412 std::vector<string16> names; 413 names.push_back(ASCIIToUTF16("John Doe")); 414 names.push_back(ASCIIToUTF16("Jane Doe")); 415 full_profile.SetRawMultiInfo(EMAIL_ADDRESS, names); 416 const string16 kEmail1 = ASCIIToUTF16(kFakeEmail); 417 const string16 kEmail2 = ASCIIToUTF16("admin@example.com"); 418 std::vector<string16> emails; 419 emails.push_back(kEmail1); 420 emails.push_back(kEmail2); 421 full_profile.SetRawMultiInfo(EMAIL_ADDRESS, emails); 422 423 // Respect variants for the email address field only. 424 controller()->GetTestingManager()->AddTestingProfile(&full_profile); 425 ui::MenuModel* shipping_model = 426 controller()->MenuModelForSection(SECTION_SHIPPING); 427 EXPECT_EQ(4, shipping_model->GetItemCount()); 428 email_model = controller()->MenuModelForSection(SECTION_EMAIL); 429 ASSERT_TRUE(!!email_model); 430 EXPECT_EQ(4, email_model->GetItemCount()); 431 432 email_model->ActivatedAt(0); 433 EXPECT_EQ(kEmail1, 434 controller()->SuggestionStateForSection(SECTION_EMAIL).text); 435 email_model->ActivatedAt(1); 436 EXPECT_EQ(kEmail2, 437 controller()->SuggestionStateForSection(SECTION_EMAIL).text); 438 439 controller()->EditClickedForSection(SECTION_EMAIL); 440 const DetailInputs& inputs = 441 controller()->RequestedFieldsForSection(SECTION_EMAIL); 442 EXPECT_EQ(kEmail2, inputs[0].initial_value); 443} 444 445// Test selecting a shipping address different from billing as address. 446TEST_F(AutofillDialogControllerTest, DontUseBillingAsShipping) { 447 AutofillProfile full_profile(test::GetFullProfile()); 448 AutofillProfile full_profile2(test::GetFullProfile2()); 449 CreditCard credit_card; 450 test::SetCreditCardInfo(&credit_card, "Test User", 451 "4234567890654321", // Visa 452 "11", "2100"); 453 controller()->GetTestingManager()->AddTestingProfile(&full_profile); 454 controller()->GetTestingManager()->AddTestingProfile(&full_profile2); 455 controller()->GetTestingManager()->AddTestingCreditCard(&credit_card); 456 ui::MenuModel* shipping_model = 457 controller()->MenuModelForSection(SECTION_SHIPPING); 458 shipping_model->ActivatedAt(2); 459 460 controller()->OnAccept(); 461 ASSERT_EQ(4U, form_structure()->field_count()); 462 EXPECT_EQ("CA", UTF16ToUTF8(form_structure()->field(2)->value)); 463 EXPECT_EQ("MI", UTF16ToUTF8(form_structure()->field(3)->value)); 464 EXPECT_EQ(ADDRESS_BILLING_STATE, form_structure()->field(2)->type()); 465 EXPECT_EQ(ADDRESS_HOME_STATE, form_structure()->field(3)->type()); 466} 467 468// Test selecting UseBillingForShipping. 469TEST_F(AutofillDialogControllerTest, UseBillingAsShipping) { 470 AutofillProfile full_profile(test::GetFullProfile()); 471 AutofillProfile full_profile2(test::GetFullProfile2()); 472 CreditCard credit_card; 473 test::SetCreditCardInfo(&credit_card, "Test User", 474 "4234567890654321", // Visa 475 "11", "2100"); 476 controller()->GetTestingManager()->AddTestingProfile(&full_profile); 477 controller()->GetTestingManager()->AddTestingProfile(&full_profile2); 478 controller()->GetTestingManager()->AddTestingCreditCard(&credit_card); 479 ui::MenuModel* shipping_model = 480 controller()->MenuModelForSection(SECTION_SHIPPING); 481 482 // Test after setting use billing for shipping. 483 shipping_model->ActivatedAt(0); 484 485 controller()->OnAccept(); 486 ASSERT_EQ(4U, form_structure()->field_count()); 487 EXPECT_EQ("CA", UTF16ToUTF8(form_structure()->field(2)->value)); 488 EXPECT_EQ("CA", UTF16ToUTF8(form_structure()->field(3)->value)); 489 EXPECT_EQ(ADDRESS_BILLING_STATE, form_structure()->field(2)->type()); 490 EXPECT_EQ(ADDRESS_HOME_STATE, form_structure()->field(3)->type()); 491} 492 493TEST_F(AutofillDialogControllerTest, AcceptLegalDocuments) { 494 EXPECT_CALL(*controller()->GetTestingWalletClient(), 495 AcceptLegalDocuments(_, _, _)).Times(1); 496 EXPECT_CALL(*controller()->GetTestingWalletClient(), 497 GetFullWallet(_)).Times(1); 498 499 scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems(); 500 wallet_items->AddLegalDocument(wallet::GetTestLegalDocument()); 501 wallet_items->AddInstrument(wallet::GetTestMaskedInstrument()); 502 wallet_items->AddAddress(wallet::GetTestShippingAddress()); 503 controller()->OnDidGetWalletItems(wallet_items.Pass()); 504 controller()->OnAccept(); 505} 506 507// Makes sure the default object IDs are respected. 508TEST_F(AutofillDialogControllerTest, WalletDefaultItems) { 509 scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems(); 510 wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument()); 511 wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument()); 512 wallet_items->AddInstrument(wallet::GetTestMaskedInstrument()); 513 wallet_items->AddInstrument(wallet::GetTestNonDefaultMaskedInstrument()); 514 515 wallet_items->AddAddress(wallet::GetTestNonDefaultShippingAddress()); 516 wallet_items->AddAddress(wallet::GetTestNonDefaultShippingAddress()); 517 wallet_items->AddAddress(wallet::GetTestNonDefaultShippingAddress()); 518 wallet_items->AddAddress(wallet::GetTestShippingAddress()); 519 wallet_items->AddAddress(wallet::GetTestNonDefaultShippingAddress()); 520 521 controller()->OnDidGetWalletItems(wallet_items.Pass()); 522 // "add", "manage", and 4 suggestions. 523 EXPECT_EQ(6, 524 controller()->MenuModelForSection(SECTION_CC_BILLING)->GetItemCount()); 525 EXPECT_TRUE(controller()->MenuModelForSection(SECTION_CC_BILLING)-> 526 IsItemCheckedAt(2)); 527 // "use billing", "add", "manage", and 5 suggestions. 528 EXPECT_EQ(8, 529 controller()->MenuModelForSection(SECTION_SHIPPING)->GetItemCount()); 530 EXPECT_TRUE(controller()->MenuModelForSection(SECTION_SHIPPING)-> 531 IsItemCheckedAt(4)); 532} 533 534TEST_F(AutofillDialogControllerTest, SaveAddress) { 535 EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1); 536 EXPECT_CALL(*controller()->GetTestingWalletClient(), 537 SaveAddress(_, _)).Times(1); 538 539 scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems(); 540 wallet_items->AddInstrument(wallet::GetTestMaskedInstrument()); 541 controller()->OnDidGetWalletItems(wallet_items.Pass()); 542 controller()->OnAccept(); 543} 544 545TEST_F(AutofillDialogControllerTest, SaveInstrument) { 546 EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1); 547 EXPECT_CALL(*controller()->GetTestingWalletClient(), 548 SaveInstrument(_, _, _)).Times(1); 549 550 scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems(); 551 wallet_items->AddAddress(wallet::GetTestShippingAddress()); 552 controller()->OnDidGetWalletItems(wallet_items.Pass()); 553 controller()->OnAccept(); 554} 555 556TEST_F(AutofillDialogControllerTest, SaveInstrumentAndAddress) { 557 EXPECT_CALL(*controller()->GetTestingWalletClient(), 558 SaveInstrumentAndAddress(_, _, _, _)).Times(1); 559 560 controller()->OnDidGetWalletItems(wallet::GetTestWalletItems()); 561 controller()->OnAccept(); 562} 563 564TEST_F(AutofillDialogControllerTest, CancelNoSave) { 565 EXPECT_CALL(*controller()->GetTestingWalletClient(), 566 SaveInstrumentAndAddress(_, _, _, _)).Times(0); 567 568 EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1); 569 570 controller()->OnDidGetWalletItems(wallet::GetTestWalletItems()); 571 controller()->OnCancel(); 572} 573 574// Checks that clicking the Manage menu item opens a new tab with a different 575// URL for Wallet and Autofill. 576TEST_F(AutofillDialogControllerTest, ManageItem) { 577 AutofillProfile full_profile(test::GetFullProfile()); 578 full_profile.set_origin(kSettingsOrigin); 579 full_profile.SetRawInfo(ADDRESS_HOME_LINE2, string16()); 580 controller()->GetTestingManager()->AddTestingProfile(&full_profile); 581 SwitchToAutofill(); 582 583 SuggestionsMenuModel* model = static_cast<SuggestionsMenuModel*>( 584 controller()->MenuModelForSection(SECTION_SHIPPING)); 585 model->ExecuteCommand(model->GetItemCount() - 1, 0); 586 GURL autofill_manage_url = controller()->open_tab_url(); 587 EXPECT_EQ("chrome", autofill_manage_url.scheme()); 588 589 SwitchToWallet(); 590 controller()->OnDidGetWalletItems(wallet::GetTestWalletItems()); 591 controller()->SuggestionItemSelected(model, model->GetItemCount() - 1); 592 GURL wallet_manage_url = controller()->open_tab_url(); 593 EXPECT_EQ("https", wallet_manage_url.scheme()); 594 595 EXPECT_NE(autofill_manage_url, wallet_manage_url); 596} 597 598TEST_F(AutofillDialogControllerTest, EditClickedCancelled) { 599 EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1); 600 601 AutofillProfile full_profile(test::GetFullProfile()); 602 const string16 kEmail = ASCIIToUTF16("first@johndoe.com"); 603 full_profile.SetRawInfo(EMAIL_ADDRESS, kEmail); 604 controller()->GetTestingManager()->AddTestingProfile(&full_profile); 605 606 ui::MenuModel* email_model = 607 controller()->MenuModelForSection(SECTION_EMAIL); 608 EXPECT_EQ(3, email_model->GetItemCount()); 609 610 // When unedited, the initial_value should be empty. 611 email_model->ActivatedAt(0); 612 const DetailInputs& inputs0 = 613 controller()->RequestedFieldsForSection(SECTION_EMAIL); 614 EXPECT_EQ(string16(), inputs0[0].initial_value); 615 EXPECT_EQ(kEmail, 616 controller()->SuggestionStateForSection(SECTION_EMAIL).text); 617 618 // When edited, the initial_value should contain the value. 619 controller()->EditClickedForSection(SECTION_EMAIL); 620 const DetailInputs& inputs1 = 621 controller()->RequestedFieldsForSection(SECTION_EMAIL); 622 EXPECT_EQ(kEmail, inputs1[0].initial_value); 623 EXPECT_EQ(string16(), 624 controller()->SuggestionStateForSection(SECTION_EMAIL).text); 625 626 // When edit is cancelled, the initial_value should be empty. 627 controller()->EditCancelledForSection(SECTION_EMAIL); 628 const DetailInputs& inputs2 = 629 controller()->RequestedFieldsForSection(SECTION_EMAIL); 630 EXPECT_EQ(kEmail, 631 controller()->SuggestionStateForSection(SECTION_EMAIL).text); 632 EXPECT_EQ(string16(), inputs2[0].initial_value); 633} 634 635// Tests that editing an autofill profile and then submitting works. 636TEST_F(AutofillDialogControllerTest, EditAutofillProfile) { 637 SwitchToAutofill(); 638 639 EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1); 640 641 AutofillProfile full_profile(test::GetFullProfile()); 642 controller()->GetTestingManager()->AddTestingProfile(&full_profile); 643 controller()->EditClickedForSection(SECTION_SHIPPING); 644 645 DetailOutputMap outputs; 646 const DetailInputs& inputs = 647 controller()->RequestedFieldsForSection(SECTION_SHIPPING); 648 for (size_t i = 0; i < inputs.size(); ++i) { 649 const DetailInput& input = inputs[i]; 650 outputs[&input] = input.type == NAME_FULL ? ASCIIToUTF16("Edited Name") : 651 input.initial_value; 652 } 653 controller()->GetView()->SetUserInput(SECTION_SHIPPING, outputs); 654 655 // We also have to simulate CC inputs to keep the controller happy. 656 FillCreditCardInputs(); 657 658 controller()->OnAccept(); 659 const AutofillProfile& edited_profile = 660 controller()->GetTestingManager()->imported_profile(); 661 662 for (size_t i = 0; i < inputs.size(); ++i) { 663 const DetailInput& input = inputs[i]; 664 EXPECT_EQ(input.type == NAME_FULL ? ASCIIToUTF16("Edited Name") : 665 input.initial_value, 666 edited_profile.GetInfo(input.type, "en-US")); 667 } 668} 669 670// Tests that adding an autofill profile and then submitting works. 671TEST_F(AutofillDialogControllerTest, AddAutofillProfile) { 672 EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1); 673 674 AutofillProfile full_profile(test::GetFullProfile()); 675 controller()->GetTestingManager()->AddTestingProfile(&full_profile); 676 677 ui::MenuModel* model = controller()->MenuModelForSection(SECTION_BILLING); 678 // Activate the "Add billing address" menu item. 679 model->ActivatedAt(model->GetItemCount() - 2); 680 681 // Fill in the inputs from the profile. 682 DetailOutputMap outputs; 683 const DetailInputs& inputs = 684 controller()->RequestedFieldsForSection(SECTION_BILLING); 685 AutofillProfile full_profile2(test::GetFullProfile2()); 686 for (size_t i = 0; i < inputs.size(); ++i) { 687 const DetailInput& input = inputs[i]; 688 outputs[&input] = full_profile2.GetInfo(input.type, "en-US"); 689 } 690 controller()->GetView()->SetUserInput(SECTION_BILLING, outputs); 691 692 // Fill in some CC info. The name field will be used to fill in the billing 693 // address name in the newly minted AutofillProfile. 694 DetailOutputMap cc_outputs; 695 const DetailInputs& cc_inputs = 696 controller()->RequestedFieldsForSection(SECTION_CC); 697 for (size_t i = 0; i < cc_inputs.size(); ++i) { 698 cc_outputs[&cc_inputs[i]] = cc_inputs[i].type == CREDIT_CARD_NAME ? 699 ASCIIToUTF16("Bill Money") : ASCIIToUTF16("111"); 700 } 701 controller()->GetView()->SetUserInput(SECTION_CC, cc_outputs); 702 703 controller()->OnAccept(); 704 const AutofillProfile& added_profile = 705 controller()->GetTestingManager()->imported_profile(); 706 707 const DetailInputs& shipping_inputs = 708 controller()->RequestedFieldsForSection(SECTION_SHIPPING); 709 for (size_t i = 0; i < shipping_inputs.size(); ++i) { 710 const DetailInput& input = shipping_inputs[i]; 711 string16 expected = input.type == NAME_FULL ? 712 ASCIIToUTF16("Bill Money") : 713 full_profile2.GetInfo(input.type, "en-US"); 714 EXPECT_EQ(expected, added_profile.GetInfo(input.type, "en-US")); 715 } 716} 717 718TEST_F(AutofillDialogControllerTest, VerifyCvv) { 719 EXPECT_CALL(*controller()->GetTestingWalletClient(), 720 GetFullWallet(_)).Times(1); 721 EXPECT_CALL(*controller()->GetTestingWalletClient(), 722 AuthenticateInstrument(_, _, _)).Times(1); 723 724 scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems(); 725 wallet_items->AddInstrument(wallet::GetTestMaskedInstrument()); 726 wallet_items->AddAddress(wallet::GetTestShippingAddress()); 727 controller()->OnDidGetWalletItems(wallet_items.Pass()); 728 controller()->OnAccept(); 729 730 EXPECT_TRUE(NotificationsOfType(DialogNotification::REQUIRED_ACTION).empty()); 731 EXPECT_TRUE(controller()->SectionIsActive(SECTION_SHIPPING)); 732 EXPECT_TRUE(controller()->SectionIsActive(SECTION_CC_BILLING)); 733 EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK)); 734 EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL)); 735 736 SuggestionState suggestion_state = 737 controller()->SuggestionStateForSection(SECTION_CC_BILLING); 738 EXPECT_TRUE(suggestion_state.extra_text.empty()); 739 740 controller()->OnDidGetFullWallet(CreateFullWalletWithVerifyCvv()); 741 742 EXPECT_FALSE( 743 NotificationsOfType(DialogNotification::REQUIRED_ACTION).empty()); 744 EXPECT_FALSE(controller()->SectionIsActive(SECTION_SHIPPING)); 745 EXPECT_TRUE(controller()->SectionIsActive(SECTION_CC_BILLING)); 746 747 suggestion_state = 748 controller()->SuggestionStateForSection(SECTION_CC_BILLING); 749 EXPECT_FALSE(suggestion_state.extra_text.empty()); 750 EXPECT_FALSE(controller()->MenuModelForSection(SECTION_CC_BILLING)); 751 752 EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK)); 753 EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL)); 754 755 controller()->OnAccept(); 756} 757 758TEST_F(AutofillDialogControllerTest, ErrorDuringSubmit) { 759 EXPECT_CALL(*controller()->GetTestingWalletClient(), 760 GetFullWallet(_)).Times(1); 761 762 scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems(); 763 wallet_items->AddInstrument(wallet::GetTestMaskedInstrument()); 764 wallet_items->AddAddress(wallet::GetTestShippingAddress()); 765 controller()->OnDidGetWalletItems(wallet_items.Pass()); 766 controller()->OnAccept(); 767 768 EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK)); 769 EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL)); 770 771 controller()->OnWalletError(wallet::WalletClient::UNKNOWN_ERROR); 772 773 EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK)); 774 EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL)); 775} 776 777// TODO(dbeam): disallow changing accounts instead and remove this test. 778TEST_F(AutofillDialogControllerTest, ChangeAccountDuringSubmit) { 779 EXPECT_CALL(*controller()->GetTestingWalletClient(), 780 GetFullWallet(_)).Times(1); 781 782 scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems(); 783 wallet_items->AddInstrument(wallet::GetTestMaskedInstrument()); 784 wallet_items->AddAddress(wallet::GetTestShippingAddress()); 785 controller()->OnDidGetWalletItems(wallet_items.Pass()); 786 controller()->OnAccept(); 787 788 EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK)); 789 EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL)); 790 791 SwitchToWallet(); 792 SwitchToAutofill(); 793 794 EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK)); 795 EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL)); 796} 797 798TEST_F(AutofillDialogControllerTest, ErrorDuringVerifyCvv) { 799 EXPECT_CALL(*controller()->GetTestingWalletClient(), 800 GetFullWallet(_)).Times(1); 801 802 scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems(); 803 wallet_items->AddInstrument(wallet::GetTestMaskedInstrument()); 804 wallet_items->AddAddress(wallet::GetTestShippingAddress()); 805 controller()->OnDidGetWalletItems(wallet_items.Pass()); 806 controller()->OnAccept(); 807 controller()->OnDidGetFullWallet(CreateFullWalletWithVerifyCvv()); 808 809 ASSERT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK)); 810 ASSERT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL)); 811 812 controller()->OnWalletError(wallet::WalletClient::UNKNOWN_ERROR); 813 814 EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK)); 815 EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL)); 816} 817 818// TODO(dbeam): disallow changing accounts instead and remove this test. 819TEST_F(AutofillDialogControllerTest, ChangeAccountDuringVerifyCvv) { 820 EXPECT_CALL(*controller()->GetTestingWalletClient(), 821 GetFullWallet(_)).Times(1); 822 823 scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems(); 824 wallet_items->AddInstrument(wallet::GetTestMaskedInstrument()); 825 wallet_items->AddAddress(wallet::GetTestShippingAddress()); 826 controller()->OnDidGetWalletItems(wallet_items.Pass()); 827 controller()->OnAccept(); 828 controller()->OnDidGetFullWallet(CreateFullWalletWithVerifyCvv()); 829 830 ASSERT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK)); 831 ASSERT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL)); 832 833 SwitchToWallet(); 834 SwitchToAutofill(); 835 836 EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK)); 837 EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL)); 838} 839 840// Test that when a wallet error happens only an error is shown (and no other 841// Wallet-related notifications). 842TEST_F(AutofillDialogControllerTest, WalletErrorNotification) { 843 controller()->OnWalletError(wallet::WalletClient::UNKNOWN_ERROR); 844 845 EXPECT_EQ(1U, NotificationsOfType( 846 DialogNotification::WALLET_ERROR).size()); 847 848 // No other wallet notifications should show on Wallet error. 849 EXPECT_TRUE(NotificationsOfType( 850 DialogNotification::WALLET_SIGNIN_PROMO).empty()); 851 EXPECT_TRUE(NotificationsOfType( 852 DialogNotification::WALLET_USAGE_CONFIRMATION).empty()); 853 EXPECT_TRUE(NotificationsOfType( 854 DialogNotification::EXPLANATORY_MESSAGE).empty()); 855} 856 857// Test that only on first run an explanation of where Chrome got the user's 858// data is shown (i.e. "Got these details from Wallet"). 859TEST_F(AutofillDialogControllerTest, WalletDetailsExplanation) { 860 scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems(); 861 wallet_items->AddInstrument(wallet::GetTestMaskedInstrument()); 862 wallet_items->AddAddress(wallet::GetTestShippingAddress()); 863 controller()->OnDidGetWalletItems(wallet_items.Pass()); 864 865 EXPECT_EQ(1U, NotificationsOfType( 866 DialogNotification::EXPLANATORY_MESSAGE).size()); 867 868 // Wallet notifications are mutually exclusive. 869 EXPECT_TRUE(NotificationsOfType( 870 DialogNotification::WALLET_USAGE_CONFIRMATION).empty()); 871 EXPECT_TRUE(NotificationsOfType( 872 DialogNotification::WALLET_SIGNIN_PROMO).empty()); 873 874 // Switch to using Autofill, no explanatory message should show. 875 SwitchToAutofill(); 876 EXPECT_TRUE(NotificationsOfType( 877 DialogNotification::EXPLANATORY_MESSAGE).empty()); 878 879 // Switch to Wallet, pretend this isn't first run. No message should show. 880 SwitchToWallet(); 881 controller()->set_is_first_run(false); 882 EXPECT_TRUE(NotificationsOfType( 883 DialogNotification::EXPLANATORY_MESSAGE).empty()); 884} 885 886// Verifies that the "[X] Save details in wallet" notification shows on first 887// run with an incomplete profile, stays showing when switching to Autofill in 888// the account chooser, and continues to show on second+ run when a user's 889// wallet is incomplete. This also tests that submitting disables interactivity. 890TEST_F(AutofillDialogControllerTest, SaveDetailsInWallet) { 891 scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems(); 892 wallet_items->AddInstrument(wallet::GetTestMaskedInstrument()); 893 controller()->OnDidGetWalletItems(wallet_items.Pass()); 894 895 std::vector<DialogNotification> notifications = 896 NotificationsOfType(DialogNotification::WALLET_USAGE_CONFIRMATION); 897 EXPECT_EQ(1U, notifications.size()); 898 EXPECT_TRUE(notifications.front().checked()); 899 EXPECT_TRUE(notifications.front().interactive()); 900 901 // Wallet notifications are mutually exclusive. 902 EXPECT_TRUE(NotificationsOfType( 903 DialogNotification::WALLET_SIGNIN_PROMO).empty()); 904 EXPECT_TRUE(NotificationsOfType( 905 DialogNotification::EXPLANATORY_MESSAGE).empty()); 906 907 // Using Autofill on second run, show an interactive, unchecked checkbox. 908 SwitchToAutofill(); 909 controller()->set_is_first_run(false); 910 911 notifications = 912 NotificationsOfType(DialogNotification::WALLET_USAGE_CONFIRMATION); 913 EXPECT_EQ(1U, notifications.size()); 914 EXPECT_FALSE(notifications.front().checked()); 915 EXPECT_TRUE(notifications.front().interactive()); 916 917 // Notifications shouldn't be interactive while submitting. 918 SwitchToWallet(); 919 controller()->OnAccept(); 920 EXPECT_FALSE(NotificationsOfType( 921 DialogNotification::WALLET_USAGE_CONFIRMATION).front().interactive()); 922} 923 924// Verifies that no Wallet notifications are shown after first run (i.e. no 925// "[X] Save details to wallet" or "These details are from your Wallet") when 926// the user has a complete wallet. 927TEST_F(AutofillDialogControllerTest, NoWalletNotifications) { 928 controller()->set_is_first_run(false); 929 930 // Simulate a complete wallet. 931 scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems(); 932 wallet_items->AddInstrument(wallet::GetTestMaskedInstrument()); 933 wallet_items->AddAddress(wallet::GetTestShippingAddress()); 934 controller()->OnDidGetWalletItems(wallet_items.Pass()); 935 936 EXPECT_TRUE(NotificationsOfType( 937 DialogNotification::EXPLANATORY_MESSAGE).empty()); 938 EXPECT_TRUE(NotificationsOfType( 939 DialogNotification::WALLET_USAGE_CONFIRMATION).empty()); 940} 941 942TEST_F(AutofillDialogControllerTest, ViewCancelDoesntSetPref) { 943 ASSERT_FALSE(profile()->GetPrefs()->HasPrefPath( 944 ::prefs::kAutofillDialogPayWithoutWallet)); 945 946 SwitchToAutofill(); 947 948 controller()->OnCancel(); 949 controller()->ViewClosed(); 950 951 EXPECT_FALSE(profile()->GetPrefs()->HasPrefPath( 952 ::prefs::kAutofillDialogPayWithoutWallet)); 953} 954 955TEST_F(AutofillDialogControllerTest, ViewSubmitSetsPref) { 956 ASSERT_FALSE(profile()->GetPrefs()->HasPrefPath( 957 ::prefs::kAutofillDialogPayWithoutWallet)); 958 959 SwitchToAutofill(); 960 961 // We also have to simulate CC inputs to keep the controller happy. 962 FillCreditCardInputs(); 963 964 controller()->OnAccept(); 965 966 EXPECT_TRUE(profile()->GetPrefs()->HasPrefPath( 967 ::prefs::kAutofillDialogPayWithoutWallet)); 968 EXPECT_TRUE(profile()->GetPrefs()->GetBoolean( 969 ::prefs::kAutofillDialogPayWithoutWallet)); 970} 971 972TEST_F(AutofillDialogControllerTest, HideWalletEmail) { 973 SwitchToAutofill(); 974 975 // Email section should be showing when using Autofill. 976 EXPECT_TRUE(controller()->SectionIsActive(SECTION_EMAIL)); 977 978 SwitchToWallet(); 979 980 // Setup some wallet state, submit, and get a full wallet to end the flow. 981 scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems(); 982 wallet_items->AddInstrument(wallet::GetTestMaskedInstrument()); 983 wallet_items->AddAddress(wallet::GetTestShippingAddress()); 984 985 // Filling |form_structure()| depends on the current username and wallet items 986 // being fetched. Until both of these have occurred, the user should not be 987 // able to click Submit if using Wallet. The username fetch happened earlier. 988 EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK)); 989 controller()->OnDidGetWalletItems(wallet_items.Pass()); 990 EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK)); 991 992 // Email section should be hidden when using Wallet. 993 EXPECT_FALSE(controller()->SectionIsActive(SECTION_EMAIL)); 994 995 controller()->OnAccept(); 996 controller()->OnDidGetFullWallet(wallet::GetTestFullWallet()); 997 998 size_t i = 0; 999 for (; i < form_structure()->field_count(); ++i) { 1000 if (form_structure()->field(i)->type() == EMAIL_ADDRESS) { 1001 EXPECT_EQ(ASCIIToUTF16(kFakeEmail), form_structure()->field(i)->value); 1002 break; 1003 } 1004 } 1005 ASSERT_LT(i, form_structure()->field_count()); 1006} 1007 1008// Test if autofill types of returned form structure are correct for billing 1009// entries. 1010TEST_F(AutofillDialogControllerTest, AutofillTypes) { 1011 controller()->OnDidGetWalletItems(wallet::GetTestWalletItems()); 1012 controller()->OnAccept(); 1013 controller()->OnDidGetFullWallet(wallet::GetTestFullWallet()); 1014 ASSERT_EQ(4U, form_structure()->field_count()); 1015 EXPECT_EQ(EMAIL_ADDRESS, form_structure()->field(0)->type()); 1016 EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure()->field(1)->type()); 1017 EXPECT_EQ(ADDRESS_BILLING_STATE, form_structure()->field(2)->type()); 1018 EXPECT_EQ(ADDRESS_HOME_STATE, form_structure()->field(3)->type()); 1019} 1020 1021TEST_F(AutofillDialogControllerTest, SaveDetailsInChrome) { 1022 EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(2); 1023 1024 AutofillProfile full_profile(test::GetFullProfile()); 1025 controller()->GetTestingManager()->AddTestingProfile(&full_profile); 1026 1027 CreditCard card; 1028 test::SetCreditCardInfo( 1029 &card, "Donald Trump", "4111-1111-1111-1111", "10", "2025"); 1030 controller()->GetTestingManager()->AddTestingCreditCard(&card); 1031 EXPECT_FALSE(controller()->ShouldOfferToSaveInChrome()); 1032 1033 controller()->EditClickedForSection(SECTION_EMAIL); 1034 EXPECT_TRUE(controller()->ShouldOfferToSaveInChrome()); 1035 1036 controller()->EditCancelledForSection(SECTION_EMAIL); 1037 EXPECT_FALSE(controller()->ShouldOfferToSaveInChrome()); 1038 1039 controller()->MenuModelForSection(SECTION_EMAIL)->ActivatedAt(1); 1040 EXPECT_TRUE(controller()->ShouldOfferToSaveInChrome()); 1041 1042 profile()->set_incognito(true); 1043 EXPECT_FALSE(controller()->ShouldOfferToSaveInChrome()); 1044} 1045 1046} // namespace autofill 1047