Home | History | Annotate | Download | only in autofill
      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 
     14 using base::ASCIIToUTF16;
     15 
     16 namespace autofill {
     17 
     18 namespace {
     19 
     20 class 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 
     37 class MockAccountChooserModelDelegate : public AccountChooserModelDelegate {
     38  public:
     39   MockAccountChooserModelDelegate() {}
     40   virtual ~MockAccountChooserModelDelegate() {}
     41 
     42   MOCK_METHOD0(AccountChoiceChanged, void());
     43   MOCK_METHOD0(AddAccount, void());
     44   MOCK_METHOD0(UpdateAccountChooserView, void());
     45 };
     46 
     47 class AccountChooserModelTest : public testing::Test {
     48  public:
     49   AccountChooserModelTest()
     50       : model_(&delegate_, &profile_, false, metric_logger_) {}
     51   virtual ~AccountChooserModelTest() {}
     52 
     53   TestingProfile* profile() { return &profile_; }
     54   MockAccountChooserModelDelegate* delegate() { return &delegate_; }
     55   TestAccountChooserModel* model() { return &model_; }
     56   const AutofillMetrics& metric_logger() { return metric_logger_; }
     57 
     58  private:
     59   TestingProfile profile_;
     60   testing::NiceMock<MockAccountChooserModelDelegate> delegate_;
     61   TestAccountChooserModel model_;
     62   AutofillMetrics metric_logger_;
     63 };
     64 
     65 }  // namespace
     66 
     67 TEST_F(AccountChooserModelTest, ObeysPref) {
     68   // When "Pay without wallet" is false, use Wallet by default.
     69   {
     70     profile()->GetPrefs()->SetBoolean(
     71         ::prefs::kAutofillDialogPayWithoutWallet, false);
     72     TestAccountChooserModel model(delegate(),
     73                                   profile(),
     74                                   false,
     75                                   metric_logger());
     76     EXPECT_TRUE(model.WalletIsSelected());
     77   }
     78   // When the user chose to "Pay without wallet", use Autofill.
     79   {
     80     profile()->GetPrefs()->SetBoolean(
     81         ::prefs::kAutofillDialogPayWithoutWallet, true);
     82     TestAccountChooserModel model(delegate(),
     83                                   profile(),
     84                                   false,
     85                                   metric_logger());
     86     EXPECT_FALSE(model.WalletIsSelected());
     87   }
     88   // When the |disable_wallet| argument is true, use Autofill regardless
     89   // of the pref.
     90   {
     91     profile()->GetPrefs()->SetBoolean(
     92         ::prefs::kAutofillDialogPayWithoutWallet, false);
     93     TestAccountChooserModel model(delegate(), profile(), true, metric_logger());
     94     EXPECT_FALSE(model.WalletIsSelected());
     95   }
     96   // In incognito, use local data regardless of the pref.
     97   {
     98     Profile* incognito = profile()->GetOffTheRecordProfile();
     99     profile()->GetPrefs()->SetBoolean(
    100         ::prefs::kAutofillDialogPayWithoutWallet, false);
    101     incognito->GetPrefs()->SetBoolean(
    102         ::prefs::kAutofillDialogPayWithoutWallet, false);
    103 
    104     TestAccountChooserModel model(
    105         delegate(), incognito, false, metric_logger());
    106     EXPECT_FALSE(model.WalletIsSelected());
    107   }
    108 }
    109 
    110 TEST_F(AccountChooserModelTest, IgnoresPrefChanges) {
    111   ASSERT_FALSE(profile()->GetPrefs()->GetBoolean(
    112       ::prefs::kAutofillDialogPayWithoutWallet));
    113   EXPECT_TRUE(model()->WalletIsSelected());
    114 
    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
    117   // running dialog).
    118   profile()->GetPrefs()->SetBoolean(
    119       ::prefs::kAutofillDialogPayWithoutWallet, true);
    120   EXPECT_TRUE(model()->WalletIsSelected());
    121 }
    122 
    123 TEST_F(AccountChooserModelTest, HandlesError) {
    124   EXPECT_CALL(*delegate(), AccountChoiceChanged()).Times(1);
    125   EXPECT_CALL(*delegate(), UpdateAccountChooserView()).Times(1);
    126 
    127   ASSERT_TRUE(model()->WalletIsSelected());
    128   ASSERT_TRUE(model()->IsCommandIdEnabled(
    129       TestAccountChooserModel::kWalletAccountsStartId));
    130 
    131   model()->SetHadWalletError();
    132   EXPECT_FALSE(model()->WalletIsSelected());
    133   EXPECT_FALSE(model()->IsCommandIdEnabled(
    134       TestAccountChooserModel::kWalletAccountsStartId));
    135 }
    136 
    137 TEST_F(AccountChooserModelTest, HandlesSigninError) {
    138   EXPECT_CALL(*delegate(), AccountChoiceChanged()).Times(1);
    139   EXPECT_CALL(*delegate(), UpdateAccountChooserView()).Times(2);
    140 
    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());
    149 
    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 (at) 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());
    162 
    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());
    175 }
    176 
    177 TEST_F(AccountChooserModelTest, RespectsUserChoice) {
    178   EXPECT_CALL(*delegate(), AccountChoiceChanged()).Times(2);
    179 
    180   model()->ExecuteCommand(TestAccountChooserModel::kAutofillItemId, 0);
    181   EXPECT_FALSE(model()->WalletIsSelected());
    182 
    183   EXPECT_CALL(*delegate(), AddAccount());
    184   model()->ExecuteCommand(TestAccountChooserModel::kWalletAddAccountId, 0);
    185   EXPECT_FALSE(model()->WalletIsSelected());
    186 
    187   model()->ExecuteCommand(TestAccountChooserModel::kWalletAccountsStartId, 0);
    188   EXPECT_TRUE(model()->WalletIsSelected());
    189 }
    190 
    191 TEST_F(AccountChooserModelTest, HandlesMultipleAccounts) {
    192   EXPECT_FALSE(model()->HasAccountsToChoose());
    193 
    194   std::vector<std::string> accounts;
    195   accounts.push_back("john.doe (at) gmail.com");
    196   accounts.push_back("jane.smith (at) 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());
    208 
    209   model()->ExecuteCommand(TestAccountChooserModel::kWalletAccountsStartId, 0);
    210   EXPECT_EQ(ASCIIToUTF16(accounts[0]), model()->GetActiveWalletAccountName());
    211   model()->ExecuteCommand(TestAccountChooserModel::kWalletAccountsStartId + 1,
    212                           0);
    213   EXPECT_EQ(ASCIIToUTF16(accounts[1]), model()->GetActiveWalletAccountName());
    214 
    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());
    220 }
    221 
    222 }  // namespace autofill
    223