92638ae3e89c7c0cb20cda2c61ff0284c206453c
[platform/framework/web/crosswalk.git] / src / chrome / browser / profiles / profile_info_cache_unittest.cc
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/file_util.h"
10 #include "base/prefs/testing_pref_service.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/time/time.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/prefs/pref_service_syncable.h"
17 #include "chrome/browser/profiles/profile_avatar_downloader.h"
18 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
19 #include "chrome/browser/profiles/profile_info_cache.h"
20 #include "chrome/browser/profiles/profile_manager.h"
21 #include "chrome/test/base/testing_browser_process.h"
22 #include "content/public/browser/notification_observer.h"
23 #include "content/public/browser/notification_registrar.h"
24 #include "content/public/browser/notification_service.h"
25 #include "content/public/test/test_browser_thread_bundle.h"
26 #include "content/public/test/test_utils.h"
27 #include "third_party/skia/include/core/SkBitmap.h"
28 #include "ui/base/resource/resource_bundle.h"
29 #include "ui/gfx/image/image.h"
30 #include "ui/gfx/image/image_unittest_util.h"
31
32 using base::ASCIIToUTF16;
33 using base::UTF8ToUTF16;
34 using content::BrowserThread;
35
36 ProfileNameVerifierObserver::ProfileNameVerifierObserver(
37     TestingProfileManager* testing_profile_manager)
38     : testing_profile_manager_(testing_profile_manager) {
39   DCHECK(testing_profile_manager_);
40 }
41
42 ProfileNameVerifierObserver::~ProfileNameVerifierObserver() {
43 }
44
45 void ProfileNameVerifierObserver::OnProfileAdded(
46     const base::FilePath& profile_path) {
47   base::string16 profile_name = GetCache()->GetNameOfProfileAtIndex(
48       GetCache()->GetIndexOfProfileWithPath(profile_path));
49   EXPECT_TRUE(profile_names_.find(profile_name) == profile_names_.end());
50   profile_names_.insert(profile_name);
51 }
52
53 void ProfileNameVerifierObserver::OnProfileWillBeRemoved(
54     const base::FilePath& profile_path) {
55   base::string16 profile_name = GetCache()->GetNameOfProfileAtIndex(
56       GetCache()->GetIndexOfProfileWithPath(profile_path));
57   EXPECT_TRUE(profile_names_.find(profile_name) != profile_names_.end());
58   profile_names_.erase(profile_name);
59 }
60
61 void ProfileNameVerifierObserver::OnProfileWasRemoved(
62     const base::FilePath& profile_path,
63     const base::string16& profile_name) {
64   EXPECT_TRUE(profile_names_.find(profile_name) == profile_names_.end());
65 }
66
67 void ProfileNameVerifierObserver::OnProfileNameChanged(
68     const base::FilePath& profile_path,
69     const base::string16& old_profile_name) {
70   base::string16 new_profile_name = GetCache()->GetNameOfProfileAtIndex(
71       GetCache()->GetIndexOfProfileWithPath(profile_path));
72   EXPECT_TRUE(profile_names_.find(old_profile_name) != profile_names_.end());
73   EXPECT_TRUE(profile_names_.find(new_profile_name) == profile_names_.end());
74   profile_names_.erase(old_profile_name);
75   profile_names_.insert(new_profile_name);
76 }
77
78 void ProfileNameVerifierObserver::OnProfileAvatarChanged(
79     const base::FilePath& profile_path) {
80   base::string16 profile_name = GetCache()->GetNameOfProfileAtIndex(
81       GetCache()->GetIndexOfProfileWithPath(profile_path));
82   EXPECT_TRUE(profile_names_.find(profile_name) != profile_names_.end());
83 }
84
85 ProfileInfoCache* ProfileNameVerifierObserver::GetCache() {
86   return testing_profile_manager_->profile_info_cache();
87 }
88
89 ProfileInfoCacheTest::ProfileInfoCacheTest()
90     : testing_profile_manager_(TestingBrowserProcess::GetGlobal()),
91       name_observer_(&testing_profile_manager_) {
92 }
93
94 ProfileInfoCacheTest::~ProfileInfoCacheTest() {
95 }
96
97 void ProfileInfoCacheTest::SetUp() {
98   ASSERT_TRUE(testing_profile_manager_.SetUp());
99   testing_profile_manager_.profile_info_cache()->AddObserver(&name_observer_);
100 }
101
102 void ProfileInfoCacheTest::TearDown() {
103   // Drain the UI thread to make sure all tasks are completed. This prevents
104   // memory leaks.
105   base::RunLoop().RunUntilIdle();
106 }
107
108 ProfileInfoCache* ProfileInfoCacheTest::GetCache() {
109   return testing_profile_manager_.profile_info_cache();
110 }
111
112 base::FilePath ProfileInfoCacheTest::GetProfilePath(
113     const std::string& base_name) {
114   return testing_profile_manager_.profile_manager()->user_data_dir().
115       AppendASCII(base_name);
116 }
117
118 void ProfileInfoCacheTest::ResetCache() {
119   testing_profile_manager_.DeleteProfileInfoCache();
120 }
121
122 TEST_F(ProfileInfoCacheTest, AddProfiles) {
123   EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
124
125   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
126   for (uint32 i = 0; i < 4; ++i) {
127     base::FilePath profile_path =
128         GetProfilePath(base::StringPrintf("path_%ud", i));
129     base::string16 profile_name =
130         ASCIIToUTF16(base::StringPrintf("name_%ud", i));
131     const SkBitmap* icon = rb.GetImageNamed(
132         profiles::GetDefaultAvatarIconResourceIDAtIndex(
133             i)).ToSkBitmap();
134     std::string supervised_user_id = i == 3 ? "TEST_ID" : "";
135
136     GetCache()->AddProfileToCache(profile_path, profile_name, base::string16(),
137                                   i, supervised_user_id);
138     GetCache()->SetBackgroundStatusOfProfileAtIndex(i, true);
139     base::string16 gaia_name = ASCIIToUTF16(base::StringPrintf("gaia_%ud", i));
140     GetCache()->SetGAIANameOfProfileAtIndex(i, gaia_name);
141
142     EXPECT_EQ(i + 1, GetCache()->GetNumberOfProfiles());
143     EXPECT_EQ(profile_name, GetCache()->GetNameOfProfileAtIndex(i));
144     EXPECT_EQ(profile_path, GetCache()->GetPathOfProfileAtIndex(i));
145     const SkBitmap* actual_icon =
146         GetCache()->GetAvatarIconOfProfileAtIndex(i).ToSkBitmap();
147     EXPECT_EQ(icon->width(), actual_icon->width());
148     EXPECT_EQ(icon->height(), actual_icon->height());
149     EXPECT_EQ(i == 3, GetCache()->ProfileIsSupervisedAtIndex(i));
150     EXPECT_EQ(i == 3, GetCache()->IsOmittedProfileAtIndex(i));
151     EXPECT_EQ(supervised_user_id,
152               GetCache()->GetSupervisedUserIdOfProfileAtIndex(i));
153   }
154
155   // Reset the cache and test the it reloads correctly.
156   ResetCache();
157
158   EXPECT_EQ(4u, GetCache()->GetNumberOfProfiles());
159   for (uint32 i = 0; i < 4; ++i) {
160     base::FilePath profile_path =
161           GetProfilePath(base::StringPrintf("path_%ud", i));
162     EXPECT_EQ(i, GetCache()->GetIndexOfProfileWithPath(profile_path));
163     base::string16 profile_name =
164         ASCIIToUTF16(base::StringPrintf("name_%ud", i));
165     EXPECT_EQ(profile_name, GetCache()->GetNameOfProfileAtIndex(i));
166     EXPECT_EQ(i, GetCache()->GetAvatarIconIndexOfProfileAtIndex(i));
167     EXPECT_EQ(true, GetCache()->GetBackgroundStatusOfProfileAtIndex(i));
168     base::string16 gaia_name = ASCIIToUTF16(base::StringPrintf("gaia_%ud", i));
169     EXPECT_EQ(gaia_name, GetCache()->GetGAIANameOfProfileAtIndex(i));
170   }
171 }
172
173 TEST_F(ProfileInfoCacheTest, DeleteProfile) {
174   EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
175
176   base::FilePath path_1 = GetProfilePath("path_1");
177   GetCache()->AddProfileToCache(path_1, ASCIIToUTF16("name_1"),
178                                 base::string16(), 0, std::string());
179   EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles());
180
181   base::FilePath path_2 = GetProfilePath("path_2");
182   base::string16 name_2 = ASCIIToUTF16("name_2");
183   GetCache()->AddProfileToCache(path_2, name_2, base::string16(), 0,
184                                 std::string());
185   EXPECT_EQ(2u, GetCache()->GetNumberOfProfiles());
186
187   GetCache()->DeleteProfileFromCache(path_1);
188   EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles());
189   EXPECT_EQ(name_2, GetCache()->GetNameOfProfileAtIndex(0));
190
191   GetCache()->DeleteProfileFromCache(path_2);
192   EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
193 }
194
195 TEST_F(ProfileInfoCacheTest, MutateProfile) {
196   GetCache()->AddProfileToCache(
197       GetProfilePath("path_1"), ASCIIToUTF16("name_1"),
198       base::string16(), 0, std::string());
199   GetCache()->AddProfileToCache(
200       GetProfilePath("path_2"), ASCIIToUTF16("name_2"),
201       base::string16(), 0, std::string());
202
203   base::string16 new_name = ASCIIToUTF16("new_name");
204   GetCache()->SetNameOfProfileAtIndex(1, new_name);
205   EXPECT_EQ(new_name, GetCache()->GetNameOfProfileAtIndex(1));
206   EXPECT_NE(new_name, GetCache()->GetNameOfProfileAtIndex(0));
207
208   base::string16 new_user_name = ASCIIToUTF16("user_name");
209   GetCache()->SetUserNameOfProfileAtIndex(1, new_user_name);
210   EXPECT_EQ(new_user_name, GetCache()->GetUserNameOfProfileAtIndex(1));
211   EXPECT_NE(new_user_name, GetCache()->GetUserNameOfProfileAtIndex(0));
212
213   size_t new_icon_index = 3;
214   GetCache()->SetAvatarIconOfProfileAtIndex(1, new_icon_index);
215   // Not much to test.
216   GetCache()->GetAvatarIconOfProfileAtIndex(1);
217 }
218
219 TEST_F(ProfileInfoCacheTest, Sort) {
220   base::string16 name_a = ASCIIToUTF16("apple");
221   GetCache()->AddProfileToCache(
222       GetProfilePath("path_a"), name_a, base::string16(), 0, std::string());
223
224   base::string16 name_c = ASCIIToUTF16("cat");
225   GetCache()->AddProfileToCache(
226       GetProfilePath("path_c"), name_c, base::string16(), 0, std::string());
227
228   // Sanity check the initial order.
229   EXPECT_EQ(name_a, GetCache()->GetNameOfProfileAtIndex(0));
230   EXPECT_EQ(name_c, GetCache()->GetNameOfProfileAtIndex(1));
231
232   // Add a new profile (start with a capital to test case insensitive sorting.
233   base::string16 name_b = ASCIIToUTF16("Banana");
234   GetCache()->AddProfileToCache(
235       GetProfilePath("path_b"), name_b, base::string16(), 0, std::string());
236
237   // Verify the new order.
238   EXPECT_EQ(name_a, GetCache()->GetNameOfProfileAtIndex(0));
239   EXPECT_EQ(name_b, GetCache()->GetNameOfProfileAtIndex(1));
240   EXPECT_EQ(name_c, GetCache()->GetNameOfProfileAtIndex(2));
241
242   // Change the name of an existing profile.
243   name_a = UTF8ToUTF16("dog");
244   GetCache()->SetNameOfProfileAtIndex(0, name_a);
245
246   // Verify the new order.
247   EXPECT_EQ(name_b, GetCache()->GetNameOfProfileAtIndex(0));
248   EXPECT_EQ(name_c, GetCache()->GetNameOfProfileAtIndex(1));
249   EXPECT_EQ(name_a, GetCache()->GetNameOfProfileAtIndex(2));
250
251   // Delete a profile.
252   GetCache()->DeleteProfileFromCache(GetProfilePath("path_c"));
253
254   // Verify the new order.
255   EXPECT_EQ(name_b, GetCache()->GetNameOfProfileAtIndex(0));
256   EXPECT_EQ(name_a, GetCache()->GetNameOfProfileAtIndex(1));
257 }
258
259 TEST_F(ProfileInfoCacheTest, BackgroundModeStatus) {
260   GetCache()->AddProfileToCache(
261       GetProfilePath("path_1"), ASCIIToUTF16("name_1"),
262       base::string16(), 0, std::string());
263   GetCache()->AddProfileToCache(
264       GetProfilePath("path_2"), ASCIIToUTF16("name_2"),
265       base::string16(), 0, std::string());
266
267   EXPECT_FALSE(GetCache()->GetBackgroundStatusOfProfileAtIndex(0));
268   EXPECT_FALSE(GetCache()->GetBackgroundStatusOfProfileAtIndex(1));
269
270   GetCache()->SetBackgroundStatusOfProfileAtIndex(1, true);
271
272   EXPECT_FALSE(GetCache()->GetBackgroundStatusOfProfileAtIndex(0));
273   EXPECT_TRUE(GetCache()->GetBackgroundStatusOfProfileAtIndex(1));
274
275   GetCache()->SetBackgroundStatusOfProfileAtIndex(0, true);
276
277   EXPECT_TRUE(GetCache()->GetBackgroundStatusOfProfileAtIndex(0));
278   EXPECT_TRUE(GetCache()->GetBackgroundStatusOfProfileAtIndex(1));
279
280   GetCache()->SetBackgroundStatusOfProfileAtIndex(1, false);
281
282   EXPECT_TRUE(GetCache()->GetBackgroundStatusOfProfileAtIndex(0));
283   EXPECT_FALSE(GetCache()->GetBackgroundStatusOfProfileAtIndex(1));
284 }
285
286 TEST_F(ProfileInfoCacheTest, ProfileActiveTime) {
287   GetCache()->AddProfileToCache(
288       GetProfilePath("path_1"), ASCIIToUTF16("name_1"),
289       base::string16(), 0, std::string());
290   EXPECT_EQ(base::Time(), GetCache()->GetProfileActiveTimeAtIndex(0));
291   // Before & After times are artificially shifted because just relying upon
292   // the system time can yield problems due to inaccuracies in the
293   // underlying storage system (which uses a double with only 52 bits of
294   // precision to store the 64-bit "time" number).  http://crbug.com/346827
295   base::Time before = base::Time::Now();
296   before -= base::TimeDelta::FromSeconds(1);
297   GetCache()->SetProfileActiveTimeAtIndex(0);
298   base::Time after = base::Time::Now();
299   after += base::TimeDelta::FromSeconds(1);
300   EXPECT_LE(before, GetCache()->GetProfileActiveTimeAtIndex(0));
301   EXPECT_GE(after, GetCache()->GetProfileActiveTimeAtIndex(0));
302 }
303
304 TEST_F(ProfileInfoCacheTest, GAIAName) {
305   GetCache()->AddProfileToCache(
306       GetProfilePath("path_1"), ASCIIToUTF16("Person 1"),
307       base::string16(), 0, std::string());
308   base::string16 profile_name(ASCIIToUTF16("Person 2"));
309   GetCache()->AddProfileToCache(
310       GetProfilePath("path_2"), profile_name, base::string16(), 0,
311       std::string());
312
313   int index1 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_1"));
314   int index2 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_2"));
315
316   // Sanity check.
317   EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(index1).empty());
318   EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(index2).empty());
319
320   // Set GAIA name. This re-sorts the cache.
321   base::string16 gaia_name(ASCIIToUTF16("Pat Smith"));
322   GetCache()->SetGAIANameOfProfileAtIndex(index2, gaia_name);
323   index1 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_1"));
324   index2 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_2"));
325
326   // Since there is a GAIA name, we use that as a display name.
327   EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(index1).empty());
328   EXPECT_EQ(gaia_name, GetCache()->GetGAIANameOfProfileAtIndex(index2));
329   EXPECT_EQ(gaia_name, GetCache()->GetNameOfProfileAtIndex(index2));
330
331   // Don't use GAIA name as profile name. This re-sorts the cache.
332   base::string16 custom_name(ASCIIToUTF16("Custom name"));
333   GetCache()->SetNameOfProfileAtIndex(index2, custom_name);
334   index1 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_1"));
335   index2 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_2"));
336
337   EXPECT_EQ(custom_name, GetCache()->GetNameOfProfileAtIndex(index2));
338   EXPECT_EQ(gaia_name, GetCache()->GetGAIANameOfProfileAtIndex(index2));
339 }
340
341 TEST_F(ProfileInfoCacheTest, GAIAPicture) {
342   GetCache()->AddProfileToCache(
343       GetProfilePath("path_1"), ASCIIToUTF16("name_1"),
344       base::string16(), 0, std::string());
345   GetCache()->AddProfileToCache(
346       GetProfilePath("path_2"), ASCIIToUTF16("name_2"),
347       base::string16(), 0, std::string());
348
349   // Sanity check.
350   EXPECT_EQ(NULL, GetCache()->GetGAIAPictureOfProfileAtIndex(0));
351   EXPECT_EQ(NULL, GetCache()->GetGAIAPictureOfProfileAtIndex(1));
352   EXPECT_FALSE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(0));
353   EXPECT_FALSE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(1));
354
355   // The profile icon should be the default one.
356   int id = profiles::GetDefaultAvatarIconResourceIDAtIndex(0);
357   const gfx::Image& profile_image(
358       ResourceBundle::GetSharedInstance().GetImageNamed(id));
359   EXPECT_TRUE(gfx::test::IsEqual(
360       profile_image, GetCache()->GetAvatarIconOfProfileAtIndex(1)));
361
362   // Set GAIA picture.
363   gfx::Image gaia_image(gfx::test::CreateImage());
364   GetCache()->SetGAIAPictureOfProfileAtIndex(1, &gaia_image);
365   EXPECT_EQ(NULL, GetCache()->GetGAIAPictureOfProfileAtIndex(0));
366   EXPECT_TRUE(gfx::test::IsEqual(
367       gaia_image, *GetCache()->GetGAIAPictureOfProfileAtIndex(1)));
368   EXPECT_TRUE(gfx::test::IsEqual(
369       profile_image, GetCache()->GetAvatarIconOfProfileAtIndex(1)));
370
371   // Use GAIA picture as profile picture.
372   GetCache()->SetIsUsingGAIAPictureOfProfileAtIndex(1, true);
373   EXPECT_TRUE(gfx::test::IsEqual(
374       gaia_image, *GetCache()->GetGAIAPictureOfProfileAtIndex(1)));
375   EXPECT_TRUE(gfx::test::IsEqual(
376       gaia_image, GetCache()->GetAvatarIconOfProfileAtIndex(1)));
377
378   // Don't use GAIA picture as profile picture.
379   GetCache()->SetIsUsingGAIAPictureOfProfileAtIndex(1, false);
380   EXPECT_TRUE(gfx::test::IsEqual(
381       gaia_image, *GetCache()->GetGAIAPictureOfProfileAtIndex(1)));
382   EXPECT_TRUE(gfx::test::IsEqual(
383       profile_image, GetCache()->GetAvatarIconOfProfileAtIndex(1)));
384 }
385
386 TEST_F(ProfileInfoCacheTest, PersistGAIAPicture) {
387   GetCache()->AddProfileToCache(
388       GetProfilePath("path_1"), ASCIIToUTF16("name_1"),
389       base::string16(), 0, std::string());
390   gfx::Image gaia_image(gfx::test::CreateImage());
391
392   content::WindowedNotificationObserver save_observer(
393       chrome::NOTIFICATION_PROFILE_CACHE_PICTURE_SAVED,
394       content::NotificationService::AllSources());
395   GetCache()->SetGAIAPictureOfProfileAtIndex(0, &gaia_image);
396   EXPECT_TRUE(gfx::test::IsEqual(
397       gaia_image, *GetCache()->GetGAIAPictureOfProfileAtIndex(0)));
398
399   // Wait for the file to be written to disk then reset the cache.
400   save_observer.Wait();
401   ResetCache();
402
403   // Try to get the GAIA picture. This should return NULL until the read from
404   // disk is done.
405   content::WindowedNotificationObserver read_observer(
406       chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED,
407       content::NotificationService::AllSources());
408   EXPECT_EQ(NULL, GetCache()->GetGAIAPictureOfProfileAtIndex(0));
409   read_observer.Wait();
410   EXPECT_TRUE(gfx::test::IsEqual(
411     gaia_image, *GetCache()->GetGAIAPictureOfProfileAtIndex(0)));
412 }
413
414 TEST_F(ProfileInfoCacheTest, SetSupervisedUserId) {
415   GetCache()->AddProfileToCache(
416       GetProfilePath("test"), ASCIIToUTF16("Test"),
417       base::string16(), 0, std::string());
418   EXPECT_FALSE(GetCache()->ProfileIsSupervisedAtIndex(0));
419
420   GetCache()->SetSupervisedUserIdOfProfileAtIndex(0, "TEST_ID");
421   EXPECT_TRUE(GetCache()->ProfileIsSupervisedAtIndex(0));
422   EXPECT_EQ("TEST_ID", GetCache()->GetSupervisedUserIdOfProfileAtIndex(0));
423
424   ResetCache();
425   EXPECT_TRUE(GetCache()->ProfileIsSupervisedAtIndex(0));
426
427   GetCache()->SetSupervisedUserIdOfProfileAtIndex(0, std::string());
428   EXPECT_FALSE(GetCache()->ProfileIsSupervisedAtIndex(0));
429   EXPECT_EQ("", GetCache()->GetSupervisedUserIdOfProfileAtIndex(0));
430 }
431
432 TEST_F(ProfileInfoCacheTest, EmptyGAIAInfo) {
433   base::string16 profile_name = ASCIIToUTF16("name_1");
434   int id = profiles::GetDefaultAvatarIconResourceIDAtIndex(0);
435   const gfx::Image& profile_image(
436       ResourceBundle::GetSharedInstance().GetImageNamed(id));
437
438   GetCache()->AddProfileToCache(
439       GetProfilePath("path_1"), profile_name, base::string16(), 0,
440                      std::string());
441
442   // Set empty GAIA info.
443   GetCache()->SetGAIANameOfProfileAtIndex(0, base::string16());
444   GetCache()->SetGAIAPictureOfProfileAtIndex(0, NULL);
445   GetCache()->SetIsUsingGAIAPictureOfProfileAtIndex(0, true);
446
447   // Verify that the profile name and picture are not empty.
448   EXPECT_EQ(profile_name, GetCache()->GetNameOfProfileAtIndex(0));
449   EXPECT_TRUE(gfx::test::IsEqual(
450       profile_image, GetCache()->GetAvatarIconOfProfileAtIndex(0)));
451 }
452
453 TEST_F(ProfileInfoCacheTest, CreateSupervisedTestingProfile) {
454   testing_profile_manager_.CreateTestingProfile("default");
455   base::string16 supervised_user_name = ASCIIToUTF16("Supervised User");
456   testing_profile_manager_.CreateTestingProfile(
457       "test1", scoped_ptr<PrefServiceSyncable>(),
458       supervised_user_name, 0, "TEST_ID", TestingProfile::TestingFactories());
459   for (size_t i = 0; i < GetCache()->GetNumberOfProfiles(); i++) {
460     bool is_supervised =
461         GetCache()->GetNameOfProfileAtIndex(i) == supervised_user_name;
462     EXPECT_EQ(is_supervised, GetCache()->ProfileIsSupervisedAtIndex(i));
463     std::string supervised_user_id = is_supervised ? "TEST_ID" : "";
464     EXPECT_EQ(supervised_user_id,
465               GetCache()->GetSupervisedUserIdOfProfileAtIndex(i));
466   }
467
468   // Supervised profiles have a custom theme, which needs to be deleted on the
469   // FILE thread. Reset the profile manager now so everything is deleted while
470   // we still have a FILE thread.
471   TestingBrowserProcess::GetGlobal()->SetProfileManager(NULL);
472 }
473
474 TEST_F(ProfileInfoCacheTest, AddStubProfile) {
475   EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
476
477   // Add some profiles with and without a '.' in their paths.
478   const struct {
479     const char* profile_path;
480     const char* profile_name;
481   } kTestCases[] = {
482     { "path.test0", "name_0" },
483     { "path_test1", "name_1" },
484     { "path.test2", "name_2" },
485     { "path_test3", "name_3" },
486   };
487
488   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
489     base::FilePath profile_path = GetProfilePath(kTestCases[i].profile_path);
490     base::string16 profile_name = ASCIIToUTF16(kTestCases[i].profile_name);
491
492     GetCache()->AddProfileToCache(profile_path, profile_name, base::string16(),
493                                   i, "");
494
495     EXPECT_EQ(profile_path, GetCache()->GetPathOfProfileAtIndex(i));
496     EXPECT_EQ(profile_name, GetCache()->GetNameOfProfileAtIndex(i));
497   }
498
499   ASSERT_EQ(4U, GetCache()->GetNumberOfProfiles());
500
501   // Check that the profiles can be extracted from the local state.
502   std::vector<base::string16> names = ProfileInfoCache::GetProfileNames();
503   for (size_t i = 0; i < 4; i++)
504     ASSERT_FALSE(names[i].empty());
505 }
506
507 TEST_F(ProfileInfoCacheTest, DownloadHighResAvatarTest) {
508   EXPECT_EQ(0U, GetCache()->GetNumberOfProfiles());
509   base::FilePath path_1 = GetProfilePath("path_1");
510   GetCache()->AddProfileToCache(path_1, ASCIIToUTF16("name_1"),
511                                 base::string16(), 0, std::string());
512   EXPECT_EQ(1U, GetCache()->GetNumberOfProfiles());
513
514   // We haven't downloaded any high-res avatars yet.
515   EXPECT_EQ(0U, GetCache()->cached_avatar_images_.size());
516   EXPECT_EQ(0U, GetCache()->avatar_images_downloads_in_progress_.size());
517   EXPECT_FALSE(GetCache()->GetHighResAvatarOfProfileAtIndex(0));
518
519   // Simulate downloading a high-res avatar.
520   const size_t kIconIndex = 0;
521   ProfileAvatarDownloader avatar_downloader(
522       kIconIndex, GetCache()->GetPathOfProfileAtIndex(0), GetCache());
523
524   // Put a real bitmap into "bitmap".  2x2 bitmap of green 32 bit pixels.
525   SkBitmap bitmap;
526   bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
527   bitmap.allocPixels();
528   bitmap.eraseColor(SK_ColorGREEN);
529
530   avatar_downloader.OnFetchComplete(
531       GURL("http://www.google.com/avatar.png"), &bitmap);
532
533   std::string file_name =
534       profiles::GetDefaultAvatarIconFileNameAtIndex(kIconIndex);
535
536   // The file should have been cached and saved.
537   EXPECT_EQ(0U, GetCache()->avatar_images_downloads_in_progress_.size());
538   EXPECT_EQ(1U, GetCache()->cached_avatar_images_.size());
539   EXPECT_TRUE(GetCache()->GetHighResAvatarOfProfileAtIndex(0));
540   EXPECT_EQ(GetCache()->cached_avatar_images_[file_name],
541       GetCache()->GetHighResAvatarOfProfileAtIndex(0));
542
543   // Make sure everything has completed, and the file has been written to disk.
544   base::RunLoop().RunUntilIdle();
545
546   // Clean up.
547   base::FilePath icon_path =
548       profiles::GetPathOfHighResAvatarAtIndex(kIconIndex);
549   EXPECT_NE(std::string::npos, icon_path.MaybeAsASCII().find(file_name));
550   EXPECT_TRUE(base::PathExists(icon_path));
551   EXPECT_TRUE(base::DeleteFile(icon_path, true));
552   EXPECT_FALSE(base::PathExists(icon_path));
553 }