profile_info_cache_unittest.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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 "base/prefs/testing_pref_service.h"
8#include "base/strings/stringprintf.h"
9#include "base/strings/utf_string_conversions.h"
10#include "chrome/browser/browser_process.h"
11#include "chrome/browser/chrome_notification_types.h"
12#include "chrome/browser/profiles/profile_info_cache.h"
13#include "chrome/browser/profiles/profile_manager.h"
14#include "chrome/test/base/testing_browser_process.h"
15#include "content/public/browser/notification_observer.h"
16#include "content/public/browser/notification_registrar.h"
17#include "content/public/browser/notification_service.h"
18#include "content/public/test/test_utils.h"
19#include "third_party/skia/include/core/SkBitmap.h"
20#include "ui/base/resource/resource_bundle.h"
21#include "ui/gfx/image/image.h"
22#include "ui/gfx/image/image_unittest_util.h"
23
24using content::BrowserThread;
25
26ProfileNameVerifierObserver::ProfileNameVerifierObserver(
27    TestingProfileManager* testing_profile_manager)
28    : testing_profile_manager_(testing_profile_manager) {
29  DCHECK(testing_profile_manager_);
30}
31
32ProfileNameVerifierObserver::~ProfileNameVerifierObserver() {
33}
34
35void ProfileNameVerifierObserver::OnProfileAdded(
36    const base::FilePath& profile_path) {
37  string16 profile_name = GetCache()->GetNameOfProfileAtIndex(
38      GetCache()->GetIndexOfProfileWithPath(profile_path));
39  EXPECT_TRUE(profile_names_.find(profile_name) == profile_names_.end());
40  profile_names_.insert(profile_name);
41}
42
43void ProfileNameVerifierObserver::OnProfileWillBeRemoved(
44    const base::FilePath& profile_path) {
45  string16 profile_name = GetCache()->GetNameOfProfileAtIndex(
46      GetCache()->GetIndexOfProfileWithPath(profile_path));
47  EXPECT_TRUE(profile_names_.find(profile_name) != profile_names_.end());
48  profile_names_.erase(profile_name);
49}
50
51void ProfileNameVerifierObserver::OnProfileWasRemoved(
52    const base::FilePath& profile_path,
53    const string16& profile_name) {
54  EXPECT_TRUE(profile_names_.find(profile_name) == profile_names_.end());
55}
56
57void ProfileNameVerifierObserver::OnProfileNameChanged(
58    const base::FilePath& profile_path,
59    const string16& old_profile_name) {
60  string16 new_profile_name = GetCache()->GetNameOfProfileAtIndex(
61      GetCache()->GetIndexOfProfileWithPath(profile_path));
62  EXPECT_TRUE(profile_names_.find(old_profile_name) != profile_names_.end());
63  EXPECT_TRUE(profile_names_.find(new_profile_name) == profile_names_.end());
64  profile_names_.erase(old_profile_name);
65  profile_names_.insert(new_profile_name);
66}
67
68void ProfileNameVerifierObserver::OnProfileAvatarChanged(
69    const base::FilePath& profile_path) {
70  string16 profile_name = GetCache()->GetNameOfProfileAtIndex(
71      GetCache()->GetIndexOfProfileWithPath(profile_path));
72  EXPECT_TRUE(profile_names_.find(profile_name) != profile_names_.end());
73}
74
75ProfileInfoCache* ProfileNameVerifierObserver::GetCache() {
76  return testing_profile_manager_->profile_info_cache();
77}
78
79ProfileInfoCacheTest::ProfileInfoCacheTest()
80    : testing_profile_manager_(
81        TestingBrowserProcess::GetGlobal()),
82      ui_thread_(BrowserThread::UI, &ui_loop_),
83      file_thread_(BrowserThread::FILE, &ui_loop_),
84      name_observer_(&testing_profile_manager_) {
85}
86
87ProfileInfoCacheTest::~ProfileInfoCacheTest() {
88}
89
90void ProfileInfoCacheTest::SetUp() {
91  ASSERT_TRUE(testing_profile_manager_.SetUp());
92  testing_profile_manager_.profile_info_cache()->AddObserver(&name_observer_);
93}
94
95void ProfileInfoCacheTest::TearDown() {
96  // Drain the UI thread to make sure all tasks are completed. This prevents
97  // memory leaks.
98  ui_loop_.RunUntilIdle();
99}
100
101ProfileInfoCache* ProfileInfoCacheTest::GetCache() {
102  return testing_profile_manager_.profile_info_cache();
103}
104
105base::FilePath ProfileInfoCacheTest::GetProfilePath(
106    const std::string& base_name) {
107  return testing_profile_manager_.profile_manager()->user_data_dir().
108      AppendASCII(base_name);
109}
110
111void ProfileInfoCacheTest::ResetCache() {
112  testing_profile_manager_.DeleteProfileInfoCache();
113}
114
115namespace {
116
117TEST_F(ProfileInfoCacheTest, AddProfiles) {
118  EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
119
120  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
121  for (uint32 i = 0; i < 4; ++i) {
122    base::FilePath profile_path =
123        GetProfilePath(base::StringPrintf("path_%ud", i));
124    string16 profile_name = ASCIIToUTF16(base::StringPrintf("name_%ud", i));
125    const SkBitmap* icon = rb.GetImageNamed(
126        ProfileInfoCache::GetDefaultAvatarIconResourceIDAtIndex(
127            i)).ToSkBitmap();
128
129    GetCache()->AddProfileToCache(profile_path, profile_name, string16(), i,
130                                  false);
131    GetCache()->SetBackgroundStatusOfProfileAtIndex(i, true);
132    string16 gaia_name = ASCIIToUTF16(base::StringPrintf("gaia_%ud", i));
133    GetCache()->SetGAIANameOfProfileAtIndex(i, gaia_name);
134
135    EXPECT_EQ(i + 1, GetCache()->GetNumberOfProfiles());
136    EXPECT_EQ(profile_name, GetCache()->GetNameOfProfileAtIndex(i));
137    EXPECT_EQ(profile_path, GetCache()->GetPathOfProfileAtIndex(i));
138    const SkBitmap* actual_icon = GetCache()->GetAvatarIconOfProfileAtIndex(
139        i).ToSkBitmap();
140    EXPECT_EQ(icon->width(), actual_icon->width());
141    EXPECT_EQ(icon->height(), actual_icon->height());
142  }
143
144  // Reset the cache and test the it reloads correctly.
145  ResetCache();
146
147  EXPECT_EQ(4u, GetCache()->GetNumberOfProfiles());
148  for (uint32 i = 0; i < 4; ++i) {
149    base::FilePath profile_path =
150          GetProfilePath(base::StringPrintf("path_%ud", i));
151    EXPECT_EQ(i, GetCache()->GetIndexOfProfileWithPath(profile_path));
152    string16 profile_name = ASCIIToUTF16(base::StringPrintf("name_%ud", i));
153    EXPECT_EQ(profile_name, GetCache()->GetNameOfProfileAtIndex(i));
154    EXPECT_EQ(i, GetCache()->GetAvatarIconIndexOfProfileAtIndex(i));
155    EXPECT_EQ(true, GetCache()->GetBackgroundStatusOfProfileAtIndex(i));
156    string16 gaia_name = ASCIIToUTF16(base::StringPrintf("gaia_%ud", i));
157    EXPECT_EQ(gaia_name, GetCache()->GetGAIANameOfProfileAtIndex(i));
158  }
159}
160
161TEST_F(ProfileInfoCacheTest, DeleteProfile) {
162  EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
163
164  base::FilePath path_1 = GetProfilePath("path_1");
165  GetCache()->AddProfileToCache(path_1, ASCIIToUTF16("name_1"), string16(),
166                                0, false);
167  EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles());
168
169  base::FilePath path_2 = GetProfilePath("path_2");
170  string16 name_2 = ASCIIToUTF16("name_2");
171  GetCache()->AddProfileToCache(path_2, name_2, string16(), 0, false);
172  EXPECT_EQ(2u, GetCache()->GetNumberOfProfiles());
173
174  GetCache()->DeleteProfileFromCache(path_1);
175  EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles());
176  EXPECT_EQ(name_2, GetCache()->GetNameOfProfileAtIndex(0));
177
178  GetCache()->DeleteProfileFromCache(path_2);
179  EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
180}
181
182TEST_F(ProfileInfoCacheTest, MutateProfile) {
183  GetCache()->AddProfileToCache(
184      GetProfilePath("path_1"), ASCIIToUTF16("name_1"), string16(), 0, false);
185  GetCache()->AddProfileToCache(
186      GetProfilePath("path_2"), ASCIIToUTF16("name_2"), string16(), 0, false);
187
188  string16 new_name = ASCIIToUTF16("new_name");
189  GetCache()->SetNameOfProfileAtIndex(1, new_name);
190  EXPECT_EQ(new_name, GetCache()->GetNameOfProfileAtIndex(1));
191  EXPECT_NE(new_name, GetCache()->GetNameOfProfileAtIndex(0));
192
193  string16 new_user_name = ASCIIToUTF16("user_name");
194  GetCache()->SetUserNameOfProfileAtIndex(1, new_user_name);
195  EXPECT_EQ(new_user_name, GetCache()->GetUserNameOfProfileAtIndex(1));
196  EXPECT_NE(new_user_name, GetCache()->GetUserNameOfProfileAtIndex(0));
197
198  size_t new_icon_index = 3;
199  GetCache()->SetAvatarIconOfProfileAtIndex(1, new_icon_index);
200  // Not much to test.
201  GetCache()->GetAvatarIconOfProfileAtIndex(1);
202}
203
204TEST_F(ProfileInfoCacheTest, Sort) {
205  string16 name_a = ASCIIToUTF16("apple");
206  GetCache()->AddProfileToCache(
207      GetProfilePath("path_a"), name_a, string16(), 0, false);
208
209  string16 name_c = ASCIIToUTF16("cat");
210  GetCache()->AddProfileToCache(
211      GetProfilePath("path_c"), name_c, string16(), 0, false);
212
213  // Sanity check the initial order.
214  EXPECT_EQ(name_a, GetCache()->GetNameOfProfileAtIndex(0));
215  EXPECT_EQ(name_c, GetCache()->GetNameOfProfileAtIndex(1));
216
217  // Add a new profile (start with a capital to test case insensitive sorting.
218  string16 name_b = ASCIIToUTF16("Banana");
219  GetCache()->AddProfileToCache(
220      GetProfilePath("path_b"), name_b, string16(), 0, false);
221
222  // Verify the new order.
223  EXPECT_EQ(name_a, GetCache()->GetNameOfProfileAtIndex(0));
224  EXPECT_EQ(name_b, GetCache()->GetNameOfProfileAtIndex(1));
225  EXPECT_EQ(name_c, GetCache()->GetNameOfProfileAtIndex(2));
226
227  // Change the name of an existing profile.
228  name_a = UTF8ToUTF16("dog");
229  GetCache()->SetNameOfProfileAtIndex(0, name_a);
230
231  // Verify the new order.
232  EXPECT_EQ(name_b, GetCache()->GetNameOfProfileAtIndex(0));
233  EXPECT_EQ(name_c, GetCache()->GetNameOfProfileAtIndex(1));
234  EXPECT_EQ(name_a, GetCache()->GetNameOfProfileAtIndex(2));
235
236  // Delete a profile.
237  GetCache()->DeleteProfileFromCache(GetProfilePath("path_c"));
238
239  // Verify the new order.
240  EXPECT_EQ(name_b, GetCache()->GetNameOfProfileAtIndex(0));
241  EXPECT_EQ(name_a, GetCache()->GetNameOfProfileAtIndex(1));
242}
243
244TEST_F(ProfileInfoCacheTest, BackgroundModeStatus) {
245  GetCache()->AddProfileToCache(
246      GetProfilePath("path_1"), ASCIIToUTF16("name_1"), string16(), 0, false);
247  GetCache()->AddProfileToCache(
248      GetProfilePath("path_2"), ASCIIToUTF16("name_2"), string16(), 0, false);
249
250  EXPECT_FALSE(GetCache()->GetBackgroundStatusOfProfileAtIndex(0));
251  EXPECT_FALSE(GetCache()->GetBackgroundStatusOfProfileAtIndex(1));
252
253  GetCache()->SetBackgroundStatusOfProfileAtIndex(1, true);
254
255  EXPECT_FALSE(GetCache()->GetBackgroundStatusOfProfileAtIndex(0));
256  EXPECT_TRUE(GetCache()->GetBackgroundStatusOfProfileAtIndex(1));
257
258  GetCache()->SetBackgroundStatusOfProfileAtIndex(0, true);
259
260  EXPECT_TRUE(GetCache()->GetBackgroundStatusOfProfileAtIndex(0));
261  EXPECT_TRUE(GetCache()->GetBackgroundStatusOfProfileAtIndex(1));
262
263  GetCache()->SetBackgroundStatusOfProfileAtIndex(1, false);
264
265  EXPECT_TRUE(GetCache()->GetBackgroundStatusOfProfileAtIndex(0));
266  EXPECT_FALSE(GetCache()->GetBackgroundStatusOfProfileAtIndex(1));
267}
268
269TEST_F(ProfileInfoCacheTest, HasMigrated) {
270  GetCache()->AddProfileToCache(
271      GetProfilePath("path_1"), ASCIIToUTF16("name_1"), string16(), 0, false);
272  GetCache()->AddProfileToCache(
273      GetProfilePath("path_2"), ASCIIToUTF16("name_2"), string16(), 0, false);
274
275  // Sanity check.
276  EXPECT_FALSE(GetCache()->GetHasMigratedToGAIAInfoOfProfileAtIndex(0));
277  EXPECT_FALSE(GetCache()->GetHasMigratedToGAIAInfoOfProfileAtIndex(1));
278
279  // Set migrated state for 2nd profile.
280  GetCache()->SetHasMigratedToGAIAInfoOfProfileAtIndex(1, true);
281  EXPECT_FALSE(GetCache()->GetHasMigratedToGAIAInfoOfProfileAtIndex(0));
282  EXPECT_TRUE(GetCache()->GetHasMigratedToGAIAInfoOfProfileAtIndex(1));
283
284  // Set migrated state for 1st profile.
285  GetCache()->SetHasMigratedToGAIAInfoOfProfileAtIndex(0, true);
286  EXPECT_TRUE(GetCache()->GetHasMigratedToGAIAInfoOfProfileAtIndex(0));
287  EXPECT_TRUE(GetCache()->GetHasMigratedToGAIAInfoOfProfileAtIndex(1));
288
289  // Unset migrated state for 2nd profile.
290  GetCache()->SetHasMigratedToGAIAInfoOfProfileAtIndex(1, false);
291  EXPECT_TRUE(GetCache()->GetHasMigratedToGAIAInfoOfProfileAtIndex(0));
292  EXPECT_FALSE(GetCache()->GetHasMigratedToGAIAInfoOfProfileAtIndex(1));
293}
294
295TEST_F(ProfileInfoCacheTest, GAIAName) {
296  GetCache()->AddProfileToCache(
297      GetProfilePath("path_1"), ASCIIToUTF16("name_1"), string16(), 0, false);
298  string16 profile_name(ASCIIToUTF16("profile name 2"));
299  GetCache()->AddProfileToCache(
300      GetProfilePath("path_2"), profile_name, string16(), 0, false);
301
302  // Sanity check.
303  EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(0).empty());
304  EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(1).empty());
305  EXPECT_FALSE(GetCache()->IsUsingGAIANameOfProfileAtIndex(0));
306  EXPECT_FALSE(GetCache()->IsUsingGAIANameOfProfileAtIndex(1));
307
308  // Set GAIA name.
309  string16 gaia_name(ASCIIToUTF16("Pat Smith"));
310  GetCache()->SetGAIANameOfProfileAtIndex(1, gaia_name);
311  EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(0).empty());
312  EXPECT_EQ(gaia_name, GetCache()->GetGAIANameOfProfileAtIndex(1));
313  EXPECT_EQ(profile_name, GetCache()->GetNameOfProfileAtIndex(1));
314
315  // Use GAIA name as profile name.
316  GetCache()->SetIsUsingGAIANameOfProfileAtIndex(1, true);
317
318  EXPECT_EQ(gaia_name, GetCache()->GetNameOfProfileAtIndex(1));
319  EXPECT_EQ(gaia_name, GetCache()->GetGAIANameOfProfileAtIndex(1));
320
321  // Don't use GAIA name as profile name.
322  GetCache()->SetIsUsingGAIANameOfProfileAtIndex(1, false);
323  EXPECT_EQ(profile_name, GetCache()->GetNameOfProfileAtIndex(1));
324  EXPECT_EQ(gaia_name, GetCache()->GetGAIANameOfProfileAtIndex(1));
325}
326
327TEST_F(ProfileInfoCacheTest, GAIAPicture) {
328  GetCache()->AddProfileToCache(
329      GetProfilePath("path_1"), ASCIIToUTF16("name_1"), string16(), 0, false);
330  GetCache()->AddProfileToCache(
331      GetProfilePath("path_2"), ASCIIToUTF16("name_2"), string16(), 0, false);
332
333  // Sanity check.
334  EXPECT_EQ(NULL, GetCache()->GetGAIAPictureOfProfileAtIndex(0));
335  EXPECT_EQ(NULL, GetCache()->GetGAIAPictureOfProfileAtIndex(1));
336  EXPECT_FALSE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(0));
337  EXPECT_FALSE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(1));
338
339  // The profile icon should be the default one.
340  int id = ProfileInfoCache::GetDefaultAvatarIconResourceIDAtIndex(0);
341  const gfx::Image& profile_image(
342      ResourceBundle::GetSharedInstance().GetImageNamed(id));
343  EXPECT_TRUE(gfx::test::IsEqual(
344      profile_image, GetCache()->GetAvatarIconOfProfileAtIndex(1)));
345
346  // Set GAIA picture.
347  gfx::Image gaia_image(gfx::test::CreateImage());
348  GetCache()->SetGAIAPictureOfProfileAtIndex(1, &gaia_image);
349  EXPECT_EQ(NULL, GetCache()->GetGAIAPictureOfProfileAtIndex(0));
350  EXPECT_TRUE(gfx::test::IsEqual(
351      gaia_image, *GetCache()->GetGAIAPictureOfProfileAtIndex(1)));
352  EXPECT_TRUE(gfx::test::IsEqual(
353      profile_image, GetCache()->GetAvatarIconOfProfileAtIndex(1)));
354
355  // Use GAIA picture as profile picture.
356  GetCache()->SetIsUsingGAIAPictureOfProfileAtIndex(1, true);
357  EXPECT_TRUE(gfx::test::IsEqual(
358      gaia_image, *GetCache()->GetGAIAPictureOfProfileAtIndex(1)));
359  EXPECT_TRUE(gfx::test::IsEqual(
360      gaia_image, GetCache()->GetAvatarIconOfProfileAtIndex(1)));
361
362  // Don't use GAIA picture as profile picture.
363  GetCache()->SetIsUsingGAIAPictureOfProfileAtIndex(1, false);
364  EXPECT_TRUE(gfx::test::IsEqual(
365      gaia_image, *GetCache()->GetGAIAPictureOfProfileAtIndex(1)));
366  EXPECT_TRUE(gfx::test::IsEqual(
367      profile_image, GetCache()->GetAvatarIconOfProfileAtIndex(1)));
368}
369
370TEST_F(ProfileInfoCacheTest, PersistGAIAPicture) {
371  GetCache()->AddProfileToCache(
372      GetProfilePath("path_1"), ASCIIToUTF16("name_1"), string16(), 0, false);
373  gfx::Image gaia_image(gfx::test::CreateImage());
374
375  content::WindowedNotificationObserver save_observer(
376      chrome::NOTIFICATION_PROFILE_CACHE_PICTURE_SAVED,
377      content::NotificationService::AllSources());
378  GetCache()->SetGAIAPictureOfProfileAtIndex(0, &gaia_image);
379  EXPECT_TRUE(gfx::test::IsEqual(
380      gaia_image, *GetCache()->GetGAIAPictureOfProfileAtIndex(0)));
381
382  // Wait for the file to be written to disk then reset the cache.
383  save_observer.Wait();
384  ResetCache();
385
386  // Try to get the GAIA picture. This should return NULL until the read from
387  // disk is done.
388  content::WindowedNotificationObserver read_observer(
389      chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED,
390      content::NotificationService::AllSources());
391  EXPECT_EQ(NULL, GetCache()->GetGAIAPictureOfProfileAtIndex(0));
392  read_observer.Wait();
393  EXPECT_TRUE(gfx::test::IsEqual(
394    gaia_image, *GetCache()->GetGAIAPictureOfProfileAtIndex(0)));
395}
396
397TEST_F(ProfileInfoCacheTest, EmptyGAIAInfo) {
398  string16 profile_name = ASCIIToUTF16("name_1");
399  int id = ProfileInfoCache::GetDefaultAvatarIconResourceIDAtIndex(0);
400  const gfx::Image& profile_image(
401      ResourceBundle::GetSharedInstance().GetImageNamed(id));
402
403  GetCache()->AddProfileToCache(
404      GetProfilePath("path_1"), profile_name, string16(), 0, false);
405
406  // Set empty GAIA info.
407  GetCache()->SetGAIANameOfProfileAtIndex(0, string16());
408  GetCache()->SetGAIAPictureOfProfileAtIndex(0, NULL);
409  GetCache()->SetIsUsingGAIANameOfProfileAtIndex(0, true);
410  GetCache()->SetIsUsingGAIAPictureOfProfileAtIndex(0, true);
411
412  // Verify that the profile name and picture are not empty.
413  EXPECT_EQ(profile_name, GetCache()->GetNameOfProfileAtIndex(0));
414  EXPECT_TRUE(gfx::test::IsEqual(
415      profile_image, GetCache()->GetAvatarIconOfProfileAtIndex(0)));
416}
417
418}  // namespace
419