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.
5 #include "chrome/browser/profiles/profile_list_desktop.h"
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"
26 using base::ASCIIToUTF16
;
30 class MockObserver
: public AvatarMenuObserver
{
32 MockObserver() : count_(0) {}
33 ~MockObserver() override
{}
35 void OnAvatarMenuChanged(AvatarMenu
* avatar_menu
) override
{ ++count_
; }
37 int change_count() const { return count_
; }
42 DISALLOW_COPY_AND_ASSIGN(MockObserver
);
45 class ProfileListDesktopTest
: public testing::Test
{
47 ProfileListDesktopTest()
48 : manager_(TestingBrowserProcess::GetGlobal()) {
51 void SetUp() override
{
52 ASSERT_TRUE(manager_
.SetUp());
53 #if defined(OS_CHROMEOS)
54 // AvatarMenu and multiple profiles works after user logged in.
55 manager_
.SetLoggedIn(true);
59 AvatarMenu
* GetAvatarMenu() {
60 // Reset the MockObserver.
61 mock_observer_
.reset(new MockObserver());
62 EXPECT_EQ(0, change_count());
65 avatar_menu_
.reset(new AvatarMenu(
66 manager()->profile_info_cache(),
69 avatar_menu_
->RebuildMenu();
70 EXPECT_EQ(0, change_count());
71 return avatar_menu_
.get();
74 TestingProfileManager
* manager() { return &manager_
; }
76 void AddOmittedProfile(std::string name
) {
77 ProfileInfoCache
* cache
= manager()->profile_info_cache();
78 cache
->AddProfileToCache(
79 cache
->GetUserDataDir().AppendASCII(name
), ASCIIToUTF16(name
),
80 std::string(), base::string16(), 0, "TEST_ID");
83 int change_count() const { return mock_observer_
->change_count(); }
86 TestingProfileManager manager_
;
87 scoped_ptr
<MockObserver
> mock_observer_
;
88 scoped_ptr
<AvatarMenu
> avatar_menu_
;
89 content::TestBrowserThreadBundle thread_bundle_
;
91 DISALLOW_COPY_AND_ASSIGN(ProfileListDesktopTest
);
94 TEST_F(ProfileListDesktopTest
, InitialCreation
) {
95 manager()->CreateTestingProfile("Test 1");
96 manager()->CreateTestingProfile("Test 2");
98 AvatarMenu
* model
= GetAvatarMenu();
99 EXPECT_EQ(0, change_count());
101 ASSERT_EQ(2U, model
->GetNumberOfItems());
103 const AvatarMenu::Item
& item1
= model
->GetItemAt(0);
104 EXPECT_EQ(0U, item1
.menu_index
);
105 EXPECT_EQ(ASCIIToUTF16("Test 1"), item1
.name
);
107 const AvatarMenu::Item
& item2
= model
->GetItemAt(1);
108 EXPECT_EQ(1U, item2
.menu_index
);
109 EXPECT_EQ(ASCIIToUTF16("Test 2"), item2
.name
);
112 TEST_F(ProfileListDesktopTest
, NoOmittedProfiles
) {
113 ProfileListDesktop
profile_list(manager()->profile_info_cache());
115 // Profiles are stored and listed alphabetically.
116 manager()->CreateTestingProfile("1 included");
117 manager()->CreateTestingProfile("2 included");
118 manager()->CreateTestingProfile("3 included");
119 manager()->CreateTestingProfile("4 included");
121 profile_list
.RebuildMenu();
122 ASSERT_EQ(4u, profile_list
.GetNumberOfItems());
124 const AvatarMenu::Item
& item1
= profile_list
.GetItemAt(0);
125 EXPECT_EQ(0u, item1
.menu_index
);
126 EXPECT_EQ(0u, item1
.profile_index
);
127 EXPECT_EQ(ASCIIToUTF16("1 included"), item1
.name
);
129 const AvatarMenu::Item
& item2
= profile_list
.GetItemAt(1);
130 EXPECT_EQ(1u, item2
.menu_index
);
131 EXPECT_EQ(1u, item2
.profile_index
);
132 EXPECT_EQ(ASCIIToUTF16("2 included"), item2
.name
);
134 const AvatarMenu::Item
& item3
= profile_list
.GetItemAt(2);
135 EXPECT_EQ(2u, item3
.menu_index
);
136 EXPECT_EQ(2u, item3
.profile_index
);
137 EXPECT_EQ(ASCIIToUTF16("3 included"), item3
.name
);
139 const AvatarMenu::Item
& item4
= profile_list
.GetItemAt(3);
140 EXPECT_EQ(3u, item4
.menu_index
);
141 EXPECT_EQ(3u, item4
.profile_index
);
142 EXPECT_EQ(ASCIIToUTF16("4 included"), item4
.name
);
144 EXPECT_EQ(0u, profile_list
.MenuIndexFromProfileIndex(0));
145 EXPECT_EQ(1u, profile_list
.MenuIndexFromProfileIndex(1));
146 EXPECT_EQ(2u, profile_list
.MenuIndexFromProfileIndex(2));
147 EXPECT_EQ(3u, profile_list
.MenuIndexFromProfileIndex(3));
150 TEST_F(ProfileListDesktopTest
, WithOmittedProfiles
) {
151 ProfileListDesktop
profile_list(manager()->profile_info_cache());
153 // Profiles are stored and listed alphabetically.
154 AddOmittedProfile("0 omitted");
155 manager()->CreateTestingProfile("1 included");
156 AddOmittedProfile("2 omitted");
157 manager()->CreateTestingProfile("3 included");
158 manager()->CreateTestingProfile("4 included");
159 AddOmittedProfile("5 omitted");
160 manager()->CreateTestingProfile("6 included");
161 AddOmittedProfile("7 omitted");
163 profile_list
.RebuildMenu();
164 ASSERT_EQ(4u, profile_list
.GetNumberOfItems());
166 const AvatarMenu::Item
& item1
= profile_list
.GetItemAt(0);
167 EXPECT_EQ(0u, item1
.menu_index
);
168 EXPECT_EQ(1u, item1
.profile_index
);
169 EXPECT_EQ(ASCIIToUTF16("1 included"), item1
.name
);
171 const AvatarMenu::Item
& item2
= profile_list
.GetItemAt(1);
172 EXPECT_EQ(1u, item2
.menu_index
);
173 EXPECT_EQ(3u, item2
.profile_index
);
174 EXPECT_EQ(ASCIIToUTF16("3 included"), item2
.name
);
176 const AvatarMenu::Item
& item3
= profile_list
.GetItemAt(2);
177 EXPECT_EQ(2u, item3
.menu_index
);
178 EXPECT_EQ(4u, item3
.profile_index
);
179 EXPECT_EQ(ASCIIToUTF16("4 included"), item3
.name
);
181 const AvatarMenu::Item
& item4
= profile_list
.GetItemAt(3);
182 EXPECT_EQ(3u, item4
.menu_index
);
183 EXPECT_EQ(6u, item4
.profile_index
);
184 EXPECT_EQ(ASCIIToUTF16("6 included"), item4
.name
);
186 EXPECT_EQ(0u, profile_list
.MenuIndexFromProfileIndex(1));
187 EXPECT_EQ(1u, profile_list
.MenuIndexFromProfileIndex(3));
188 EXPECT_EQ(2u, profile_list
.MenuIndexFromProfileIndex(4));
189 EXPECT_EQ(3u, profile_list
.MenuIndexFromProfileIndex(6));
192 TEST_F(ProfileListDesktopTest
, ActiveItem
) {
193 manager()->CreateTestingProfile("Test 1");
194 manager()->CreateTestingProfile("Test 2");
196 AvatarMenu
* model
= GetAvatarMenu();
197 ASSERT_EQ(2U, model
->GetNumberOfItems());
198 // TODO(jeremy): Expand test to verify active profile index other than 0
200 ASSERT_EQ(0U, model
->GetActiveProfileIndex());
203 TEST_F(ProfileListDesktopTest
, ModifyingNameResortsCorrectly
) {
204 std::string
name1("Alpha");
205 std::string
name2("Beta");
206 std::string
newname1("Gamma");
208 manager()->CreateTestingProfile(name1
);
209 manager()->CreateTestingProfile(name2
);
211 AvatarMenu
* model
= GetAvatarMenu();
212 EXPECT_EQ(0, change_count());
214 ASSERT_EQ(2U, model
->GetNumberOfItems());
216 const AvatarMenu::Item
& item1
= model
->GetItemAt(0);
217 EXPECT_EQ(0U, item1
.menu_index
);
218 EXPECT_EQ(ASCIIToUTF16(name1
), item1
.name
);
220 const AvatarMenu::Item
& item2
= model
->GetItemAt(1);
221 EXPECT_EQ(1U, item2
.menu_index
);
222 EXPECT_EQ(ASCIIToUTF16(name2
), item2
.name
);
224 // Change name of the first profile, to trigger resorting of the profiles:
225 // now the first model should be named "beta", and the second be "gamma".
226 manager()->profile_info_cache()->SetNameOfProfileAtIndex(0,
227 ASCIIToUTF16(newname1
));
228 const AvatarMenu::Item
& item1next
= model
->GetItemAt(0);
229 EXPECT_EQ(1, change_count());
230 EXPECT_EQ(0U, item1next
.menu_index
);
231 EXPECT_EQ(ASCIIToUTF16(name2
), item1next
.name
);
233 const AvatarMenu::Item
& item2next
= model
->GetItemAt(1);
234 EXPECT_EQ(1U, item2next
.menu_index
);
235 EXPECT_EQ(ASCIIToUTF16(newname1
), item2next
.name
);
238 TEST_F(ProfileListDesktopTest
, ChangeOnNotify
) {
239 manager()->CreateTestingProfile("Test 1");
240 manager()->CreateTestingProfile("Test 2");
242 AvatarMenu
* model
= GetAvatarMenu();
243 EXPECT_EQ(0, change_count());
244 EXPECT_EQ(2U, model
->GetNumberOfItems());
246 manager()->CreateTestingProfile("Test 3");
248 // Three changes happened via the call to CreateTestingProfile: adding the
249 // profile to the cache, setting the user name (which rebuilds the list of
250 // profiles after the name change) and changing the avatar.
251 // On Windows, an extra change happens to set the shortcut name for the
253 EXPECT_GE(3, change_count());
254 ASSERT_EQ(3U, model
->GetNumberOfItems());
256 const AvatarMenu::Item
& item1
= model
->GetItemAt(0);
257 EXPECT_EQ(0U, item1
.menu_index
);
258 EXPECT_EQ(ASCIIToUTF16("Test 1"), item1
.name
);
260 const AvatarMenu::Item
& item2
= model
->GetItemAt(1);
261 EXPECT_EQ(1U, item2
.menu_index
);
262 EXPECT_EQ(ASCIIToUTF16("Test 2"), item2
.name
);
264 const AvatarMenu::Item
& item3
= model
->GetItemAt(2);
265 EXPECT_EQ(2U, item3
.menu_index
);
266 EXPECT_EQ(ASCIIToUTF16("Test 3"), item3
.name
);
269 TEST_F(ProfileListDesktopTest
, ShowAvatarMenuInTrial
) {
270 // If multiprofile mode is not enabled, the trial will not be enabled, so it
272 if (!profiles::IsMultipleProfilesEnabled())
275 base::FieldTrialList
field_trial_list_(NULL
);
276 base::FieldTrialList::CreateFieldTrial("ShowProfileSwitcher", "AlwaysShow");
278 #if defined(OS_CHROMEOS)
279 EXPECT_FALSE(AvatarMenu::ShouldShowAvatarMenu());
281 EXPECT_TRUE(AvatarMenu::ShouldShowAvatarMenu());
285 TEST_F(ProfileListDesktopTest
, DontShowOldAvatarMenuForSingleProfile
) {
286 switches::DisableNewAvatarMenuForTesting(
287 base::CommandLine::ForCurrentProcess());
289 manager()->CreateTestingProfile("Test 1");
291 EXPECT_FALSE(AvatarMenu::ShouldShowAvatarMenu());
293 // If multiprofile mode is enabled, there are no other cases when we wouldn't
295 if (profiles::IsMultipleProfilesEnabled())
298 manager()->CreateTestingProfile("Test 2");
300 EXPECT_FALSE(AvatarMenu::ShouldShowAvatarMenu());
303 TEST_F(ProfileListDesktopTest
, AlwaysShowNewAvatarMenu
) {
304 // If multiprofile mode is not enabled then the menu is never shown.
305 if (!profiles::IsMultipleProfilesEnabled())
308 switches::EnableNewAvatarMenuForTesting(
309 base::CommandLine::ForCurrentProcess());
311 manager()->CreateTestingProfile("Test 1");
313 EXPECT_TRUE(AvatarMenu::ShouldShowAvatarMenu());
316 TEST_F(ProfileListDesktopTest
, ShowAvatarMenu
) {
317 // If multiprofile mode is not enabled then the menu is never shown.
318 if (!profiles::IsMultipleProfilesEnabled())
321 manager()->CreateTestingProfile("Test 1");
322 manager()->CreateTestingProfile("Test 2");
324 #if defined(OS_CHROMEOS)
325 EXPECT_FALSE(AvatarMenu::ShouldShowAvatarMenu());
327 EXPECT_TRUE(AvatarMenu::ShouldShowAvatarMenu());
331 TEST_F(ProfileListDesktopTest
, SyncState
) {
332 // If multiprofile mode is not enabled then the menu is never shown.
333 if (!profiles::IsMultipleProfilesEnabled())
336 manager()->CreateTestingProfile("Test 1");
338 // Add a managed user profile.
339 ProfileInfoCache
* cache
= manager()->profile_info_cache();
340 base::FilePath path
= cache
->GetUserDataDir().AppendASCII("p2");
341 cache
->AddProfileToCache(path
, ASCIIToUTF16("Test 2"), std::string(),
342 base::string16(), 0, "TEST_ID");
343 cache
->SetIsOmittedProfileAtIndex(cache
->GetIndexOfProfileWithPath(path
),
346 AvatarMenu
* model
= GetAvatarMenu();
347 model
->RebuildMenu();
348 EXPECT_EQ(2U, model
->GetNumberOfItems());
350 // Now check that the username of a supervised user shows the supervised
351 // user avatar label instead.
352 base::string16 supervised_user_label
=
353 l10n_util::GetStringUTF16(IDS_LEGACY_SUPERVISED_USER_AVATAR_LABEL
);
354 const AvatarMenu::Item
& item1
= model
->GetItemAt(0);
355 EXPECT_NE(item1
.username
, supervised_user_label
);
357 const AvatarMenu::Item
& item2
= model
->GetItemAt(1);
358 EXPECT_EQ(item2
.username
, supervised_user_label
);