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_info_cache_unittest.h"
9 #include "base/command_line.h"
10 #include "base/files/file_util.h"
11 #include "base/prefs/testing_pref_service.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/time/time.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/prefs/pref_service_syncable.h"
18 #include "chrome/browser/profiles/profile_avatar_downloader.h"
19 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
20 #include "chrome/browser/profiles/profile_info_cache.h"
21 #include "chrome/browser/profiles/profile_manager.h"
22 #include "chrome/common/chrome_switches.h"
23 #include "chrome/test/base/testing_browser_process.h"
24 #include "components/signin/core/common/profile_management_switches.h"
25 #include "content/public/browser/notification_observer.h"
26 #include "content/public/browser/notification_registrar.h"
27 #include "content/public/browser/notification_service.h"
28 #include "content/public/test/test_browser_thread_bundle.h"
29 #include "content/public/test/test_utils.h"
30 #include "third_party/skia/include/core/SkBitmap.h"
31 #include "ui/base/resource/resource_bundle.h"
32 #include "ui/gfx/image/image.h"
33 #include "ui/gfx/image/image_unittest_util.h"
35 using base::ASCIIToUTF16
;
36 using base::UTF8ToUTF16
;
37 using content::BrowserThread
;
39 ProfileNameVerifierObserver::ProfileNameVerifierObserver(
40 TestingProfileManager
* testing_profile_manager
)
41 : testing_profile_manager_(testing_profile_manager
) {
42 DCHECK(testing_profile_manager_
);
45 ProfileNameVerifierObserver::~ProfileNameVerifierObserver() {
48 void ProfileNameVerifierObserver::OnProfileAdded(
49 const base::FilePath
& profile_path
) {
50 base::string16 profile_name
= GetCache()->GetNameOfProfileAtIndex(
51 GetCache()->GetIndexOfProfileWithPath(profile_path
));
52 EXPECT_TRUE(profile_names_
.find(profile_name
) == profile_names_
.end());
53 profile_names_
.insert(profile_name
);
56 void ProfileNameVerifierObserver::OnProfileWillBeRemoved(
57 const base::FilePath
& profile_path
) {
58 base::string16 profile_name
= GetCache()->GetNameOfProfileAtIndex(
59 GetCache()->GetIndexOfProfileWithPath(profile_path
));
60 EXPECT_TRUE(profile_names_
.find(profile_name
) != profile_names_
.end());
61 profile_names_
.erase(profile_name
);
64 void ProfileNameVerifierObserver::OnProfileWasRemoved(
65 const base::FilePath
& profile_path
,
66 const base::string16
& profile_name
) {
67 EXPECT_TRUE(profile_names_
.find(profile_name
) == profile_names_
.end());
70 void ProfileNameVerifierObserver::OnProfileNameChanged(
71 const base::FilePath
& profile_path
,
72 const base::string16
& old_profile_name
) {
73 base::string16 new_profile_name
= GetCache()->GetNameOfProfileAtIndex(
74 GetCache()->GetIndexOfProfileWithPath(profile_path
));
75 EXPECT_TRUE(profile_names_
.find(old_profile_name
) != profile_names_
.end());
76 EXPECT_TRUE(profile_names_
.find(new_profile_name
) == profile_names_
.end());
77 profile_names_
.erase(old_profile_name
);
78 profile_names_
.insert(new_profile_name
);
81 void ProfileNameVerifierObserver::OnProfileAvatarChanged(
82 const base::FilePath
& profile_path
) {
83 base::string16 profile_name
= GetCache()->GetNameOfProfileAtIndex(
84 GetCache()->GetIndexOfProfileWithPath(profile_path
));
85 EXPECT_TRUE(profile_names_
.find(profile_name
) != profile_names_
.end());
88 ProfileInfoCache
* ProfileNameVerifierObserver::GetCache() {
89 return testing_profile_manager_
->profile_info_cache();
92 ProfileInfoCacheTest::ProfileInfoCacheTest()
93 : testing_profile_manager_(TestingBrowserProcess::GetGlobal()),
94 name_observer_(&testing_profile_manager_
) {
97 ProfileInfoCacheTest::~ProfileInfoCacheTest() {
100 void ProfileInfoCacheTest::SetUp() {
101 ASSERT_TRUE(testing_profile_manager_
.SetUp());
102 testing_profile_manager_
.profile_info_cache()->AddObserver(&name_observer_
);
105 void ProfileInfoCacheTest::TearDown() {
106 // Drain the UI thread to make sure all tasks are completed. This prevents
108 base::RunLoop().RunUntilIdle();
111 ProfileInfoCache
* ProfileInfoCacheTest::GetCache() {
112 return testing_profile_manager_
.profile_info_cache();
115 base::FilePath
ProfileInfoCacheTest::GetProfilePath(
116 const std::string
& base_name
) {
117 return testing_profile_manager_
.profile_manager()->user_data_dir().
118 AppendASCII(base_name
);
121 void ProfileInfoCacheTest::ResetCache() {
122 testing_profile_manager_
.DeleteProfileInfoCache();
125 TEST_F(ProfileInfoCacheTest
, AddProfiles
) {
126 EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
128 ui::ResourceBundle
& rb
= ui::ResourceBundle::GetSharedInstance();
129 for (uint32 i
= 0; i
< 4; ++i
) {
130 base::FilePath profile_path
=
131 GetProfilePath(base::StringPrintf("path_%ud", i
));
132 base::string16 profile_name
=
133 ASCIIToUTF16(base::StringPrintf("name_%ud", i
));
134 const SkBitmap
* icon
= rb
.GetImageNamed(
135 profiles::GetDefaultAvatarIconResourceIDAtIndex(
137 std::string supervised_user_id
= i
== 3 ? "TEST_ID" : "";
139 GetCache()->AddProfileToCache(profile_path
, profile_name
, base::string16(),
140 i
, supervised_user_id
);
141 GetCache()->SetBackgroundStatusOfProfileAtIndex(i
, true);
142 base::string16 gaia_name
= ASCIIToUTF16(base::StringPrintf("gaia_%ud", i
));
143 GetCache()->SetGAIANameOfProfileAtIndex(i
, gaia_name
);
145 EXPECT_EQ(i
+ 1, GetCache()->GetNumberOfProfiles());
146 EXPECT_EQ(profile_name
, GetCache()->GetNameOfProfileAtIndex(i
));
147 EXPECT_EQ(profile_path
, GetCache()->GetPathOfProfileAtIndex(i
));
148 const SkBitmap
* actual_icon
=
149 GetCache()->GetAvatarIconOfProfileAtIndex(i
).ToSkBitmap();
150 EXPECT_EQ(icon
->width(), actual_icon
->width());
151 EXPECT_EQ(icon
->height(), actual_icon
->height());
152 EXPECT_EQ(i
== 3, GetCache()->ProfileIsSupervisedAtIndex(i
));
153 EXPECT_EQ(i
== 3, GetCache()->IsOmittedProfileAtIndex(i
));
154 EXPECT_EQ(supervised_user_id
,
155 GetCache()->GetSupervisedUserIdOfProfileAtIndex(i
));
158 // Reset the cache and test the it reloads correctly.
161 EXPECT_EQ(4u, GetCache()->GetNumberOfProfiles());
162 for (uint32 i
= 0; i
< 4; ++i
) {
163 base::FilePath profile_path
=
164 GetProfilePath(base::StringPrintf("path_%ud", i
));
165 EXPECT_EQ(i
, GetCache()->GetIndexOfProfileWithPath(profile_path
));
166 base::string16 profile_name
=
167 ASCIIToUTF16(base::StringPrintf("name_%ud", i
));
168 EXPECT_EQ(profile_name
, GetCache()->GetNameOfProfileAtIndex(i
));
169 EXPECT_EQ(i
, GetCache()->GetAvatarIconIndexOfProfileAtIndex(i
));
170 EXPECT_EQ(true, GetCache()->GetBackgroundStatusOfProfileAtIndex(i
));
171 base::string16 gaia_name
= ASCIIToUTF16(base::StringPrintf("gaia_%ud", i
));
172 EXPECT_EQ(gaia_name
, GetCache()->GetGAIANameOfProfileAtIndex(i
));
176 TEST_F(ProfileInfoCacheTest
, DeleteProfile
) {
177 EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
179 base::FilePath path_1
= GetProfilePath("path_1");
180 GetCache()->AddProfileToCache(path_1
, ASCIIToUTF16("name_1"),
181 base::string16(), 0, std::string());
182 EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles());
184 base::FilePath path_2
= GetProfilePath("path_2");
185 base::string16 name_2
= ASCIIToUTF16("name_2");
186 GetCache()->AddProfileToCache(path_2
, name_2
, base::string16(), 0,
188 EXPECT_EQ(2u, GetCache()->GetNumberOfProfiles());
190 GetCache()->DeleteProfileFromCache(path_1
);
191 EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles());
192 EXPECT_EQ(name_2
, GetCache()->GetNameOfProfileAtIndex(0));
194 GetCache()->DeleteProfileFromCache(path_2
);
195 EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
198 TEST_F(ProfileInfoCacheTest
, MutateProfile
) {
199 GetCache()->AddProfileToCache(
200 GetProfilePath("path_1"), ASCIIToUTF16("name_1"),
201 base::string16(), 0, std::string());
202 GetCache()->AddProfileToCache(
203 GetProfilePath("path_2"), ASCIIToUTF16("name_2"),
204 base::string16(), 0, std::string());
206 base::string16 new_name
= ASCIIToUTF16("new_name");
207 GetCache()->SetNameOfProfileAtIndex(1, new_name
);
208 EXPECT_EQ(new_name
, GetCache()->GetNameOfProfileAtIndex(1));
209 EXPECT_NE(new_name
, GetCache()->GetNameOfProfileAtIndex(0));
211 base::string16 new_user_name
= ASCIIToUTF16("user_name");
212 GetCache()->SetUserNameOfProfileAtIndex(1, new_user_name
);
213 EXPECT_EQ(new_user_name
, GetCache()->GetUserNameOfProfileAtIndex(1));
214 EXPECT_NE(new_user_name
, GetCache()->GetUserNameOfProfileAtIndex(0));
216 size_t new_icon_index
= 3;
217 GetCache()->SetAvatarIconOfProfileAtIndex(1, new_icon_index
);
219 GetCache()->GetAvatarIconOfProfileAtIndex(1);
222 TEST_F(ProfileInfoCacheTest
, Sort
) {
223 base::string16 name_a
= ASCIIToUTF16("apple");
224 GetCache()->AddProfileToCache(
225 GetProfilePath("path_a"), name_a
, base::string16(), 0, std::string());
227 base::string16 name_c
= ASCIIToUTF16("cat");
228 GetCache()->AddProfileToCache(
229 GetProfilePath("path_c"), name_c
, base::string16(), 0, std::string());
231 // Sanity check the initial order.
232 EXPECT_EQ(name_a
, GetCache()->GetNameOfProfileAtIndex(0));
233 EXPECT_EQ(name_c
, GetCache()->GetNameOfProfileAtIndex(1));
235 // Add a new profile (start with a capital to test case insensitive sorting.
236 base::string16 name_b
= ASCIIToUTF16("Banana");
237 GetCache()->AddProfileToCache(
238 GetProfilePath("path_b"), name_b
, base::string16(), 0, std::string());
240 // Verify the new order.
241 EXPECT_EQ(name_a
, GetCache()->GetNameOfProfileAtIndex(0));
242 EXPECT_EQ(name_b
, GetCache()->GetNameOfProfileAtIndex(1));
243 EXPECT_EQ(name_c
, GetCache()->GetNameOfProfileAtIndex(2));
245 // Change the name of an existing profile.
246 name_a
= UTF8ToUTF16("dog");
247 GetCache()->SetNameOfProfileAtIndex(0, name_a
);
249 // Verify the new order.
250 EXPECT_EQ(name_b
, GetCache()->GetNameOfProfileAtIndex(0));
251 EXPECT_EQ(name_c
, GetCache()->GetNameOfProfileAtIndex(1));
252 EXPECT_EQ(name_a
, GetCache()->GetNameOfProfileAtIndex(2));
255 GetCache()->DeleteProfileFromCache(GetProfilePath("path_c"));
257 // Verify the new order.
258 EXPECT_EQ(name_b
, GetCache()->GetNameOfProfileAtIndex(0));
259 EXPECT_EQ(name_a
, GetCache()->GetNameOfProfileAtIndex(1));
262 TEST_F(ProfileInfoCacheTest
, BackgroundModeStatus
) {
263 GetCache()->AddProfileToCache(
264 GetProfilePath("path_1"), ASCIIToUTF16("name_1"),
265 base::string16(), 0, std::string());
266 GetCache()->AddProfileToCache(
267 GetProfilePath("path_2"), ASCIIToUTF16("name_2"),
268 base::string16(), 0, std::string());
270 EXPECT_FALSE(GetCache()->GetBackgroundStatusOfProfileAtIndex(0));
271 EXPECT_FALSE(GetCache()->GetBackgroundStatusOfProfileAtIndex(1));
273 GetCache()->SetBackgroundStatusOfProfileAtIndex(1, true);
275 EXPECT_FALSE(GetCache()->GetBackgroundStatusOfProfileAtIndex(0));
276 EXPECT_TRUE(GetCache()->GetBackgroundStatusOfProfileAtIndex(1));
278 GetCache()->SetBackgroundStatusOfProfileAtIndex(0, true);
280 EXPECT_TRUE(GetCache()->GetBackgroundStatusOfProfileAtIndex(0));
281 EXPECT_TRUE(GetCache()->GetBackgroundStatusOfProfileAtIndex(1));
283 GetCache()->SetBackgroundStatusOfProfileAtIndex(1, false);
285 EXPECT_TRUE(GetCache()->GetBackgroundStatusOfProfileAtIndex(0));
286 EXPECT_FALSE(GetCache()->GetBackgroundStatusOfProfileAtIndex(1));
289 TEST_F(ProfileInfoCacheTest
, ProfileActiveTime
) {
290 GetCache()->AddProfileToCache(
291 GetProfilePath("path_1"), ASCIIToUTF16("name_1"),
292 base::string16(), 0, std::string());
293 EXPECT_EQ(base::Time(), GetCache()->GetProfileActiveTimeAtIndex(0));
294 // Before & After times are artificially shifted because just relying upon
295 // the system time can yield problems due to inaccuracies in the
296 // underlying storage system (which uses a double with only 52 bits of
297 // precision to store the 64-bit "time" number). http://crbug.com/346827
298 base::Time before
= base::Time::Now();
299 before
-= base::TimeDelta::FromSeconds(1);
300 GetCache()->SetProfileActiveTimeAtIndex(0);
301 base::Time after
= base::Time::Now();
302 after
+= base::TimeDelta::FromSeconds(1);
303 EXPECT_LE(before
, GetCache()->GetProfileActiveTimeAtIndex(0));
304 EXPECT_GE(after
, GetCache()->GetProfileActiveTimeAtIndex(0));
307 TEST_F(ProfileInfoCacheTest
, GAIAName
) {
308 GetCache()->AddProfileToCache(
309 GetProfilePath("path_1"), ASCIIToUTF16("Person 1"),
310 base::string16(), 0, std::string());
311 base::string16
profile_name(ASCIIToUTF16("Person 2"));
312 GetCache()->AddProfileToCache(
313 GetProfilePath("path_2"), profile_name
, base::string16(), 0,
316 int index1
= GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_1"));
317 int index2
= GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_2"));
320 EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(index1
).empty());
321 EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(index2
).empty());
323 // Set GAIA name. This re-sorts the cache.
324 base::string16
gaia_name(ASCIIToUTF16("Pat Smith"));
325 GetCache()->SetGAIANameOfProfileAtIndex(index2
, gaia_name
);
326 index1
= GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_1"));
327 index2
= GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_2"));
329 // Since there is a GAIA name, we use that as a display name.
330 EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(index1
).empty());
331 EXPECT_EQ(gaia_name
, GetCache()->GetGAIANameOfProfileAtIndex(index2
));
332 EXPECT_EQ(gaia_name
, GetCache()->GetNameOfProfileAtIndex(index2
));
334 // Don't use GAIA name as profile name. This re-sorts the cache.
335 base::string16
custom_name(ASCIIToUTF16("Custom name"));
336 GetCache()->SetNameOfProfileAtIndex(index2
, custom_name
);
337 GetCache()->SetProfileIsUsingDefaultNameAtIndex(index2
, false);
339 index1
= GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_1"));
340 index2
= GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_2"));
342 EXPECT_EQ(custom_name
, GetCache()->GetNameOfProfileAtIndex(index2
));
343 EXPECT_EQ(gaia_name
, GetCache()->GetGAIANameOfProfileAtIndex(index2
));
346 TEST_F(ProfileInfoCacheTest
, GAIAPicture
) {
347 const int kDefaultAvatarIndex
= 0;
348 const int kOtherAvatarIndex
= 1;
349 const int kGaiaPictureSize
= 256; // Standard size of a Gaia account picture.
350 GetCache()->AddProfileToCache(
351 GetProfilePath("path_1"), ASCIIToUTF16("name_1"),
352 base::string16(), kDefaultAvatarIndex
, std::string());
353 GetCache()->AddProfileToCache(
354 GetProfilePath("path_2"), ASCIIToUTF16("name_2"),
355 base::string16(), kDefaultAvatarIndex
, std::string());
358 EXPECT_EQ(NULL
, GetCache()->GetGAIAPictureOfProfileAtIndex(0));
359 EXPECT_EQ(NULL
, GetCache()->GetGAIAPictureOfProfileAtIndex(1));
360 EXPECT_FALSE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(0));
361 EXPECT_FALSE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(1));
363 // The profile icon should be the default one.
364 EXPECT_TRUE(GetCache()->ProfileIsUsingDefaultAvatarAtIndex(0));
365 EXPECT_TRUE(GetCache()->ProfileIsUsingDefaultAvatarAtIndex(1));
366 int default_avatar_id
=
367 profiles::GetDefaultAvatarIconResourceIDAtIndex(kDefaultAvatarIndex
);
368 const gfx::Image
& default_avatar_image(
369 ResourceBundle::GetSharedInstance().GetImageNamed(default_avatar_id
));
370 EXPECT_TRUE(gfx::test::IsEqual(
371 default_avatar_image
, GetCache()->GetAvatarIconOfProfileAtIndex(1)));
374 gfx::Image
gaia_image(gfx::test::CreateImage(
375 kGaiaPictureSize
, kGaiaPictureSize
));
376 GetCache()->SetGAIAPictureOfProfileAtIndex(1, &gaia_image
);
377 EXPECT_EQ(NULL
, GetCache()->GetGAIAPictureOfProfileAtIndex(0));
378 EXPECT_TRUE(gfx::test::IsEqual(
379 gaia_image
, *GetCache()->GetGAIAPictureOfProfileAtIndex(1)));
380 // Since we're still using the default avatar, the GAIA image should be
381 // preferred over the generic avatar image.
382 EXPECT_TRUE(GetCache()->ProfileIsUsingDefaultAvatarAtIndex(1));
383 EXPECT_TRUE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(1));
384 EXPECT_TRUE(gfx::test::IsEqual(
385 gaia_image
, GetCache()->GetAvatarIconOfProfileAtIndex(1)));
387 // Set a non-default avatar. This should be preferred over the GAIA image.
388 GetCache()->SetAvatarIconOfProfileAtIndex(1, kOtherAvatarIndex
);
389 GetCache()->SetProfileIsUsingDefaultAvatarAtIndex(1, false);
390 EXPECT_FALSE(GetCache()->ProfileIsUsingDefaultAvatarAtIndex(1));
391 EXPECT_FALSE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(1));
392 int other_avatar_id
=
393 profiles::GetDefaultAvatarIconResourceIDAtIndex(kOtherAvatarIndex
);
394 const gfx::Image
& other_avatar_image(
395 ResourceBundle::GetSharedInstance().GetImageNamed(other_avatar_id
));
396 EXPECT_TRUE(gfx::test::IsEqual(
397 other_avatar_image
, GetCache()->GetAvatarIconOfProfileAtIndex(1)));
399 // Explicitly setting the GAIA picture should make it preferred again.
400 GetCache()->SetIsUsingGAIAPictureOfProfileAtIndex(1, true);
401 EXPECT_TRUE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(1));
402 EXPECT_TRUE(gfx::test::IsEqual(
403 gaia_image
, *GetCache()->GetGAIAPictureOfProfileAtIndex(1)));
404 EXPECT_TRUE(gfx::test::IsEqual(
405 gaia_image
, GetCache()->GetAvatarIconOfProfileAtIndex(1)));
407 // Clearing the IsUsingGAIAPicture flag should result in the generic image
409 GetCache()->SetIsUsingGAIAPictureOfProfileAtIndex(1, false);
410 EXPECT_FALSE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(1));
411 EXPECT_TRUE(gfx::test::IsEqual(
412 gaia_image
, *GetCache()->GetGAIAPictureOfProfileAtIndex(1)));
413 EXPECT_TRUE(gfx::test::IsEqual(
414 other_avatar_image
, GetCache()->GetAvatarIconOfProfileAtIndex(1)));
417 TEST_F(ProfileInfoCacheTest
, PersistGAIAPicture
) {
418 GetCache()->AddProfileToCache(
419 GetProfilePath("path_1"), ASCIIToUTF16("name_1"),
420 base::string16(), 0, std::string());
421 gfx::Image
gaia_image(gfx::test::CreateImage());
423 content::WindowedNotificationObserver
save_observer(
424 chrome::NOTIFICATION_PROFILE_CACHE_PICTURE_SAVED
,
425 content::NotificationService::AllSources());
426 GetCache()->SetGAIAPictureOfProfileAtIndex(0, &gaia_image
);
427 EXPECT_TRUE(gfx::test::IsEqual(
428 gaia_image
, *GetCache()->GetGAIAPictureOfProfileAtIndex(0)));
430 // Wait for the file to be written to disk then reset the cache.
431 save_observer
.Wait();
434 // Try to get the GAIA picture. This should return NULL until the read from
436 content::WindowedNotificationObserver
read_observer(
437 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED
,
438 content::NotificationService::AllSources());
439 EXPECT_EQ(NULL
, GetCache()->GetGAIAPictureOfProfileAtIndex(0));
440 read_observer
.Wait();
441 EXPECT_TRUE(gfx::test::IsEqual(
442 gaia_image
, *GetCache()->GetGAIAPictureOfProfileAtIndex(0)));
445 TEST_F(ProfileInfoCacheTest
, SetSupervisedUserId
) {
446 GetCache()->AddProfileToCache(
447 GetProfilePath("test"), ASCIIToUTF16("Test"),
448 base::string16(), 0, std::string());
449 EXPECT_FALSE(GetCache()->ProfileIsSupervisedAtIndex(0));
451 GetCache()->SetSupervisedUserIdOfProfileAtIndex(0, "TEST_ID");
452 EXPECT_TRUE(GetCache()->ProfileIsSupervisedAtIndex(0));
453 EXPECT_EQ("TEST_ID", GetCache()->GetSupervisedUserIdOfProfileAtIndex(0));
456 EXPECT_TRUE(GetCache()->ProfileIsSupervisedAtIndex(0));
458 GetCache()->SetSupervisedUserIdOfProfileAtIndex(0, std::string());
459 EXPECT_FALSE(GetCache()->ProfileIsSupervisedAtIndex(0));
460 EXPECT_EQ("", GetCache()->GetSupervisedUserIdOfProfileAtIndex(0));
463 TEST_F(ProfileInfoCacheTest
, EmptyGAIAInfo
) {
464 base::string16 profile_name
= ASCIIToUTF16("name_1");
465 int id
= profiles::GetDefaultAvatarIconResourceIDAtIndex(0);
466 const gfx::Image
& profile_image(
467 ResourceBundle::GetSharedInstance().GetImageNamed(id
));
469 GetCache()->AddProfileToCache(
470 GetProfilePath("path_1"), profile_name
, base::string16(), 0,
473 // Set empty GAIA info.
474 GetCache()->SetGAIANameOfProfileAtIndex(0, base::string16());
475 GetCache()->SetGAIAPictureOfProfileAtIndex(0, NULL
);
476 GetCache()->SetIsUsingGAIAPictureOfProfileAtIndex(0, true);
478 // Verify that the profile name and picture are not empty.
479 EXPECT_EQ(profile_name
, GetCache()->GetNameOfProfileAtIndex(0));
480 EXPECT_TRUE(gfx::test::IsEqual(
481 profile_image
, GetCache()->GetAvatarIconOfProfileAtIndex(0)));
484 TEST_F(ProfileInfoCacheTest
, CreateSupervisedTestingProfile
) {
485 testing_profile_manager_
.CreateTestingProfile("default");
486 base::string16 supervised_user_name
= ASCIIToUTF16("Supervised User");
487 testing_profile_manager_
.CreateTestingProfile(
488 "test1", scoped_ptr
<PrefServiceSyncable
>(),
489 supervised_user_name
, 0, "TEST_ID", TestingProfile::TestingFactories());
490 for (size_t i
= 0; i
< GetCache()->GetNumberOfProfiles(); i
++) {
492 GetCache()->GetNameOfProfileAtIndex(i
) == supervised_user_name
;
493 EXPECT_EQ(is_supervised
, GetCache()->ProfileIsSupervisedAtIndex(i
));
494 std::string supervised_user_id
= is_supervised
? "TEST_ID" : "";
495 EXPECT_EQ(supervised_user_id
,
496 GetCache()->GetSupervisedUserIdOfProfileAtIndex(i
));
499 // Supervised profiles have a custom theme, which needs to be deleted on the
500 // FILE thread. Reset the profile manager now so everything is deleted while
501 // we still have a FILE thread.
502 TestingBrowserProcess::GetGlobal()->SetProfileManager(NULL
);
505 TEST_F(ProfileInfoCacheTest
, AddStubProfile
) {
506 EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
508 // Add some profiles with and without a '.' in their paths.
510 const char* profile_path
;
511 const char* profile_name
;
513 { "path.test0", "name_0" },
514 { "path_test1", "name_1" },
515 { "path.test2", "name_2" },
516 { "path_test3", "name_3" },
519 for (size_t i
= 0; i
< arraysize(kTestCases
); ++i
) {
520 base::FilePath profile_path
= GetProfilePath(kTestCases
[i
].profile_path
);
521 base::string16 profile_name
= ASCIIToUTF16(kTestCases
[i
].profile_name
);
523 GetCache()->AddProfileToCache(profile_path
, profile_name
, base::string16(),
526 EXPECT_EQ(profile_path
, GetCache()->GetPathOfProfileAtIndex(i
));
527 EXPECT_EQ(profile_name
, GetCache()->GetNameOfProfileAtIndex(i
));
530 ASSERT_EQ(4U, GetCache()->GetNumberOfProfiles());
532 // Check that the profiles can be extracted from the local state.
533 std::vector
<base::string16
> names
= ProfileInfoCache::GetProfileNames();
534 for (size_t i
= 0; i
< 4; i
++)
535 ASSERT_FALSE(names
[i
].empty());
538 // High res avatar downloading is only supported on desktop.
539 #if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_CHROMEOS)
540 TEST_F(ProfileInfoCacheTest
, DownloadHighResAvatarTest
) {
541 switches::EnableNewAvatarMenuForTesting(CommandLine::ForCurrentProcess());
543 EXPECT_EQ(0U, GetCache()->GetNumberOfProfiles());
544 base::FilePath path_1
= GetProfilePath("path_1");
545 GetCache()->AddProfileToCache(path_1
, ASCIIToUTF16("name_1"),
546 base::string16(), 0, std::string());
547 EXPECT_EQ(1U, GetCache()->GetNumberOfProfiles());
549 // We haven't downloaded any high-res avatars yet.
550 EXPECT_EQ(0U, GetCache()->cached_avatar_images_
.size());
552 // After adding a new profile, the download of high-res avatar will be
553 // triggered if the flag kNewAvatarMenu has been set. But the downloader
554 // won't ever call OnFetchComplete in the test.
555 EXPECT_EQ(1U, GetCache()->avatar_images_downloads_in_progress_
.size());
557 EXPECT_FALSE(GetCache()->GetHighResAvatarOfProfileAtIndex(0));
559 // Simulate downloading a high-res avatar.
560 const size_t kIconIndex
= 0;
561 ProfileAvatarDownloader
avatar_downloader(
562 kIconIndex
, GetCache()->GetPathOfProfileAtIndex(0), GetCache());
564 // Put a real bitmap into "bitmap". 2x2 bitmap of green 32 bit pixels.
566 bitmap
.allocN32Pixels(2, 2);
567 bitmap
.eraseColor(SK_ColorGREEN
);
569 avatar_downloader
.OnFetchComplete(
570 GURL("http://www.google.com/avatar.png"), &bitmap
);
572 std::string file_name
=
573 profiles::GetDefaultAvatarIconFileNameAtIndex(kIconIndex
);
575 // The file should have been cached and saved.
576 EXPECT_EQ(1U, GetCache()->avatar_images_downloads_in_progress_
.size());
577 EXPECT_EQ(1U, GetCache()->cached_avatar_images_
.size());
578 EXPECT_TRUE(GetCache()->GetHighResAvatarOfProfileAtIndex(0));
579 EXPECT_EQ(GetCache()->cached_avatar_images_
[file_name
],
580 GetCache()->GetHighResAvatarOfProfileAtIndex(0));
582 // Make sure everything has completed, and the file has been written to disk.
583 base::RunLoop().RunUntilIdle();
586 base::FilePath icon_path
=
587 profiles::GetPathOfHighResAvatarAtIndex(kIconIndex
);
588 EXPECT_NE(std::string::npos
, icon_path
.MaybeAsASCII().find(file_name
));
589 EXPECT_TRUE(base::PathExists(icon_path
));
590 EXPECT_TRUE(base::DeleteFile(icon_path
, true));
591 EXPECT_FALSE(base::PathExists(icon_path
));
594 TEST_F(ProfileInfoCacheTest
, MigrateLegacyProfileNamesWithNewAvatarMenu
) {
595 switches::EnableNewAvatarMenuForTesting(CommandLine::ForCurrentProcess());
596 EXPECT_EQ(0U, GetCache()->GetNumberOfProfiles());
598 base::FilePath path_1
= GetProfilePath("path_1");
599 GetCache()->AddProfileToCache(path_1
, ASCIIToUTF16("Default Profile"),
600 base::string16(), 0, std::string());
601 base::FilePath path_2
= GetProfilePath("path_2");
602 GetCache()->AddProfileToCache(path_2
, ASCIIToUTF16("First user"),
603 base::string16(), 1, std::string());
604 base::string16 name_3
= ASCIIToUTF16("Lemonade");
605 base::FilePath path_3
= GetProfilePath("path_3");
606 GetCache()->AddProfileToCache(path_3
, name_3
,
607 base::string16(), 2, std::string());
608 base::string16 name_4
= ASCIIToUTF16("Batman");
609 base::FilePath path_4
= GetProfilePath("path_4");
610 GetCache()->AddProfileToCache(path_4
, name_4
,
611 base::string16(), 3, std::string());
612 base::string16 name_5
= ASCIIToUTF16("Person 2");
613 base::FilePath path_5
= GetProfilePath("path_5");
614 GetCache()->AddProfileToCache(path_5
, name_5
,
615 base::string16(), 2, std::string());
617 EXPECT_EQ(5U, GetCache()->GetNumberOfProfiles());
622 // Legacy profile names like "Default Profile" and "First user" should be
623 // migrated to "Person %n" type names.
624 EXPECT_EQ(ASCIIToUTF16("Person 1"), GetCache()->GetNameOfProfileAtIndex(
625 GetCache()->GetIndexOfProfileWithPath(path_1
)));
626 EXPECT_EQ(ASCIIToUTF16("Person 3"), GetCache()->GetNameOfProfileAtIndex(
627 GetCache()->GetIndexOfProfileWithPath(path_2
)));
629 // Other profile names should not be migrated even if they're the old
630 // default cartoon profile names.
631 EXPECT_EQ(name_3
, GetCache()->GetNameOfProfileAtIndex(
632 GetCache()->GetIndexOfProfileWithPath(path_3
)));
633 EXPECT_EQ(name_4
, GetCache()->GetNameOfProfileAtIndex(
634 GetCache()->GetIndexOfProfileWithPath(path_4
)));
635 EXPECT_EQ(name_5
, GetCache()->GetNameOfProfileAtIndex(
636 GetCache()->GetIndexOfProfileWithPath(path_5
)));
640 TEST_F(ProfileInfoCacheTest
,
641 DontMigrateLegacyProfileNamesWithoutNewAvatarMenu
) {
642 switches::DisableNewAvatarMenuForTesting(CommandLine::ForCurrentProcess());
644 EXPECT_EQ(0U, GetCache()->GetNumberOfProfiles());
646 base::string16 name_1
= ASCIIToUTF16("Default Profile");
647 base::FilePath path_1
= GetProfilePath("path_1");
648 GetCache()->AddProfileToCache(path_1
, name_1
,
649 base::string16(), 0, std::string());
650 base::string16 name_2
= ASCIIToUTF16("First user");
651 base::FilePath path_2
= GetProfilePath("path_2");
652 GetCache()->AddProfileToCache(path_2
, name_2
,
653 base::string16(), 1, std::string());
654 base::string16 name_3
= ASCIIToUTF16("Lemonade");
655 base::FilePath path_3
= GetProfilePath("path_3");
656 GetCache()->AddProfileToCache(path_3
, name_3
,
657 base::string16(), 2, std::string());
658 base::string16 name_4
= ASCIIToUTF16("Batman");
659 base::FilePath path_4
= GetProfilePath("path_4");
660 GetCache()->AddProfileToCache(path_4
, name_4
,
661 base::string16(), 3, std::string());
662 EXPECT_EQ(4U, GetCache()->GetNumberOfProfiles());
666 // Profile names should have been preserved.
667 EXPECT_EQ(name_1
, GetCache()->GetNameOfProfileAtIndex(
668 GetCache()->GetIndexOfProfileWithPath(path_1
)));
669 EXPECT_EQ(name_2
, GetCache()->GetNameOfProfileAtIndex(
670 GetCache()->GetIndexOfProfileWithPath(path_2
)));
671 EXPECT_EQ(name_3
, GetCache()->GetNameOfProfileAtIndex(
672 GetCache()->GetIndexOfProfileWithPath(path_3
)));
673 EXPECT_EQ(name_4
, GetCache()->GetNameOfProfileAtIndex(
674 GetCache()->GetIndexOfProfileWithPath(path_4
)));