Home | History | Annotate | Download | only in profiles
      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 
     35 using base::ASCIIToUTF16;
     36 using base::UTF8ToUTF16;
     37 using content::BrowserThread;
     38 
     39 ProfileNameVerifierObserver::ProfileNameVerifierObserver(
     40     TestingProfileManager* testing_profile_manager)
     41     : testing_profile_manager_(testing_profile_manager) {
     42   DCHECK(testing_profile_manager_);
     43 }
     44 
     45 ProfileNameVerifierObserver::~ProfileNameVerifierObserver() {
     46 }
     47 
     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);
     54 }
     55 
     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);
     62 }
     63 
     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());
     68 }
     69 
     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);
     79 }
     80 
     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());
     86 }
     87 
     88 ProfileInfoCache* ProfileNameVerifierObserver::GetCache() {
     89   return testing_profile_manager_->profile_info_cache();
     90 }
     91 
     92 ProfileInfoCacheTest::ProfileInfoCacheTest()
     93     : testing_profile_manager_(TestingBrowserProcess::GetGlobal()),
     94       name_observer_(&testing_profile_manager_) {
     95 }
     96 
     97 ProfileInfoCacheTest::~ProfileInfoCacheTest() {
     98 }
     99 
    100 void ProfileInfoCacheTest::SetUp() {
    101   ASSERT_TRUE(testing_profile_manager_.SetUp());
    102   testing_profile_manager_.profile_info_cache()->AddObserver(&name_observer_);
    103 }
    104 
    105 void 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 
    111 ProfileInfoCache* ProfileInfoCacheTest::GetCache() {
    112   return testing_profile_manager_.profile_info_cache();
    113 }
    114 
    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);
    119 }
    120 
    121 void ProfileInfoCacheTest::ResetCache() {
    122   testing_profile_manager_.DeleteProfileInfoCache();
    123 }
    124 
    125 TEST_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 
    176 TEST_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 
    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());
    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 
    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());
    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 
    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());
    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 
    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));
    305 }
    306 
    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,
    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 
    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());
    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 
    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());
    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 
    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));
    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 
    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));
    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 
    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++) {
    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 
    505 TEST_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)
    540 TEST_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 
    594 TEST_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 
    640 TEST_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