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