Home | History | Annotate | Download | only in profiles
      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 <string>
      6 
      7 #include "ash/ash_switches.h"
      8 #include "base/command_line.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/strings/string16.h"
     11 #include "base/strings/utf_string_conversions.h"
     12 #include "chrome/browser/chromeos/login/fake_user_manager.h"
     13 #include "chrome/browser/chromeos/profiles/profile_helper.h"
     14 #include "chrome/browser/prefs/pref_service_syncable.h"
     15 #include "chrome/browser/profiles/avatar_menu.h"
     16 #include "chrome/browser/profiles/avatar_menu_observer.h"
     17 #include "chrome/browser/profiles/profile_info_cache.h"
     18 #include "chrome/browser/ui/ash/chrome_shell_delegate.h"
     19 #include "chrome/common/chrome_constants.h"
     20 #include "chrome/common/chrome_switches.h"
     21 #include "chrome/test/base/testing_browser_process.h"
     22 #include "chrome/test/base/testing_profile_manager.h"
     23 #include "testing/gtest/include/gtest/gtest.h"
     24 #include "ui/base/l10n/l10n_util.h"
     25 
     26 namespace {
     27 
     28 // As defined in /chromeos/dbus/cryptohome_client.cc.
     29 static const char kUserIdHashSuffix[] = "-hash";
     30 
     31 class MockObserver : public AvatarMenuObserver {
     32  public:
     33   MockObserver() : count_(0) {}
     34   virtual ~MockObserver() {}
     35 
     36   virtual void OnAvatarMenuChanged(
     37       AvatarMenu* avatar_menu) OVERRIDE {
     38     ++count_;
     39   }
     40 
     41   int change_count() const { return count_; }
     42 
     43  private:
     44   int count_;
     45 
     46   DISALLOW_COPY_AND_ASSIGN(MockObserver);
     47 };
     48 
     49 }  // namespace
     50 
     51 namespace chromeos {
     52 
     53 class ProfileListChromeOSTest : public testing::Test {
     54  public:
     55   ProfileListChromeOSTest()
     56       : manager_(TestingBrowserProcess::GetGlobal()) {
     57   }
     58 
     59   virtual void SetUp() {
     60     ASSERT_TRUE(manager_.SetUp());
     61 
     62     // AvatarMenu and multiple profiles works after user logged in.
     63     manager_.SetLoggedIn(true);
     64 
     65     // We only instantiate UserMenuModel if multi-profile mode is enabled.
     66     CommandLine* cl = CommandLine::ForCurrentProcess();
     67     cl->AppendSwitch(switches::kMultiProfiles);
     68 
     69     // Initialize the UserManager singleton to a fresh FakeUserManager instance.
     70     user_manager_enabler_.reset(
     71         new ScopedUserManagerEnabler(new FakeUserManager));
     72   }
     73 
     74   FakeUserManager* GetFakeUserManager() {
     75     return static_cast<FakeUserManager*>(UserManager::Get());
     76   }
     77 
     78   void AddProfile(base::string16 name, bool log_in) {
     79     std::string email_string = UTF16ToASCII(name) + "@example.com";
     80 
     81     // Add a user to the fake user manager.
     82     GetFakeUserManager()->AddUser(email_string);
     83     if (log_in) {
     84       GetFakeUserManager()->UserLoggedIn(
     85           email_string,
     86           email_string + kUserIdHashSuffix,
     87           false);
     88     }
     89 
     90     // Create a profile for the user.
     91     manager()->CreateTestingProfile(
     92         chrome::kProfileDirPrefix + email_string + kUserIdHashSuffix,
     93         scoped_ptr<PrefServiceSyncable>(),
     94         ASCIIToUTF16(email_string), 0, std::string(),
     95         TestingProfile::TestingFactories());
     96   }
     97 
     98   AvatarMenu* GetAvatarMenu() {
     99     // Reset the MockObserver.
    100     mock_observer_.reset(new MockObserver());
    101     EXPECT_EQ(0, change_count());
    102 
    103     // Reset the menu.
    104     avatar_menu_.reset(new AvatarMenu(
    105         manager()->profile_info_cache(),
    106         mock_observer_.get(),
    107         NULL));
    108     avatar_menu_->RebuildMenu();
    109     EXPECT_EQ(0, change_count());
    110     return avatar_menu_.get();
    111   }
    112 
    113   void ActiveUserChanged(ProfileHelper* profile_helper,
    114                          const std::string& hash) {
    115     profile_helper->ActiveUserHashChanged(hash);
    116   }
    117 
    118   TestingProfileManager* manager() { return &manager_; }
    119 
    120   int change_count() const { return mock_observer_->change_count(); }
    121 
    122  private:
    123   TestingProfileManager manager_;
    124   scoped_ptr<MockObserver> mock_observer_;
    125   scoped_ptr<ScopedUserManagerEnabler> user_manager_enabler_;
    126   scoped_ptr<AvatarMenu> avatar_menu_;
    127   ChromeShellDelegate chrome_shell_delegate_;
    128 
    129   DISALLOW_COPY_AND_ASSIGN(ProfileListChromeOSTest);
    130 };
    131 
    132 TEST_F(ProfileListChromeOSTest, InitialCreation) {
    133   base::string16 name1(ASCIIToUTF16("p1"));
    134 
    135   AddProfile(name1, true);
    136 
    137   AvatarMenu* menu = GetAvatarMenu();
    138 
    139   ASSERT_EQ(1U, menu->GetNumberOfItems());
    140 
    141   const AvatarMenu::Item& item1 = menu->GetItemAt(0);
    142   EXPECT_EQ(0U, item1.menu_index);
    143   EXPECT_EQ(name1, item1.name);
    144 }
    145 
    146 TEST_F(ProfileListChromeOSTest, ShowLoggedInUsers) {
    147   base::string16 name1(ASCIIToUTF16("p1"));
    148   base::string16 name2(ASCIIToUTF16("p2"));
    149   base::string16 name3(ASCIIToUTF16("p3"));
    150   base::string16 name4(ASCIIToUTF16("p4"));
    151 
    152   AddProfile(name1, true);
    153   AddProfile(name2, false);
    154   AddProfile(name3, true);
    155   AddProfile(name4, false);
    156 
    157   AvatarMenu* menu = GetAvatarMenu();
    158 
    159   ASSERT_EQ(2U, menu->GetNumberOfItems());
    160 
    161   const AvatarMenu::Item& item1 = menu->GetItemAt(0);
    162   EXPECT_EQ(0U, item1.menu_index);
    163   EXPECT_EQ(name1, item1.name);
    164 
    165   const AvatarMenu::Item& item3 = menu->GetItemAt(1);
    166   EXPECT_EQ(1U, item3.menu_index);
    167   EXPECT_EQ(name3, item3.name);
    168 }
    169 
    170 TEST_F(ProfileListChromeOSTest, DontShowManagedUsers) {
    171   base::string16 name1(ASCIIToUTF16("p1"));
    172   base::string16 managed_name(ASCIIToUTF16("p2 (at) example.com"));
    173 
    174   AddProfile(name1, true);
    175 
    176   // Add a managed user profile.
    177   ProfileInfoCache* cache = manager()->profile_info_cache();
    178   manager()->profile_info_cache()->AddProfileToCache(
    179       cache->GetUserDataDir().AppendASCII("p2"), managed_name,
    180       base::string16(), 0, "TEST_ID");
    181 
    182   GetFakeUserManager()->AddUser(UTF16ToASCII(managed_name));
    183 
    184   AvatarMenu* menu = GetAvatarMenu();
    185   ASSERT_EQ(1U, menu->GetNumberOfItems());
    186 
    187   const AvatarMenu::Item& item1 = menu->GetItemAt(0);
    188   EXPECT_EQ(0U, item1.menu_index);
    189   EXPECT_EQ(name1, item1.name);
    190 }
    191 
    192 TEST_F(ProfileListChromeOSTest, ShowAddProfileLink) {
    193   base::string16 name1(ASCIIToUTF16("p1.com"));
    194   base::string16 name2(ASCIIToUTF16("p2.com"));
    195 
    196   AddProfile(name1, true);
    197   AddProfile(name2, false);
    198 
    199   AvatarMenu* menu = GetAvatarMenu();
    200 
    201   ASSERT_EQ(1U, menu->GetNumberOfItems());
    202   EXPECT_TRUE(menu->ShouldShowAddNewProfileLink());
    203 }
    204 
    205 TEST_F(ProfileListChromeOSTest, DontShowAddProfileLink) {
    206   base::string16 name1(ASCIIToUTF16("p1.com"));
    207   base::string16 name2(ASCIIToUTF16("p2.com"));
    208 
    209   AddProfile(name1, true);
    210   AddProfile(name2, true);
    211 
    212   AvatarMenu* menu = GetAvatarMenu();
    213 
    214   ASSERT_EQ(2U, menu->GetNumberOfItems());
    215   EXPECT_FALSE(menu->ShouldShowAddNewProfileLink());
    216 }
    217 
    218 TEST_F(ProfileListChromeOSTest, ActiveItem) {
    219   base::string16 name1(ASCIIToUTF16("p1.com"));
    220   base::string16 name2(ASCIIToUTF16("p2.com"));
    221 
    222   AddProfile(name1, true);
    223   AddProfile(name2, true);
    224 
    225   // Initialize ProfileHelper, it will be accessed from GetActiveProfileIndex.
    226   std::string email_string = UTF16ToASCII(name1) + "@example.com";
    227   std::string hash = email_string + kUserIdHashSuffix;
    228   ActiveUserChanged(
    229       g_browser_process->platform_part()->profile_helper(), hash);
    230 
    231   AvatarMenu* menu = GetAvatarMenu();
    232 
    233   ASSERT_EQ(2U, menu->GetNumberOfItems());
    234   // TODO(jeremy): Expand test to verify active profile index other than 0
    235   // crbug.com/100871
    236   ASSERT_EQ(0U, menu->GetActiveProfileIndex());
    237 }
    238 
    239 TEST_F(ProfileListChromeOSTest, ModifyingNameResortsCorrectly) {
    240   base::string16 name1(ASCIIToUTF16("Alpha"));
    241   base::string16 name2(ASCIIToUTF16("Beta"));
    242   base::string16 newname1(ASCIIToUTF16("Gamma"));
    243 
    244   AddProfile(name1, true);
    245   AddProfile(name2, true);
    246 
    247   AvatarMenu* menu = GetAvatarMenu();
    248 
    249   ASSERT_EQ(2U, menu->GetNumberOfItems());
    250 
    251   const AvatarMenu::Item& item1 = menu->GetItemAt(0);
    252   EXPECT_EQ(0U, item1.menu_index);
    253   EXPECT_EQ(name1, item1.name);
    254 
    255   const AvatarMenu::Item& item2 = menu->GetItemAt(1);
    256   EXPECT_EQ(1U, item2.menu_index);
    257   EXPECT_EQ(name2, item2.name);
    258 
    259   // Change name of the first profile, to trigger resorting of the profiles:
    260   // now the first menu item should be named "beta", and the second be "gamma".
    261   GetFakeUserManager()->SaveUserDisplayName(
    262       UTF16ToASCII(name1) + "@example.com", newname1);
    263   manager()->profile_info_cache()->SetNameOfProfileAtIndex(0, newname1);
    264 
    265   const AvatarMenu::Item& item1next = menu->GetItemAt(0);
    266   EXPECT_GT(change_count(), 1);
    267   EXPECT_EQ(0U, item1next.menu_index);
    268   EXPECT_EQ(name2, item1next.name);
    269 
    270   const AvatarMenu::Item& item2next = menu->GetItemAt(1);
    271   EXPECT_EQ(1U, item2next.menu_index);
    272   EXPECT_EQ(newname1, item2next.name);
    273 }
    274 
    275 TEST_F(ProfileListChromeOSTest, ChangeOnNotify) {
    276   base::string16 name1(ASCIIToUTF16("p1.com"));
    277   base::string16 name2(ASCIIToUTF16("p2.com"));
    278 
    279   AddProfile(name1, true);
    280   AddProfile(name2, true);
    281 
    282   AvatarMenu* menu = GetAvatarMenu();
    283   EXPECT_EQ(2U, menu->GetNumberOfItems());
    284 
    285   base::string16 name3(ASCIIToUTF16("p3.com"));
    286   AddProfile(name3, true);
    287 
    288   // Four changes happened via the call to CreateTestingProfile: adding the
    289   // profile to the cache, setting the user name, rebuilding the list of
    290   // profiles after the name change, and changing the avatar.
    291   // TODO(michaelpg): Determine why actual change number does not match comment.
    292   EXPECT_GE(change_count(), 4);
    293   ASSERT_EQ(3U, menu->GetNumberOfItems());
    294 
    295   const AvatarMenu::Item& item1 = menu->GetItemAt(0);
    296   EXPECT_EQ(0U, item1.menu_index);
    297   EXPECT_EQ(name1, item1.name);
    298 
    299   const AvatarMenu::Item& item2 = menu->GetItemAt(1);
    300   EXPECT_EQ(1U, item2.menu_index);
    301   EXPECT_EQ(name2, item2.name);
    302 
    303   const AvatarMenu::Item& item3 = menu->GetItemAt(2);
    304   EXPECT_EQ(2U, item3.menu_index);
    305   EXPECT_EQ(name3, item3.name);
    306 }
    307 
    308 TEST_F(ProfileListChromeOSTest, DontShowAvatarMenu) {
    309   // If in the new M-32 UX mode the icon gets shown, the menu will not.
    310   base::string16 name1(ASCIIToUTF16("p1"));
    311   base::string16 name2(ASCIIToUTF16("p2"));
    312 
    313   AddProfile(name1, true);
    314 
    315   // Should only show avatar menu with multiple users.
    316   EXPECT_FALSE(AvatarMenu::ShouldShowAvatarMenu());
    317 
    318   AddProfile(name2, false);
    319 
    320   EXPECT_FALSE(AvatarMenu::ShouldShowAvatarMenu());
    321 }
    322 
    323 TEST_F(ProfileListChromeOSTest, ShowAvatarMenuInM31) {
    324   // In M-31 mode, the menu will get shown.
    325   CommandLine* cl = CommandLine::ForCurrentProcess();
    326   cl->AppendSwitch(ash::switches::kAshEnableFullMultiProfileMode);
    327 
    328   base::string16 name1(ASCIIToUTF16("p1"));
    329   base::string16 name2(ASCIIToUTF16("p2"));
    330 
    331   AddProfile(name1, true);
    332 
    333   // Should only show avatar menu with multiple users.
    334   EXPECT_FALSE(AvatarMenu::ShouldShowAvatarMenu());
    335 
    336   AddProfile(name2, false);
    337 
    338   EXPECT_TRUE(AvatarMenu::ShouldShowAvatarMenu());
    339 }
    340 
    341 }  // namespace chromeos
    342