Home | History | Annotate | Download | only in profiles
      1 // Copyright (c) 2012 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 "chrome/browser/profiles/profile_list_desktop.h"
      6 
      7 #include <string>
      8 
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/metrics/field_trial.h"
     11 #include "base/strings/string16.h"
     12 #include "base/strings/utf_string_conversions.h"
     13 #include "chrome/browser/prefs/pref_service_syncable.h"
     14 #include "chrome/browser/profiles/avatar_menu_observer.h"
     15 #include "chrome/browser/profiles/profile_info_cache.h"
     16 #include "chrome/browser/profiles/profiles_state.h"
     17 #include "chrome/test/base/testing_browser_process.h"
     18 #include "chrome/test/base/testing_profile_manager.h"
     19 #include "grit/generated_resources.h"
     20 #include "testing/gtest/include/gtest/gtest.h"
     21 #include "ui/base/l10n/l10n_util.h"
     22 
     23 using base::ASCIIToUTF16;
     24 
     25 namespace {
     26 
     27 class MockObserver : public AvatarMenuObserver {
     28  public:
     29   MockObserver() : count_(0) {}
     30   virtual ~MockObserver() {}
     31 
     32   virtual void OnAvatarMenuChanged(
     33       AvatarMenu* avatar_menu) OVERRIDE {
     34     ++count_;
     35   }
     36 
     37   int change_count() const { return count_; }
     38 
     39  private:
     40   int count_;
     41 
     42   DISALLOW_COPY_AND_ASSIGN(MockObserver);
     43 };
     44 
     45 class ProfileListDesktopTest : public testing::Test {
     46  public:
     47   ProfileListDesktopTest()
     48       : manager_(TestingBrowserProcess::GetGlobal()) {
     49   }
     50 
     51   virtual void SetUp() {
     52     ASSERT_TRUE(manager_.SetUp());
     53 #if defined(OS_CHROMEOS)
     54     // AvatarMenu and multiple profiles works after user logged in.
     55     manager_.SetLoggedIn(true);
     56 #endif
     57   }
     58 
     59   AvatarMenu* GetAvatarMenu() {
     60     // Reset the MockObserver.
     61     mock_observer_.reset(new MockObserver());
     62     EXPECT_EQ(0, change_count());
     63 
     64     // Reset the model.
     65     avatar_menu_.reset(new AvatarMenu(
     66         manager()->profile_info_cache(),
     67         mock_observer_.get(),
     68         NULL));
     69     avatar_menu_->RebuildMenu();
     70     EXPECT_EQ(0, change_count());
     71     return avatar_menu_.get();
     72   }
     73 
     74   TestingProfileManager* manager() { return &manager_; }
     75 
     76   void AddOmittedProfile(std::string name) {
     77     ProfileInfoCache* cache = manager()->profile_info_cache();
     78     cache->AddProfileToCache(
     79         cache->GetUserDataDir().AppendASCII(name), ASCIIToUTF16(name),
     80         base::string16(), 0, "TEST_ID");
     81   }
     82 
     83   int change_count() const { return mock_observer_->change_count(); }
     84 
     85  private:
     86   TestingProfileManager manager_;
     87   scoped_ptr<MockObserver> mock_observer_;
     88   scoped_ptr<AvatarMenu> avatar_menu_;
     89 
     90   DISALLOW_COPY_AND_ASSIGN(ProfileListDesktopTest);
     91 };
     92 
     93 TEST_F(ProfileListDesktopTest, InitialCreation) {
     94   manager()->CreateTestingProfile("Test 1");
     95   manager()->CreateTestingProfile("Test 2");
     96 
     97   AvatarMenu* model = GetAvatarMenu();
     98   EXPECT_EQ(0, change_count());
     99 
    100   ASSERT_EQ(2U, model->GetNumberOfItems());
    101 
    102   const AvatarMenu::Item& item1 = model->GetItemAt(0);
    103   EXPECT_EQ(0U, item1.menu_index);
    104   EXPECT_EQ(ASCIIToUTF16("Test 1"), item1.name);
    105 
    106   const AvatarMenu::Item& item2 = model->GetItemAt(1);
    107   EXPECT_EQ(1U, item2.menu_index);
    108   EXPECT_EQ(ASCIIToUTF16("Test 2"), item2.name);
    109 }
    110 
    111 TEST_F(ProfileListDesktopTest, NoOmittedProfiles) {
    112   ProfileListDesktop profile_list(manager()->profile_info_cache());
    113 
    114   // Profiles are stored and listed alphabetically.
    115   manager()->CreateTestingProfile("1 included");
    116   manager()->CreateTestingProfile("2 included");
    117   manager()->CreateTestingProfile("3 included");
    118   manager()->CreateTestingProfile("4 included");
    119 
    120   profile_list.RebuildMenu();
    121   ASSERT_EQ(4u, profile_list.GetNumberOfItems());
    122 
    123   const AvatarMenu::Item& item1 = profile_list.GetItemAt(0);
    124   EXPECT_EQ(0u, item1.menu_index);
    125   EXPECT_EQ(0u, item1.profile_index);
    126   EXPECT_EQ(ASCIIToUTF16("1 included"), item1.name);
    127 
    128   const AvatarMenu::Item& item2 = profile_list.GetItemAt(1);
    129   EXPECT_EQ(1u, item2.menu_index);
    130   EXPECT_EQ(1u, item2.profile_index);
    131   EXPECT_EQ(ASCIIToUTF16("2 included"), item2.name);
    132 
    133   const AvatarMenu::Item& item3 = profile_list.GetItemAt(2);
    134   EXPECT_EQ(2u, item3.menu_index);
    135   EXPECT_EQ(2u, item3.profile_index);
    136   EXPECT_EQ(ASCIIToUTF16("3 included"), item3.name);
    137 
    138   const AvatarMenu::Item& item4 = profile_list.GetItemAt(3);
    139   EXPECT_EQ(3u, item4.menu_index);
    140   EXPECT_EQ(3u, item4.profile_index);
    141   EXPECT_EQ(ASCIIToUTF16("4 included"), item4.name);
    142 
    143   EXPECT_EQ(0u, profile_list.MenuIndexFromProfileIndex(0));
    144   EXPECT_EQ(1u, profile_list.MenuIndexFromProfileIndex(1));
    145   EXPECT_EQ(2u, profile_list.MenuIndexFromProfileIndex(2));
    146   EXPECT_EQ(3u, profile_list.MenuIndexFromProfileIndex(3));
    147 }
    148 
    149 TEST_F(ProfileListDesktopTest, WithOmittedProfiles) {
    150   ProfileListDesktop profile_list(manager()->profile_info_cache());
    151 
    152   // Profiles are stored and listed alphabetically.
    153   AddOmittedProfile("0 omitted");
    154   manager()->CreateTestingProfile("1 included");
    155   AddOmittedProfile("2 omitted");
    156   manager()->CreateTestingProfile("3 included");
    157   manager()->CreateTestingProfile("4 included");
    158   AddOmittedProfile("5 omitted");
    159   manager()->CreateTestingProfile("6 included");
    160   AddOmittedProfile("7 omitted");
    161 
    162   profile_list.RebuildMenu();
    163   ASSERT_EQ(4u, profile_list.GetNumberOfItems());
    164 
    165   const AvatarMenu::Item& item1 = profile_list.GetItemAt(0);
    166   EXPECT_EQ(0u, item1.menu_index);
    167   EXPECT_EQ(1u, item1.profile_index);
    168   EXPECT_EQ(ASCIIToUTF16("1 included"), item1.name);
    169 
    170   const AvatarMenu::Item& item2 = profile_list.GetItemAt(1);
    171   EXPECT_EQ(1u, item2.menu_index);
    172   EXPECT_EQ(3u, item2.profile_index);
    173   EXPECT_EQ(ASCIIToUTF16("3 included"), item2.name);
    174 
    175   const AvatarMenu::Item& item3 = profile_list.GetItemAt(2);
    176   EXPECT_EQ(2u, item3.menu_index);
    177   EXPECT_EQ(4u, item3.profile_index);
    178   EXPECT_EQ(ASCIIToUTF16("4 included"), item3.name);
    179 
    180   const AvatarMenu::Item& item4 = profile_list.GetItemAt(3);
    181   EXPECT_EQ(3u, item4.menu_index);
    182   EXPECT_EQ(6u, item4.profile_index);
    183   EXPECT_EQ(ASCIIToUTF16("6 included"), item4.name);
    184 
    185   EXPECT_EQ(0u, profile_list.MenuIndexFromProfileIndex(1));
    186   EXPECT_EQ(1u, profile_list.MenuIndexFromProfileIndex(3));
    187   EXPECT_EQ(2u, profile_list.MenuIndexFromProfileIndex(4));
    188   EXPECT_EQ(3u, profile_list.MenuIndexFromProfileIndex(6));
    189 }
    190 
    191 TEST_F(ProfileListDesktopTest, ActiveItem) {
    192   manager()->CreateTestingProfile("Test 1");
    193   manager()->CreateTestingProfile("Test 2");
    194 
    195   AvatarMenu* model = GetAvatarMenu();
    196   ASSERT_EQ(2U, model->GetNumberOfItems());
    197   // TODO(jeremy): Expand test to verify active profile index other than 0
    198   // crbug.com/100871
    199   ASSERT_EQ(0U, model->GetActiveProfileIndex());
    200 }
    201 
    202 TEST_F(ProfileListDesktopTest, ModifyingNameResortsCorrectly) {
    203   std::string name1("Alpha");
    204   std::string name2("Beta");
    205   std::string newname1("Gamma");
    206 
    207   manager()->CreateTestingProfile(name1);
    208   manager()->CreateTestingProfile(name2);
    209 
    210   AvatarMenu* model = GetAvatarMenu();
    211   EXPECT_EQ(0, change_count());
    212 
    213   ASSERT_EQ(2U, model->GetNumberOfItems());
    214 
    215   const AvatarMenu::Item& item1 = model->GetItemAt(0);
    216   EXPECT_EQ(0U, item1.menu_index);
    217   EXPECT_EQ(ASCIIToUTF16(name1), item1.name);
    218 
    219   const AvatarMenu::Item& item2 = model->GetItemAt(1);
    220   EXPECT_EQ(1U, item2.menu_index);
    221   EXPECT_EQ(ASCIIToUTF16(name2), item2.name);
    222 
    223   // Change name of the first profile, to trigger resorting of the profiles:
    224   // now the first model should be named "beta", and the second be "gamma".
    225   manager()->profile_info_cache()->SetNameOfProfileAtIndex(0,
    226         ASCIIToUTF16(newname1));
    227   const AvatarMenu::Item& item1next = model->GetItemAt(0);
    228   EXPECT_GT(change_count(), 1);
    229   EXPECT_EQ(0U, item1next.menu_index);
    230   EXPECT_EQ(ASCIIToUTF16(name2), item1next.name);
    231 
    232   const AvatarMenu::Item& item2next = model->GetItemAt(1);
    233   EXPECT_EQ(1U, item2next.menu_index);
    234   EXPECT_EQ(ASCIIToUTF16(newname1), item2next.name);
    235 }
    236 
    237 TEST_F(ProfileListDesktopTest, ChangeOnNotify) {
    238   manager()->CreateTestingProfile("Test 1");
    239   manager()->CreateTestingProfile("Test 2");
    240 
    241   AvatarMenu* model = GetAvatarMenu();
    242   EXPECT_EQ(0, change_count());
    243   EXPECT_EQ(2U, model->GetNumberOfItems());
    244 
    245   manager()->CreateTestingProfile("Test 3");
    246 
    247   // Four changes happened via the call to CreateTestingProfile: adding the
    248   // profile to the cache, setting the user name, rebuilding the list of
    249   // profiles after the name change, and changing the avatar.
    250   // On Windows, an extra change happens to set the shortcut name for the
    251   // profile.
    252   // TODO(michaelpg): Determine why five changes happen on ChromeOS and
    253   // investigate other platforms.
    254   EXPECT_GE(change_count(), 4);
    255   ASSERT_EQ(3U, model->GetNumberOfItems());
    256 
    257   const AvatarMenu::Item& item1 = model->GetItemAt(0);
    258   EXPECT_EQ(0U, item1.menu_index);
    259   EXPECT_EQ(ASCIIToUTF16("Test 1"), item1.name);
    260 
    261   const AvatarMenu::Item& item2 = model->GetItemAt(1);
    262   EXPECT_EQ(1U, item2.menu_index);
    263   EXPECT_EQ(ASCIIToUTF16("Test 2"), item2.name);
    264 
    265   const AvatarMenu::Item& item3 = model->GetItemAt(2);
    266   EXPECT_EQ(2U, item3.menu_index);
    267   EXPECT_EQ(ASCIIToUTF16("Test 3"), item3.name);
    268 }
    269 
    270 TEST_F(ProfileListDesktopTest, ShowAvatarMenuInTrial) {
    271   // If multiprofile mode is not enabled, the trial will not be enabled, so it
    272   // isn't tested.
    273   if (!profiles::IsMultipleProfilesEnabled())
    274     return;
    275 
    276   base::FieldTrialList field_trial_list_(NULL);
    277   base::FieldTrialList::CreateFieldTrial("ShowProfileSwitcher", "AlwaysShow");
    278 
    279 #if defined(OS_CHROMEOS)
    280   EXPECT_FALSE(AvatarMenu::ShouldShowAvatarMenu());
    281 #else
    282   EXPECT_TRUE(AvatarMenu::ShouldShowAvatarMenu());
    283 #endif
    284 }
    285 
    286 TEST_F(ProfileListDesktopTest, DontShowAvatarMenu) {
    287   manager()->CreateTestingProfile("Test 1");
    288 
    289   EXPECT_FALSE(AvatarMenu::ShouldShowAvatarMenu());
    290 
    291   // If multiprofile mode is enabled, there are no other cases when we wouldn't
    292   // show the menu.
    293   if (profiles::IsMultipleProfilesEnabled())
    294     return;
    295 
    296   manager()->CreateTestingProfile("Test 2");
    297 
    298   EXPECT_FALSE(AvatarMenu::ShouldShowAvatarMenu());
    299 }
    300 
    301 TEST_F(ProfileListDesktopTest, ShowAvatarMenu) {
    302   // If multiprofile mode is not enabled then the menu is never shown.
    303   if (!profiles::IsMultipleProfilesEnabled())
    304     return;
    305 
    306   manager()->CreateTestingProfile("Test 1");
    307   manager()->CreateTestingProfile("Test 2");
    308 
    309 #if defined(OS_CHROMEOS)
    310   EXPECT_FALSE(AvatarMenu::ShouldShowAvatarMenu());
    311 #else
    312   EXPECT_TRUE(AvatarMenu::ShouldShowAvatarMenu());
    313 #endif
    314 }
    315 
    316 TEST_F(ProfileListDesktopTest, SyncState) {
    317   // If multiprofile mode is not enabled then the menu is never shown.
    318   if (!profiles::IsMultipleProfilesEnabled())
    319     return;
    320 
    321   manager()->CreateTestingProfile("Test 1");
    322 
    323   // Add a managed user profile.
    324   ProfileInfoCache* cache = manager()->profile_info_cache();
    325   base::FilePath path = cache->GetUserDataDir().AppendASCII("p2");
    326   cache->AddProfileToCache(path, ASCIIToUTF16("Test 2"), base::string16(), 0,
    327                            "TEST_ID");
    328   cache->SetIsOmittedProfileAtIndex(cache->GetIndexOfProfileWithPath(path),
    329                                     false);
    330 
    331   AvatarMenu* model = GetAvatarMenu();
    332   model->RebuildMenu();
    333   EXPECT_EQ(2U, model->GetNumberOfItems());
    334 
    335   // Now check that the sync_state of a managed user shows the managed user
    336   // avatar label instead.
    337   base::string16 managed_user_label =
    338       l10n_util::GetStringUTF16(IDS_MANAGED_USER_AVATAR_LABEL);
    339   const AvatarMenu::Item& item1 = model->GetItemAt(0);
    340   EXPECT_NE(item1.sync_state, managed_user_label);
    341 
    342   const AvatarMenu::Item& item2 = model->GetItemAt(1);
    343   EXPECT_EQ(item2.sync_state, managed_user_label);
    344 }
    345 
    346 }  // namespace
    347