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