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