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