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.
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"
26 using base::ASCIIToUTF16
;
30 // As defined in /chromeos/dbus/cryptohome_client.cc.
31 static const char kUserIdHashSuffix
[] = "-hash";
33 class MockObserver
: public AvatarMenuObserver
{
35 MockObserver() : count_(0) {}
36 virtual ~MockObserver() {}
38 virtual void OnAvatarMenuChanged(
39 AvatarMenu
* avatar_menu
) OVERRIDE
{
43 int change_count() const { return count_
; }
48 DISALLOW_COPY_AND_ASSIGN(MockObserver
);
55 class ProfileListChromeOSTest
: public testing::Test
{
57 ProfileListChromeOSTest()
58 : manager_(TestingBrowserProcess::GetGlobal()) {
61 virtual void SetUp() {
62 ASSERT_TRUE(manager_
.SetUp());
64 // AvatarMenu and multiple profiles works after user logged in.
65 manager_
.SetLoggedIn(true);
67 // We only instantiate UserMenuModel if multi-profile mode is enabled.
68 CommandLine
* cl
= CommandLine::ForCurrentProcess();
69 cl
->AppendSwitch(switches::kMultiProfiles
);
71 // Initialize the UserManager singleton to a fresh FakeUserManager instance.
72 user_manager_enabler_
.reset(
73 new ScopedUserManagerEnabler(new FakeUserManager
));
76 FakeUserManager
* GetFakeUserManager() {
77 return static_cast<FakeUserManager
*>(UserManager::Get());
80 void AddProfile(base::string16 name
, bool log_in
) {
81 std::string email_string
= base::UTF16ToASCII(name
) + "@example.com";
83 // Add a user to the fake user manager.
84 GetFakeUserManager()->AddUser(email_string
);
86 GetFakeUserManager()->UserLoggedIn(
88 email_string
+ kUserIdHashSuffix
,
92 // Create a profile for the user.
93 manager()->CreateTestingProfile(
94 chrome::kProfileDirPrefix
+ email_string
+ kUserIdHashSuffix
,
95 scoped_ptr
<PrefServiceSyncable
>(),
96 ASCIIToUTF16(email_string
), 0, std::string(),
97 TestingProfile::TestingFactories());
100 AvatarMenu
* GetAvatarMenu() {
101 // Reset the MockObserver.
102 mock_observer_
.reset(new MockObserver());
103 EXPECT_EQ(0, change_count());
106 avatar_menu_
.reset(new AvatarMenu(
107 manager()->profile_info_cache(),
108 mock_observer_
.get(),
110 avatar_menu_
->RebuildMenu();
111 EXPECT_EQ(0, change_count());
112 return avatar_menu_
.get();
115 void ActiveUserChanged(ProfileHelper
* profile_helper
,
116 const std::string
& hash
) {
117 profile_helper
->ActiveUserHashChanged(hash
);
120 TestingProfileManager
* manager() { return &manager_
; }
122 int change_count() const { return mock_observer_
->change_count(); }
125 TestingProfileManager manager_
;
126 scoped_ptr
<MockObserver
> mock_observer_
;
127 scoped_ptr
<ScopedUserManagerEnabler
> user_manager_enabler_
;
128 scoped_ptr
<AvatarMenu
> avatar_menu_
;
129 ChromeShellDelegate chrome_shell_delegate_
;
131 DISALLOW_COPY_AND_ASSIGN(ProfileListChromeOSTest
);
134 TEST_F(ProfileListChromeOSTest
, InitialCreation
) {
135 base::string16
name1(ASCIIToUTF16("p1"));
137 AddProfile(name1
, true);
139 AvatarMenu
* menu
= GetAvatarMenu();
141 ASSERT_EQ(1U, menu
->GetNumberOfItems());
143 const AvatarMenu::Item
& item1
= menu
->GetItemAt(0);
144 EXPECT_EQ(0U, item1
.menu_index
);
145 EXPECT_EQ(name1
, item1
.name
);
148 TEST_F(ProfileListChromeOSTest
, ShowLoggedInUsers
) {
149 base::string16
name1(ASCIIToUTF16("p1"));
150 base::string16
name2(ASCIIToUTF16("p2"));
151 base::string16
name3(ASCIIToUTF16("p3"));
152 base::string16
name4(ASCIIToUTF16("p4"));
154 AddProfile(name1
, true);
155 AddProfile(name2
, false);
156 AddProfile(name3
, true);
157 AddProfile(name4
, false);
159 AvatarMenu
* menu
= GetAvatarMenu();
161 ASSERT_EQ(2U, menu
->GetNumberOfItems());
163 const AvatarMenu::Item
& item1
= menu
->GetItemAt(0);
164 EXPECT_EQ(0U, item1
.menu_index
);
165 EXPECT_EQ(name1
, item1
.name
);
167 const AvatarMenu::Item
& item3
= menu
->GetItemAt(1);
168 EXPECT_EQ(1U, item3
.menu_index
);
169 EXPECT_EQ(name3
, item3
.name
);
172 TEST_F(ProfileListChromeOSTest
, DontShowManagedUsers
) {
173 base::string16
name1(ASCIIToUTF16("p1"));
174 base::string16
managed_name(ASCIIToUTF16("p2@example.com"));
176 AddProfile(name1
, true);
178 // Add a managed user profile.
179 ProfileInfoCache
* cache
= manager()->profile_info_cache();
180 manager()->profile_info_cache()->AddProfileToCache(
181 cache
->GetUserDataDir().AppendASCII("p2"), managed_name
,
182 base::string16(), 0, "TEST_ID");
184 GetFakeUserManager()->AddUser(base::UTF16ToASCII(managed_name
));
186 AvatarMenu
* menu
= GetAvatarMenu();
187 ASSERT_EQ(1U, menu
->GetNumberOfItems());
189 const AvatarMenu::Item
& item1
= menu
->GetItemAt(0);
190 EXPECT_EQ(0U, item1
.menu_index
);
191 EXPECT_EQ(name1
, item1
.name
);
194 TEST_F(ProfileListChromeOSTest
, ShowAddProfileLink
) {
195 base::string16
name1(ASCIIToUTF16("p1.com"));
196 base::string16
name2(ASCIIToUTF16("p2.com"));
198 AddProfile(name1
, true);
199 AddProfile(name2
, false);
201 AvatarMenu
* menu
= GetAvatarMenu();
203 ASSERT_EQ(1U, menu
->GetNumberOfItems());
204 EXPECT_TRUE(menu
->ShouldShowAddNewProfileLink());
207 TEST_F(ProfileListChromeOSTest
, DontShowAddProfileLink
) {
208 base::string16
name1(ASCIIToUTF16("p1.com"));
209 base::string16
name2(ASCIIToUTF16("p2.com"));
211 AddProfile(name1
, true);
212 AddProfile(name2
, true);
214 AvatarMenu
* menu
= GetAvatarMenu();
216 ASSERT_EQ(2U, menu
->GetNumberOfItems());
217 EXPECT_FALSE(menu
->ShouldShowAddNewProfileLink());
220 TEST_F(ProfileListChromeOSTest
, ActiveItem
) {
221 base::string16
name1(ASCIIToUTF16("p1.com"));
222 base::string16
name2(ASCIIToUTF16("p2.com"));
224 AddProfile(name1
, true);
225 AddProfile(name2
, true);
227 // Initialize ProfileHelper, it will be accessed from GetActiveProfileIndex.
228 std::string email_string
= base::UTF16ToASCII(name1
) + "@example.com";
229 std::string hash
= email_string
+ kUserIdHashSuffix
;
231 g_browser_process
->platform_part()->profile_helper(), hash
);
233 AvatarMenu
* menu
= GetAvatarMenu();
235 ASSERT_EQ(2U, menu
->GetNumberOfItems());
236 // TODO(jeremy): Expand test to verify active profile index other than 0
238 ASSERT_EQ(0U, menu
->GetActiveProfileIndex());
241 TEST_F(ProfileListChromeOSTest
, ModifyingNameResortsCorrectly
) {
242 base::string16
name1(ASCIIToUTF16("Alpha"));
243 base::string16
name2(ASCIIToUTF16("Beta"));
244 base::string16
newname1(ASCIIToUTF16("Gamma"));
246 AddProfile(name1
, true);
247 AddProfile(name2
, true);
249 AvatarMenu
* menu
= GetAvatarMenu();
251 ASSERT_EQ(2U, menu
->GetNumberOfItems());
253 const AvatarMenu::Item
& item1
= menu
->GetItemAt(0);
254 EXPECT_EQ(0U, item1
.menu_index
);
255 EXPECT_EQ(name1
, item1
.name
);
257 const AvatarMenu::Item
& item2
= menu
->GetItemAt(1);
258 EXPECT_EQ(1U, item2
.menu_index
);
259 EXPECT_EQ(name2
, item2
.name
);
261 // Change name of the first profile, to trigger resorting of the profiles:
262 // now the first menu item should be named "beta", and the second be "gamma".
263 GetFakeUserManager()->SaveUserDisplayName(
264 base::UTF16ToASCII(name1
) + "@example.com", newname1
);
265 manager()->profile_info_cache()->SetNameOfProfileAtIndex(0, newname1
);
267 const AvatarMenu::Item
& item1next
= menu
->GetItemAt(0);
268 EXPECT_GT(change_count(), 1);
269 EXPECT_EQ(0U, item1next
.menu_index
);
270 EXPECT_EQ(name2
, item1next
.name
);
272 const AvatarMenu::Item
& item2next
= menu
->GetItemAt(1);
273 EXPECT_EQ(1U, item2next
.menu_index
);
274 EXPECT_EQ(newname1
, item2next
.name
);
277 TEST_F(ProfileListChromeOSTest
, ChangeOnNotify
) {
278 base::string16
name1(ASCIIToUTF16("p1.com"));
279 base::string16
name2(ASCIIToUTF16("p2.com"));
281 AddProfile(name1
, true);
282 AddProfile(name2
, true);
284 AvatarMenu
* menu
= GetAvatarMenu();
285 EXPECT_EQ(2U, menu
->GetNumberOfItems());
287 base::string16
name3(ASCIIToUTF16("p3.com"));
288 AddProfile(name3
, true);
290 // Four changes happened via the call to CreateTestingProfile: adding the
291 // profile to the cache, setting the user name, rebuilding the list of
292 // profiles after the name change, and changing the avatar.
293 // TODO(michaelpg): Determine why actual change number does not match comment.
294 EXPECT_GE(change_count(), 4);
295 ASSERT_EQ(3U, menu
->GetNumberOfItems());
297 const AvatarMenu::Item
& item1
= menu
->GetItemAt(0);
298 EXPECT_EQ(0U, item1
.menu_index
);
299 EXPECT_EQ(name1
, item1
.name
);
301 const AvatarMenu::Item
& item2
= menu
->GetItemAt(1);
302 EXPECT_EQ(1U, item2
.menu_index
);
303 EXPECT_EQ(name2
, item2
.name
);
305 const AvatarMenu::Item
& item3
= menu
->GetItemAt(2);
306 EXPECT_EQ(2U, item3
.menu_index
);
307 EXPECT_EQ(name3
, item3
.name
);
310 TEST_F(ProfileListChromeOSTest
, DontShowAvatarMenu
) {
311 // If in the new M-32 UX mode the icon gets shown, the menu will not.
312 base::string16
name1(ASCIIToUTF16("p1"));
313 base::string16
name2(ASCIIToUTF16("p2"));
315 AddProfile(name1
, true);
317 // Should only show avatar menu with multiple users.
318 EXPECT_FALSE(AvatarMenu::ShouldShowAvatarMenu());
320 AddProfile(name2
, false);
322 EXPECT_FALSE(AvatarMenu::ShouldShowAvatarMenu());
325 } // namespace chromeos