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.
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"
14 using base::ASCIIToUTF16;
20 class TestAccountChooserModel : public AccountChooserModel {
22 TestAccountChooserModel(AccountChooserModelDelegate* delegate,
25 const AutofillMetrics& metric_logger)
26 : AccountChooserModel(delegate, profile, disable_wallet, metric_logger) {}
27 virtual ~TestAccountChooserModel() {}
29 using AccountChooserModel::kWalletAccountsStartId;
30 using AccountChooserModel::kWalletAddAccountId;
31 using AccountChooserModel::kAutofillItemId;
34 DISALLOW_COPY_AND_ASSIGN(TestAccountChooserModel);
37 class MockAccountChooserModelDelegate : public AccountChooserModelDelegate {
39 MockAccountChooserModelDelegate() {}
40 virtual ~MockAccountChooserModelDelegate() {}
42 MOCK_METHOD0(AccountChoiceChanged, void());
43 MOCK_METHOD0(AddAccount, void());
44 MOCK_METHOD0(UpdateAccountChooserView, void());
47 class AccountChooserModelTest : public testing::Test {
49 AccountChooserModelTest()
50 : model_(&delegate_, &profile_, false, metric_logger_) {}
51 virtual ~AccountChooserModelTest() {}
53 TestingProfile* profile() { return &profile_; }
54 MockAccountChooserModelDelegate* delegate() { return &delegate_; }
55 TestAccountChooserModel* model() { return &model_; }
56 const AutofillMetrics& metric_logger() { return metric_logger_; }
59 TestingProfile profile_;
60 testing::NiceMock<MockAccountChooserModelDelegate> delegate_;
61 TestAccountChooserModel model_;
62 AutofillMetrics metric_logger_;
67 TEST_F(AccountChooserModelTest, ObeysPref) {
68 // When "Pay without wallet" is false, use Wallet by default.
70 profile()->GetPrefs()->SetBoolean(
71 ::prefs::kAutofillDialogPayWithoutWallet, false);
72 TestAccountChooserModel model(delegate(),
76 EXPECT_TRUE(model.WalletIsSelected());
78 // When the user chose to "Pay without wallet", use Autofill.
80 profile()->GetPrefs()->SetBoolean(
81 ::prefs::kAutofillDialogPayWithoutWallet, true);
82 TestAccountChooserModel model(delegate(),
86 EXPECT_FALSE(model.WalletIsSelected());
88 // When the |disable_wallet| argument is true, use Autofill regardless
91 profile()->GetPrefs()->SetBoolean(
92 ::prefs::kAutofillDialogPayWithoutWallet, false);
93 TestAccountChooserModel model(delegate(), profile(), true, metric_logger());
94 EXPECT_FALSE(model.WalletIsSelected());
96 // In incognito, use local data regardless of the pref.
98 Profile* incognito = profile()->GetOffTheRecordProfile();
99 profile()->GetPrefs()->SetBoolean(
100 ::prefs::kAutofillDialogPayWithoutWallet, false);
101 incognito->GetPrefs()->SetBoolean(
102 ::prefs::kAutofillDialogPayWithoutWallet, false);
104 TestAccountChooserModel model(
105 delegate(), incognito, false, metric_logger());
106 EXPECT_FALSE(model.WalletIsSelected());
110 TEST_F(AccountChooserModelTest, IgnoresPrefChanges) {
111 ASSERT_FALSE(profile()->GetPrefs()->GetBoolean(
112 ::prefs::kAutofillDialogPayWithoutWallet));
113 EXPECT_TRUE(model()->WalletIsSelected());
115 // Check that nothing changes while this dialog is running if a pref changes
116 // (this could cause subtle bugs or annoyances if a user closes another
118 profile()->GetPrefs()->SetBoolean(
119 ::prefs::kAutofillDialogPayWithoutWallet, true);
120 EXPECT_TRUE(model()->WalletIsSelected());
123 TEST_F(AccountChooserModelTest, HandlesError) {
124 EXPECT_CALL(*delegate(), AccountChoiceChanged()).Times(1);
125 EXPECT_CALL(*delegate(), UpdateAccountChooserView()).Times(1);
127 ASSERT_TRUE(model()->WalletIsSelected());
128 ASSERT_TRUE(model()->IsCommandIdEnabled(
129 TestAccountChooserModel::kWalletAccountsStartId));
131 model()->SetHadWalletError();
132 EXPECT_FALSE(model()->WalletIsSelected());
133 EXPECT_FALSE(model()->IsCommandIdEnabled(
134 TestAccountChooserModel::kWalletAccountsStartId));
137 TEST_F(AccountChooserModelTest, HandlesSigninError) {
138 EXPECT_CALL(*delegate(), AccountChoiceChanged()).Times(1);
139 EXPECT_CALL(*delegate(), UpdateAccountChooserView()).Times(2);
141 // 0. "Unknown" wallet account, we don't know if the user is signed-in yet.
142 ASSERT_TRUE(model()->WalletIsSelected());
143 ASSERT_TRUE(model()->IsCommandIdEnabled(
144 TestAccountChooserModel::kWalletAccountsStartId));
145 ASSERT_TRUE(model()->WalletIsSelected());
146 ASSERT_FALSE(model()->HasAccountsToChoose());
147 ASSERT_EQ(3, model()->GetItemCount());
148 EXPECT_EQ(base::string16(), model()->GetActiveWalletAccountName());
150 // 1. "Known" wallet account (e.g. after active/passive/automatic sign-in).
151 // Calls UpdateAccountChooserView.
152 std::vector<std::string> accounts;
153 accounts.push_back("john.doe@gmail.com");
154 model()->SetWalletAccounts(accounts, 0U);
155 ASSERT_TRUE(model()->WalletIsSelected());
156 ASSERT_TRUE(model()->IsCommandIdEnabled(
157 TestAccountChooserModel::kWalletAccountsStartId));
158 ASSERT_TRUE(model()->WalletIsSelected());
159 ASSERT_TRUE(model()->HasAccountsToChoose());
160 EXPECT_EQ(3, model()->GetItemCount());
161 EXPECT_EQ(ASCIIToUTF16(accounts[0]), model()->GetActiveWalletAccountName());
163 // 2. Sign-in failure.
164 // Autofill data should be selected and be the only valid choice.
165 // Calls UpdateAccountChooserView.
166 // Calls AccountChoiceChanged.
167 model()->SetHadWalletSigninError();
168 EXPECT_FALSE(model()->WalletIsSelected());
169 EXPECT_TRUE(model()->IsCommandIdEnabled(
170 TestAccountChooserModel::kWalletAccountsStartId));
171 EXPECT_FALSE(model()->WalletIsSelected());
172 EXPECT_FALSE(model()->HasAccountsToChoose());
173 EXPECT_EQ(2, model()->GetItemCount());
174 EXPECT_EQ(base::string16(), model()->GetActiveWalletAccountName());
177 TEST_F(AccountChooserModelTest, RespectsUserChoice) {
178 EXPECT_CALL(*delegate(), AccountChoiceChanged()).Times(2);
180 model()->ExecuteCommand(TestAccountChooserModel::kAutofillItemId, 0);
181 EXPECT_FALSE(model()->WalletIsSelected());
183 EXPECT_CALL(*delegate(), AddAccount());
184 model()->ExecuteCommand(TestAccountChooserModel::kWalletAddAccountId, 0);
185 EXPECT_FALSE(model()->WalletIsSelected());
187 model()->ExecuteCommand(TestAccountChooserModel::kWalletAccountsStartId, 0);
188 EXPECT_TRUE(model()->WalletIsSelected());
191 TEST_F(AccountChooserModelTest, HandlesMultipleAccounts) {
192 EXPECT_FALSE(model()->HasAccountsToChoose());
194 std::vector<std::string> accounts;
195 accounts.push_back("john.doe@gmail.com");
196 accounts.push_back("jane.smith@gmail.com");
197 model()->SetWalletAccounts(accounts, 0U);
198 EXPECT_TRUE(model()->HasAccountsToChoose());
199 EXPECT_TRUE(model()->WalletIsSelected());
200 ASSERT_EQ(4, model()->GetItemCount());
201 EXPECT_TRUE(model()->IsCommandIdEnabled(
202 TestAccountChooserModel::kWalletAccountsStartId));
203 EXPECT_TRUE(model()->IsCommandIdEnabled(
204 TestAccountChooserModel::kWalletAccountsStartId + 1));
205 EXPECT_EQ(ASCIIToUTF16(accounts[0]), model()->GetActiveWalletAccountName());
206 model()->SetWalletAccounts(accounts, 1U);
207 EXPECT_EQ(ASCIIToUTF16(accounts[1]), model()->GetActiveWalletAccountName());
209 model()->ExecuteCommand(TestAccountChooserModel::kWalletAccountsStartId, 0);
210 EXPECT_EQ(ASCIIToUTF16(accounts[0]), model()->GetActiveWalletAccountName());
211 model()->ExecuteCommand(TestAccountChooserModel::kWalletAccountsStartId + 1,
213 EXPECT_EQ(ASCIIToUTF16(accounts[1]), model()->GetActiveWalletAccountName());
215 // Setting the wallet accounts forces the switch to wallet.
216 model()->ExecuteCommand(TestAccountChooserModel::kAutofillItemId, 0);
217 EXPECT_FALSE(model()->WalletIsSelected());
218 model()->SetWalletAccounts(accounts, 1U);
219 EXPECT_TRUE(model()->WalletIsSelected());
222 } // namespace autofill