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