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_info_cache_unittest.h" 6 7#include <vector> 8 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" 34 35using base::ASCIIToUTF16; 36using base::UTF8ToUTF16; 37using content::BrowserThread; 38 39ProfileNameVerifierObserver::ProfileNameVerifierObserver( 40 TestingProfileManager* testing_profile_manager) 41 : testing_profile_manager_(testing_profile_manager) { 42 DCHECK(testing_profile_manager_); 43} 44 45ProfileNameVerifierObserver::~ProfileNameVerifierObserver() { 46} 47 48void 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); 54} 55 56void 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); 62} 63 64void 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()); 68} 69 70void 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); 79} 80 81void 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()); 86} 87 88ProfileInfoCache* ProfileNameVerifierObserver::GetCache() { 89 return testing_profile_manager_->profile_info_cache(); 90} 91 92ProfileInfoCacheTest::ProfileInfoCacheTest() 93 : testing_profile_manager_(TestingBrowserProcess::GetGlobal()), 94 name_observer_(&testing_profile_manager_) { 95} 96 97ProfileInfoCacheTest::~ProfileInfoCacheTest() { 98} 99 100void ProfileInfoCacheTest::SetUp() { 101 ASSERT_TRUE(testing_profile_manager_.SetUp()); 102 testing_profile_manager_.profile_info_cache()->AddObserver(&name_observer_); 103} 104 105void ProfileInfoCacheTest::TearDown() { 106 // Drain the UI thread to make sure all tasks are completed. This prevents 107 // memory leaks. 108 base::RunLoop().RunUntilIdle(); 109} 110 111ProfileInfoCache* ProfileInfoCacheTest::GetCache() { 112 return testing_profile_manager_.profile_info_cache(); 113} 114 115base::FilePath ProfileInfoCacheTest::GetProfilePath( 116 const std::string& base_name) { 117 return testing_profile_manager_.profile_manager()->user_data_dir(). 118 AppendASCII(base_name); 119} 120 121void ProfileInfoCacheTest::ResetCache() { 122 testing_profile_manager_.DeleteProfileInfoCache(); 123} 124 125TEST_F(ProfileInfoCacheTest, AddProfiles) { 126 EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles()); 127 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( 136 i)).ToSkBitmap(); 137 std::string supervised_user_id = i == 3 ? "TEST_ID" : ""; 138 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); 144 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)); 156 } 157 158 // Reset the cache and test the it reloads correctly. 159 ResetCache(); 160 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)); 173 } 174} 175 176TEST_F(ProfileInfoCacheTest, DeleteProfile) { 177 EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles()); 178 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()); 183 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, 187 std::string()); 188 EXPECT_EQ(2u, GetCache()->GetNumberOfProfiles()); 189 190 GetCache()->DeleteProfileFromCache(path_1); 191 EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles()); 192 EXPECT_EQ(name_2, GetCache()->GetNameOfProfileAtIndex(0)); 193 194 GetCache()->DeleteProfileFromCache(path_2); 195 EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles()); 196} 197 198TEST_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()); 205 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)); 210 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)); 215 216 size_t new_icon_index = 3; 217 GetCache()->SetAvatarIconOfProfileAtIndex(1, new_icon_index); 218 // Not much to test. 219 GetCache()->GetAvatarIconOfProfileAtIndex(1); 220} 221 222TEST_F(ProfileInfoCacheTest, Sort) { 223 base::string16 name_a = ASCIIToUTF16("apple"); 224 GetCache()->AddProfileToCache( 225 GetProfilePath("path_a"), name_a, base::string16(), 0, std::string()); 226 227 base::string16 name_c = ASCIIToUTF16("cat"); 228 GetCache()->AddProfileToCache( 229 GetProfilePath("path_c"), name_c, base::string16(), 0, std::string()); 230 231 // Sanity check the initial order. 232 EXPECT_EQ(name_a, GetCache()->GetNameOfProfileAtIndex(0)); 233 EXPECT_EQ(name_c, GetCache()->GetNameOfProfileAtIndex(1)); 234 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()); 239 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)); 244 245 // Change the name of an existing profile. 246 name_a = UTF8ToUTF16("dog"); 247 GetCache()->SetNameOfProfileAtIndex(0, name_a); 248 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)); 253 254 // Delete a profile. 255 GetCache()->DeleteProfileFromCache(GetProfilePath("path_c")); 256 257 // Verify the new order. 258 EXPECT_EQ(name_b, GetCache()->GetNameOfProfileAtIndex(0)); 259 EXPECT_EQ(name_a, GetCache()->GetNameOfProfileAtIndex(1)); 260} 261 262TEST_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()); 269 270 EXPECT_FALSE(GetCache()->GetBackgroundStatusOfProfileAtIndex(0)); 271 EXPECT_FALSE(GetCache()->GetBackgroundStatusOfProfileAtIndex(1)); 272 273 GetCache()->SetBackgroundStatusOfProfileAtIndex(1, true); 274 275 EXPECT_FALSE(GetCache()->GetBackgroundStatusOfProfileAtIndex(0)); 276 EXPECT_TRUE(GetCache()->GetBackgroundStatusOfProfileAtIndex(1)); 277 278 GetCache()->SetBackgroundStatusOfProfileAtIndex(0, true); 279 280 EXPECT_TRUE(GetCache()->GetBackgroundStatusOfProfileAtIndex(0)); 281 EXPECT_TRUE(GetCache()->GetBackgroundStatusOfProfileAtIndex(1)); 282 283 GetCache()->SetBackgroundStatusOfProfileAtIndex(1, false); 284 285 EXPECT_TRUE(GetCache()->GetBackgroundStatusOfProfileAtIndex(0)); 286 EXPECT_FALSE(GetCache()->GetBackgroundStatusOfProfileAtIndex(1)); 287} 288 289TEST_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)); 305} 306 307TEST_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, 314 std::string()); 315 316 int index1 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_1")); 317 int index2 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_2")); 318 319 // Sanity check. 320 EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(index1).empty()); 321 EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(index2).empty()); 322 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")); 328 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)); 333 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); 338 339 index1 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_1")); 340 index2 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_2")); 341 342 EXPECT_EQ(custom_name, GetCache()->GetNameOfProfileAtIndex(index2)); 343 EXPECT_EQ(gaia_name, GetCache()->GetGAIANameOfProfileAtIndex(index2)); 344} 345 346TEST_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()); 356 357 // Sanity check. 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)); 362 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))); 372 373 // Set GAIA picture. 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))); 386 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))); 398 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))); 406 407 // Clearing the IsUsingGAIAPicture flag should result in the generic image 408 // being used again. 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))); 415} 416 417TEST_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()); 422 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))); 429 430 // Wait for the file to be written to disk then reset the cache. 431 save_observer.Wait(); 432 ResetCache(); 433 434 // Try to get the GAIA picture. This should return NULL until the read from 435 // disk is done. 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))); 443} 444 445TEST_F(ProfileInfoCacheTest, SetSupervisedUserId) { 446 GetCache()->AddProfileToCache( 447 GetProfilePath("test"), ASCIIToUTF16("Test"), 448 base::string16(), 0, std::string()); 449 EXPECT_FALSE(GetCache()->ProfileIsSupervisedAtIndex(0)); 450 451 GetCache()->SetSupervisedUserIdOfProfileAtIndex(0, "TEST_ID"); 452 EXPECT_TRUE(GetCache()->ProfileIsSupervisedAtIndex(0)); 453 EXPECT_EQ("TEST_ID", GetCache()->GetSupervisedUserIdOfProfileAtIndex(0)); 454 455 ResetCache(); 456 EXPECT_TRUE(GetCache()->ProfileIsSupervisedAtIndex(0)); 457 458 GetCache()->SetSupervisedUserIdOfProfileAtIndex(0, std::string()); 459 EXPECT_FALSE(GetCache()->ProfileIsSupervisedAtIndex(0)); 460 EXPECT_EQ("", GetCache()->GetSupervisedUserIdOfProfileAtIndex(0)); 461} 462 463TEST_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)); 468 469 GetCache()->AddProfileToCache( 470 GetProfilePath("path_1"), profile_name, base::string16(), 0, 471 std::string()); 472 473 // Set empty GAIA info. 474 GetCache()->SetGAIANameOfProfileAtIndex(0, base::string16()); 475 GetCache()->SetGAIAPictureOfProfileAtIndex(0, NULL); 476 GetCache()->SetIsUsingGAIAPictureOfProfileAtIndex(0, true); 477 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))); 482} 483 484TEST_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++) { 491 bool is_supervised = 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)); 497 } 498 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); 503} 504 505TEST_F(ProfileInfoCacheTest, AddStubProfile) { 506 EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles()); 507 508 // Add some profiles with and without a '.' in their paths. 509 const struct { 510 const char* profile_path; 511 const char* profile_name; 512 } kTestCases[] = { 513 { "path.test0", "name_0" }, 514 { "path_test1", "name_1" }, 515 { "path.test2", "name_2" }, 516 { "path_test3", "name_3" }, 517 }; 518 519 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) { 520 base::FilePath profile_path = GetProfilePath(kTestCases[i].profile_path); 521 base::string16 profile_name = ASCIIToUTF16(kTestCases[i].profile_name); 522 523 GetCache()->AddProfileToCache(profile_path, profile_name, base::string16(), 524 i, ""); 525 526 EXPECT_EQ(profile_path, GetCache()->GetPathOfProfileAtIndex(i)); 527 EXPECT_EQ(profile_name, GetCache()->GetNameOfProfileAtIndex(i)); 528 } 529 530 ASSERT_EQ(4U, GetCache()->GetNumberOfProfiles()); 531 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()); 536} 537 538// High res avatar downloading is only supported on desktop. 539#if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_CHROMEOS) 540TEST_F(ProfileInfoCacheTest, DownloadHighResAvatarTest) { 541 switches::EnableNewAvatarMenuForTesting(CommandLine::ForCurrentProcess()); 542 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()); 548 549 // We haven't downloaded any high-res avatars yet. 550 EXPECT_EQ(0U, GetCache()->cached_avatar_images_.size()); 551 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()); 556 557 EXPECT_FALSE(GetCache()->GetHighResAvatarOfProfileAtIndex(0)); 558 559 // Simulate downloading a high-res avatar. 560 const size_t kIconIndex = 0; 561 ProfileAvatarDownloader avatar_downloader( 562 kIconIndex, GetCache()->GetPathOfProfileAtIndex(0), GetCache()); 563 564 // Put a real bitmap into "bitmap". 2x2 bitmap of green 32 bit pixels. 565 SkBitmap bitmap; 566 bitmap.allocN32Pixels(2, 2); 567 bitmap.eraseColor(SK_ColorGREEN); 568 569 avatar_downloader.OnFetchComplete( 570 GURL("http://www.google.com/avatar.png"), &bitmap); 571 572 std::string file_name = 573 profiles::GetDefaultAvatarIconFileNameAtIndex(kIconIndex); 574 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)); 581 582 // Make sure everything has completed, and the file has been written to disk. 583 base::RunLoop().RunUntilIdle(); 584 585 // Clean up. 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)); 592} 593 594TEST_F(ProfileInfoCacheTest, MigrateLegacyProfileNamesWithNewAvatarMenu) { 595 switches::EnableNewAvatarMenuForTesting(CommandLine::ForCurrentProcess()); 596 EXPECT_EQ(0U, GetCache()->GetNumberOfProfiles()); 597 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()); 616 617 EXPECT_EQ(5U, GetCache()->GetNumberOfProfiles()); 618 619 620 ResetCache(); 621 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))); 628 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))); 637} 638#endif 639 640TEST_F(ProfileInfoCacheTest, 641 DontMigrateLegacyProfileNamesWithoutNewAvatarMenu) { 642 switches::DisableNewAvatarMenuForTesting(CommandLine::ForCurrentProcess()); 643 644 EXPECT_EQ(0U, GetCache()->GetNumberOfProfiles()); 645 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()); 663 664 ResetCache(); 665 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))); 675} 676 677