account_chooser_model_unittest.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1// Copyright 2013 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/prefs/pref_service.h" 6#include "base/strings/utf_string_conversions.h" 7#include "chrome/browser/ui/autofill/account_chooser_model.h" 8#include "chrome/common/pref_names.h" 9#include "chrome/test/base/testing_profile.h" 10#include "components/autofill/core/browser/autofill_metrics.h" 11#include "testing/gmock/include/gmock/gmock.h" 12#include "testing/gtest/include/gtest/gtest.h" 13 14using base::ASCIIToUTF16; 15 16namespace autofill { 17 18namespace { 19 20class TestAccountChooserModel : public AccountChooserModel { 21 public: 22 TestAccountChooserModel(AccountChooserModelDelegate* delegate, 23 Profile* profile, 24 bool disable_wallet, 25 const AutofillMetrics& metric_logger) 26 : AccountChooserModel(delegate, profile, disable_wallet, metric_logger) {} 27 virtual ~TestAccountChooserModel() {} 28 29 using AccountChooserModel::kWalletAccountsStartId; 30 using AccountChooserModel::kWalletAddAccountId; 31 using AccountChooserModel::kAutofillItemId; 32 33 private: 34 DISALLOW_COPY_AND_ASSIGN(TestAccountChooserModel); 35}; 36 37class MockAccountChooserModelDelegate : public AccountChooserModelDelegate { 38 public: 39 MockAccountChooserModelDelegate() {} 40 virtual ~MockAccountChooserModelDelegate() {} 41 42 MOCK_METHOD0(AccountChooserWillShow, void()); 43 MOCK_METHOD0(AccountChoiceChanged, void()); 44 MOCK_METHOD0(AddAccount, void()); 45 MOCK_METHOD0(UpdateAccountChooserView, void()); 46}; 47 48class AccountChooserModelTest : public testing::Test { 49 public: 50 AccountChooserModelTest() 51 : model_(&delegate_, &profile_, false, metric_logger_) {} 52 virtual ~AccountChooserModelTest() {} 53 54 TestingProfile* profile() { return &profile_; } 55 MockAccountChooserModelDelegate* delegate() { return &delegate_; } 56 TestAccountChooserModel* model() { return &model_; } 57 const AutofillMetrics& metric_logger() { return metric_logger_; } 58 59 private: 60 TestingProfile profile_; 61 testing::NiceMock<MockAccountChooserModelDelegate> delegate_; 62 TestAccountChooserModel model_; 63 AutofillMetrics metric_logger_; 64}; 65 66} // namespace 67 68TEST_F(AccountChooserModelTest, ObeysPref) { 69 // When "Pay without wallet" is false, use Wallet by default. 70 { 71 profile()->GetPrefs()->SetBoolean( 72 ::prefs::kAutofillDialogPayWithoutWallet, false); 73 TestAccountChooserModel model(delegate(), 74 profile(), 75 false, 76 metric_logger()); 77 EXPECT_TRUE(model.WalletIsSelected()); 78 } 79 // When the user chose to "Pay without wallet", use Autofill. 80 { 81 profile()->GetPrefs()->SetBoolean( 82 ::prefs::kAutofillDialogPayWithoutWallet, true); 83 TestAccountChooserModel model(delegate(), 84 profile(), 85 false, 86 metric_logger()); 87 EXPECT_FALSE(model.WalletIsSelected()); 88 } 89 // When the |disable_wallet| argument is true, use Autofill regardless 90 // of the pref. 91 { 92 profile()->GetPrefs()->SetBoolean( 93 ::prefs::kAutofillDialogPayWithoutWallet, false); 94 TestAccountChooserModel model(delegate(), profile(), true, metric_logger()); 95 EXPECT_FALSE(model.WalletIsSelected()); 96 } 97 // In incognito, use local data regardless of the pref. 98 { 99 TestingProfile::Builder builder; 100 builder.SetIncognito(); 101 scoped_ptr<TestingProfile> incognito = builder.Build(); 102 incognito->SetOriginalProfile(profile()); 103 profile()->GetPrefs()->SetBoolean( 104 ::prefs::kAutofillDialogPayWithoutWallet, false); 105 incognito->GetPrefs()->SetBoolean( 106 ::prefs::kAutofillDialogPayWithoutWallet, false); 107 108 TestAccountChooserModel model(delegate(), 109 incognito.get(), 110 false, 111 metric_logger()); 112 EXPECT_FALSE(model.WalletIsSelected()); 113 } 114} 115 116TEST_F(AccountChooserModelTest, IgnoresPrefChanges) { 117 ASSERT_FALSE(profile()->GetPrefs()->GetBoolean( 118 ::prefs::kAutofillDialogPayWithoutWallet)); 119 EXPECT_TRUE(model()->WalletIsSelected()); 120 121 // Check that nothing changes while this dialog is running if a pref changes 122 // (this could cause subtle bugs or annoyances if a user closes another 123 // running dialog). 124 profile()->GetPrefs()->SetBoolean( 125 ::prefs::kAutofillDialogPayWithoutWallet, true); 126 EXPECT_TRUE(model()->WalletIsSelected()); 127} 128 129TEST_F(AccountChooserModelTest, HandlesError) { 130 EXPECT_CALL(*delegate(), AccountChoiceChanged()).Times(1); 131 EXPECT_CALL(*delegate(), UpdateAccountChooserView()).Times(1); 132 133 ASSERT_TRUE(model()->WalletIsSelected()); 134 ASSERT_TRUE(model()->IsCommandIdEnabled( 135 TestAccountChooserModel::kWalletAccountsStartId)); 136 137 model()->SetHadWalletError(); 138 EXPECT_FALSE(model()->WalletIsSelected()); 139 EXPECT_FALSE(model()->IsCommandIdEnabled( 140 TestAccountChooserModel::kWalletAccountsStartId)); 141} 142 143TEST_F(AccountChooserModelTest, HandlesSigninError) { 144 EXPECT_CALL(*delegate(), AccountChoiceChanged()).Times(1); 145 EXPECT_CALL(*delegate(), UpdateAccountChooserView()).Times(2); 146 147 // 0. "Unknown" wallet account, we don't know if the user is signed-in yet. 148 ASSERT_TRUE(model()->WalletIsSelected()); 149 ASSERT_TRUE(model()->IsCommandIdEnabled( 150 TestAccountChooserModel::kWalletAccountsStartId)); 151 ASSERT_TRUE(model()->WalletIsSelected()); 152 ASSERT_FALSE(model()->HasAccountsToChoose()); 153 ASSERT_EQ(3, model()->GetItemCount()); 154 EXPECT_EQ(base::string16(), model()->GetActiveWalletAccountName()); 155 156 // 1. "Known" wallet account (e.g. after active/passive/automatic sign-in). 157 // Calls UpdateAccountChooserView. 158 std::vector<std::string> accounts; 159 accounts.push_back("john.doe@gmail.com"); 160 model()->SetWalletAccounts(accounts, 0U); 161 ASSERT_TRUE(model()->WalletIsSelected()); 162 ASSERT_TRUE(model()->IsCommandIdEnabled( 163 TestAccountChooserModel::kWalletAccountsStartId)); 164 ASSERT_TRUE(model()->WalletIsSelected()); 165 ASSERT_TRUE(model()->HasAccountsToChoose()); 166 EXPECT_EQ(3, model()->GetItemCount()); 167 EXPECT_EQ(ASCIIToUTF16(accounts[0]), model()->GetActiveWalletAccountName()); 168 169 // 2. Sign-in failure. 170 // Autofill data should be selected and be the only valid choice. 171 // Calls UpdateAccountChooserView. 172 // Calls AccountChoiceChanged. 173 model()->SetHadWalletSigninError(); 174 EXPECT_FALSE(model()->WalletIsSelected()); 175 EXPECT_TRUE(model()->IsCommandIdEnabled( 176 TestAccountChooserModel::kWalletAccountsStartId)); 177 EXPECT_FALSE(model()->WalletIsSelected()); 178 EXPECT_FALSE(model()->HasAccountsToChoose()); 179 EXPECT_EQ(2, model()->GetItemCount()); 180 EXPECT_EQ(base::string16(), model()->GetActiveWalletAccountName()); 181} 182 183TEST_F(AccountChooserModelTest, RespectsUserChoice) { 184 EXPECT_CALL(*delegate(), AccountChoiceChanged()).Times(2); 185 186 model()->ExecuteCommand(TestAccountChooserModel::kAutofillItemId, 0); 187 EXPECT_FALSE(model()->WalletIsSelected()); 188 189 EXPECT_CALL(*delegate(), AddAccount()); 190 model()->ExecuteCommand(TestAccountChooserModel::kWalletAddAccountId, 0); 191 EXPECT_FALSE(model()->WalletIsSelected()); 192 193 model()->ExecuteCommand(TestAccountChooserModel::kWalletAccountsStartId, 0); 194 EXPECT_TRUE(model()->WalletIsSelected()); 195} 196 197TEST_F(AccountChooserModelTest, HandlesMultipleAccounts) { 198 EXPECT_FALSE(model()->HasAccountsToChoose()); 199 200 std::vector<std::string> accounts; 201 accounts.push_back("john.doe@gmail.com"); 202 accounts.push_back("jane.smith@gmail.com"); 203 model()->SetWalletAccounts(accounts, 0U); 204 EXPECT_TRUE(model()->HasAccountsToChoose()); 205 EXPECT_TRUE(model()->WalletIsSelected()); 206 ASSERT_EQ(4, model()->GetItemCount()); 207 EXPECT_TRUE(model()->IsCommandIdEnabled( 208 TestAccountChooserModel::kWalletAccountsStartId)); 209 EXPECT_TRUE(model()->IsCommandIdEnabled( 210 TestAccountChooserModel::kWalletAccountsStartId + 1)); 211 EXPECT_EQ(ASCIIToUTF16(accounts[0]), model()->GetActiveWalletAccountName()); 212 model()->SetWalletAccounts(accounts, 1U); 213 EXPECT_EQ(ASCIIToUTF16(accounts[1]), model()->GetActiveWalletAccountName()); 214 215 model()->ExecuteCommand(TestAccountChooserModel::kWalletAccountsStartId, 0); 216 EXPECT_EQ(ASCIIToUTF16(accounts[0]), model()->GetActiveWalletAccountName()); 217 model()->ExecuteCommand(TestAccountChooserModel::kWalletAccountsStartId + 1, 218 0); 219 EXPECT_EQ(ASCIIToUTF16(accounts[1]), model()->GetActiveWalletAccountName()); 220 221 // Setting the wallet accounts forces the switch to wallet. 222 model()->ExecuteCommand(TestAccountChooserModel::kAutofillItemId, 0); 223 EXPECT_FALSE(model()->WalletIsSelected()); 224 model()->SetWalletAccounts(accounts, 1U); 225 EXPECT_TRUE(model()->WalletIsSelected()); 226} 227 228} // namespace autofill 229