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 <stddef.h>
8 #include <stdint.h>
9
10 #include <algorithm>
11 #include <set>
12 #include <vector>
13
14 #include "base/bind.h"
15 #include "base/command_line.h"
16 #include "base/files/file_util.h"
17 #include "base/stl_util.h"
18 #include "base/strings/stringprintf.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "base/time/time.h"
21 #include "build/build_config.h"
22 #include "chrome/browser/browser_process.h"
23 #include "chrome/browser/profiles/avatar_menu.h"
24 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
25 #include "chrome/browser/profiles/profile_info_cache.h"
26 #include "chrome/browser/profiles/profile_manager.h"
27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/pref_names.h"
29 #include "chrome/test/base/testing_browser_process.h"
30 #include "components/account_id/account_id.h"
31 #include "components/prefs/testing_pref_service.h"
32 #include "components/sync_preferences/pref_service_syncable.h"
33 #include "content/public/test/browser_task_environment.h"
34 #include "content/public/test/test_utils.h"
35 #include "third_party/skia/include/core/SkBitmap.h"
36 #include "ui/base/resource/resource_bundle.h"
37 #include "ui/gfx/image/image.h"
38 #include "ui/gfx/image/image_unittest_util.h"
39
40 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
41 #include "chrome/browser/supervised_user/supervised_user_constants.h"
42 #endif
43
44 using base::ASCIIToUTF16;
45 using base::UTF8ToUTF16;
46 using content::BrowserThread;
47
48 namespace {
49
GetDefaultAvatarIconResourceIDAtIndex(int index)50 size_t GetDefaultAvatarIconResourceIDAtIndex(int index) {
51 #if defined(OS_WIN)
52 return profiles::GetOldDefaultAvatar2xIconResourceIDAtIndex(index);
53 #else
54 return profiles::GetDefaultAvatarIconResourceIDAtIndex(index);
55 #endif // defined(OS_WIN)
56 }
57
58 } // namespace
59
ProfileNameVerifierObserver(TestingProfileManager * testing_profile_manager)60 ProfileNameVerifierObserver::ProfileNameVerifierObserver(
61 TestingProfileManager* testing_profile_manager)
62 : testing_profile_manager_(testing_profile_manager) {
63 DCHECK(testing_profile_manager_);
64 }
65
~ProfileNameVerifierObserver()66 ProfileNameVerifierObserver::~ProfileNameVerifierObserver() {
67 }
68
OnProfileAdded(const base::FilePath & profile_path)69 void ProfileNameVerifierObserver::OnProfileAdded(
70 const base::FilePath& profile_path) {
71 ProfileAttributesEntry* entry = nullptr;
72 GetCache()->GetProfileAttributesWithPath(profile_path, &entry);
73 base::string16 profile_name = entry->GetName();
74 EXPECT_TRUE(profile_names_.find(profile_path) == profile_names_.end());
75 profile_names_.insert({profile_path, profile_name});
76 }
77
OnProfileWillBeRemoved(const base::FilePath & profile_path)78 void ProfileNameVerifierObserver::OnProfileWillBeRemoved(
79 const base::FilePath& profile_path) {
80 auto it = profile_names_.find(profile_path);
81 EXPECT_TRUE(it != profile_names_.end());
82 profile_names_.erase(it);
83 }
84
OnProfileWasRemoved(const base::FilePath & profile_path,const base::string16 & profile_name)85 void ProfileNameVerifierObserver::OnProfileWasRemoved(
86 const base::FilePath& profile_path,
87 const base::string16& profile_name) {
88 EXPECT_TRUE(profile_names_.find(profile_path) == profile_names_.end());
89 }
90
OnProfileNameChanged(const base::FilePath & profile_path,const base::string16 & old_profile_name)91 void ProfileNameVerifierObserver::OnProfileNameChanged(
92 const base::FilePath& profile_path,
93 const base::string16& old_profile_name) {
94 ProfileAttributesEntry* entry = nullptr;
95 GetCache()->GetProfileAttributesWithPath(profile_path, &entry);
96 base::string16 new_profile_name = entry->GetName();
97 EXPECT_TRUE(profile_names_[profile_path] == old_profile_name);
98 profile_names_[profile_path] = new_profile_name;
99 }
100
OnProfileAvatarChanged(const base::FilePath & profile_path)101 void ProfileNameVerifierObserver::OnProfileAvatarChanged(
102 const base::FilePath& profile_path) {
103 EXPECT_TRUE(profile_names_.find(profile_path) != profile_names_.end());
104 }
105
GetCache()106 ProfileInfoCache* ProfileNameVerifierObserver::GetCache() {
107 return testing_profile_manager_->profile_info_cache();
108 }
109
ProfileInfoCacheTest()110 ProfileInfoCacheTest::ProfileInfoCacheTest()
111 : testing_profile_manager_(TestingBrowserProcess::GetGlobal()),
112 name_observer_(&testing_profile_manager_) {}
113
~ProfileInfoCacheTest()114 ProfileInfoCacheTest::~ProfileInfoCacheTest() {
115 }
116
SetUp()117 void ProfileInfoCacheTest::SetUp() {
118 ASSERT_TRUE(testing_profile_manager_.SetUp());
119 testing_profile_manager_.profile_info_cache()->AddObserver(&name_observer_);
120 }
121
TearDown()122 void ProfileInfoCacheTest::TearDown() {
123 // Drain remaining tasks to make sure all tasks are completed. This prevents
124 // memory leaks.
125 content::RunAllTasksUntilIdle();
126 }
127
GetCache()128 ProfileInfoCache* ProfileInfoCacheTest::GetCache() {
129 return testing_profile_manager_.profile_info_cache();
130 }
131
GetProfilePath(const std::string & base_name)132 base::FilePath ProfileInfoCacheTest::GetProfilePath(
133 const std::string& base_name) {
134 return testing_profile_manager_.profile_manager()->user_data_dir().
135 AppendASCII(base_name);
136 }
137
ResetCache()138 void ProfileInfoCacheTest::ResetCache() {
139 testing_profile_manager_.DeleteProfileInfoCache();
140 }
141
GetConcatenation(const base::string16 & gaia_name,const base::string16 profile_name)142 base::string16 ProfileInfoCacheTest::GetConcatenation(
143 const base::string16& gaia_name,
144 const base::string16 profile_name) {
145 base::string16 name_to_display(gaia_name);
146 name_to_display.append(base::UTF8ToUTF16(" ("));
147 name_to_display.append(profile_name);
148 name_to_display.append(base::UTF8ToUTF16(")"));
149 return name_to_display;
150 }
151
TEST_F(ProfileInfoCacheTest,AddProfiles)152 TEST_F(ProfileInfoCacheTest, AddProfiles) {
153 EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
154 // Avatar icons not used on Android.
155 #if !defined(OS_ANDROID)
156 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
157 #endif
158
159 for (uint32_t i = 0; i < 4; ++i) {
160 base::FilePath profile_path =
161 GetProfilePath(base::StringPrintf("path_%ud", i));
162 base::string16 profile_name =
163 ASCIIToUTF16(base::StringPrintf("name_%ud", i));
164 #if !defined(OS_ANDROID)
165
166 size_t icon_id = GetDefaultAvatarIconResourceIDAtIndex(i);
167 const SkBitmap* icon = rb.GetImageNamed(icon_id).ToSkBitmap();
168
169 #endif // !defined(OS_ANDROID)
170 std::string supervised_user_id;
171 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
172 if (i == 3)
173 supervised_user_id = supervised_users::kChildAccountSUID;
174 #endif
175
176 GetCache()->AddProfileToCache(profile_path, profile_name, std::string(),
177 base::string16(), false, i,
178 supervised_user_id, EmptyAccountId());
179
180 ProfileAttributesEntry* entry = nullptr;
181 GetCache()->GetProfileAttributesWithPath(profile_path, &entry);
182 entry->SetBackgroundStatus(true);
183 base::string16 gaia_name = ASCIIToUTF16(base::StringPrintf("gaia_%ud", i));
184 entry->SetGAIAName(gaia_name);
185
186 EXPECT_EQ(i + 1, GetCache()->GetNumberOfProfiles());
187 base::string16 expected_profile_name =
188 GetConcatenation(gaia_name, profile_name);
189
190 EXPECT_EQ(expected_profile_name, entry->GetName());
191
192 EXPECT_EQ(profile_path, GetCache()->GetPathOfProfileAtIndex(i));
193 #if !defined(OS_ANDROID)
194 const SkBitmap* actual_icon = entry->GetAvatarIcon().ToSkBitmap();
195 EXPECT_EQ(icon->width(), actual_icon->width());
196 EXPECT_EQ(icon->height(), actual_icon->height());
197 #endif
198 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
199 EXPECT_EQ(i == 3, entry->IsSupervised());
200 EXPECT_EQ(i == 3, entry->IsOmitted());
201 #else
202 EXPECT_FALSE(entry->IsSupervised());
203 EXPECT_FALSE(entry->IsOmitted());
204 #endif // BUILDFLAG(ENABLE_SUPERVISED_USERS)
205 EXPECT_EQ(supervised_user_id, entry->GetSupervisedUserId());
206 }
207
208 // Reset the cache and test the it reloads correctly.
209 ResetCache();
210
211 EXPECT_EQ(4u, GetCache()->GetNumberOfProfiles());
212 for (uint32_t i = 0; i < 4; ++i) {
213 base::FilePath profile_path =
214 GetProfilePath(base::StringPrintf("path_%ud", i));
215 int index = GetCache()->GetIndexOfProfileWithPath(profile_path);
216 ProfileAttributesEntry* entry = nullptr;
217 GetCache()->GetProfileAttributesWithPath(profile_path, &entry);
218 base::string16 profile_name =
219 ASCIIToUTF16(base::StringPrintf("name_%ud", index));
220 base::string16 gaia_name = ASCIIToUTF16(base::StringPrintf("gaia_%ud", i));
221 base::string16 expected_profile_name =
222 GetConcatenation(gaia_name, profile_name);
223 EXPECT_EQ(expected_profile_name, entry->GetName());
224 #if !defined(OS_ANDROID)
225 EXPECT_EQ(i, GetCache()->GetAvatarIconIndexOfProfileAtIndex(index));
226 #endif
227 EXPECT_EQ(true, entry->GetBackgroundStatus());
228 EXPECT_EQ(gaia_name, entry->GetGAIAName());
229 }
230 }
231
TEST_F(ProfileInfoCacheTest,GAIAName)232 TEST_F(ProfileInfoCacheTest, GAIAName) {
233 base::FilePath profile_path_1 = GetProfilePath("path_1");
234 GetCache()->AddProfileToCache(profile_path_1, ASCIIToUTF16("Person 1"),
235 std::string(), base::string16(), false, 0,
236 std::string(), EmptyAccountId());
237 ProfileAttributesEntry* entry_1 = nullptr;
238 GetCache()->GetProfileAttributesWithPath(profile_path_1, &entry_1);
239 base::string16 profile_name(ASCIIToUTF16("Person 2"));
240 base::FilePath profile_path_2 = GetProfilePath("path_2");
241 GetCache()->AddProfileToCache(GetProfilePath("path_2"), profile_name,
242 std::string(), base::string16(), false, 0,
243 std::string(), EmptyAccountId());
244 ProfileAttributesEntry* entry_2 = nullptr;
245 GetCache()->GetProfileAttributesWithPath(profile_path_2, &entry_2);
246
247 // Sanity check.
248 EXPECT_TRUE(entry_1->GetGAIAName().empty());
249 EXPECT_TRUE(entry_2->GetGAIAName().empty());
250
251 // Set GAIA name.
252 base::string16 gaia_name(ASCIIToUTF16("Pat Smith"));
253 entry_2->SetGAIAName(gaia_name);
254 // Since there is a GAIA name, we use that as a display name.
255 EXPECT_TRUE(entry_1->GetGAIAName().empty());
256 EXPECT_EQ(gaia_name, entry_2->GetGAIAName());
257 EXPECT_EQ(gaia_name, entry_2->GetName());
258
259 base::string16 custom_name(ASCIIToUTF16("Custom name"));
260 entry_2->SetLocalProfileName(custom_name);
261 entry_2->SetIsUsingDefaultName(false);
262
263 base::string16 expected_profile_name =
264 GetConcatenation(gaia_name, custom_name);
265 EXPECT_EQ(expected_profile_name, entry_2->GetName());
266 EXPECT_EQ(gaia_name, entry_2->GetGAIAName());
267 }
268
TEST_F(ProfileInfoCacheTest,ConcatenateGaiaNameAndProfileName)269 TEST_F(ProfileInfoCacheTest, ConcatenateGaiaNameAndProfileName) {
270 // We should only append the profile name to the GAIA name if:
271 // - The user has chosen a profile name on purpose.
272 // - Two profiles has the sama GAIA name and we need to show it to
273 // clear ambiguity.
274 // If one of the two conditions hold, we will show the profile name in this
275 // format |GAIA name (Profile local name)|
276 // Single profile.
277 GetCache()->AddProfileToCache(
278 GetProfilePath("path_1"), ASCIIToUTF16("Person 1"), std::string(),
279 base::string16(), false, 0, std::string(), EmptyAccountId());
280 ProfileAttributesEntry* entry_1 = nullptr;
281 GetCache()->GetProfileAttributesWithPath(GetProfilePath("path_1"), &entry_1);
282 EXPECT_EQ(ASCIIToUTF16("Person 1"), entry_1->GetName());
283 entry_1->SetGAIAName(ASCIIToUTF16("Patt Smith"));
284 EXPECT_EQ(ASCIIToUTF16("Patt Smith"), entry_1->GetName());
285 entry_1->SetGAIAGivenName(ASCIIToUTF16("Patt"));
286 EXPECT_EQ(ASCIIToUTF16("Patt"), entry_1->GetName());
287
288 // Set a custom profile name.
289 entry_1->SetIsUsingDefaultName(false);
290 entry_1->SetLocalProfileName(ASCIIToUTF16("Work"));
291 EXPECT_EQ(ASCIIToUTF16("Patt (Work)"), entry_1->GetName());
292
293 // Set the profile name to be equal to GAIA name.
294 entry_1->SetLocalProfileName(ASCIIToUTF16("patt"));
295 EXPECT_EQ(ASCIIToUTF16("Patt"), entry_1->GetName());
296
297 // Multiple profiles.
298 // Add another profile with the same GAIA name and a default profile name.
299 GetCache()->AddProfileToCache(
300 GetProfilePath("path_2"), ASCIIToUTF16("Person 2"), std::string(),
301 base::string16(), false, 0, std::string(), EmptyAccountId());
302 ProfileAttributesEntry* entry_2 = nullptr;
303 GetCache()->GetProfileAttributesWithPath(GetProfilePath("path_2"), &entry_2);
304 EXPECT_EQ(ASCIIToUTF16("Patt"), entry_1->GetName());
305 EXPECT_EQ(ASCIIToUTF16("Person 2"), entry_2->GetName());
306
307 entry_1->SetLocalProfileName(ASCIIToUTF16("Work"));
308 EXPECT_EQ(ASCIIToUTF16("Patt (Work)"), entry_1->GetName());
309 EXPECT_EQ(ASCIIToUTF16("Person 2"), entry_2->GetName());
310
311 // A second profile with a different GAIA name should not affect the first
312 // profile.
313 entry_2->SetGAIAGivenName(ASCIIToUTF16("Olly"));
314 EXPECT_EQ(ASCIIToUTF16("Patt (Work)"), entry_1->GetName());
315 EXPECT_EQ(ASCIIToUTF16("Olly"), entry_2->GetName());
316
317 // Mark profile name as default.
318 entry_1->SetIsUsingDefaultName(true);
319 entry_1->SetLocalProfileName(ASCIIToUTF16("Person 1"));
320 EXPECT_EQ(ASCIIToUTF16("Patt"), entry_1->GetName());
321 EXPECT_EQ(ASCIIToUTF16("Olly"), entry_2->GetName());
322
323 // Add a third profile with the same GAIA name as the first.
324 // The two profiles are marked as using default profile names.
325 GetCache()->AddProfileToCache(
326 GetProfilePath("path_3"), ASCIIToUTF16("Person 3"), std::string(),
327 base::string16(), false, 0, std::string(), EmptyAccountId());
328 ProfileAttributesEntry* entry_3 = nullptr;
329 GetCache()->GetProfileAttributesWithPath(GetProfilePath("path_3"), &entry_3);
330 entry_3->SetGAIAName(ASCIIToUTF16("Patt Smith"));
331 EXPECT_EQ(ASCIIToUTF16("Patt"), entry_1->GetName());
332 EXPECT_EQ(ASCIIToUTF16("Patt Smith"), entry_3->GetName());
333
334 // Two profiles with same GAIA name and default profile name.
335 // Empty GAIA given name.
336 entry_3->SetGAIAName(ASCIIToUTF16("Patt"));
337 EXPECT_EQ(ASCIIToUTF16("Patt (Person 1)"), entry_1->GetName());
338 EXPECT_EQ(ASCIIToUTF16("Patt (Person 3)"), entry_3->GetName());
339 // Set GAIA given name.
340 entry_3->SetGAIAGivenName(ASCIIToUTF16("Patt"));
341 EXPECT_EQ(ASCIIToUTF16("Patt (Person 1)"), entry_1->GetName());
342 EXPECT_EQ(ASCIIToUTF16("Patt (Person 3)"), entry_3->GetName());
343
344 // Customize the profile name for one of the two profiles.
345 entry_3->SetIsUsingDefaultName(false);
346 entry_3->SetLocalProfileName(ASCIIToUTF16("Personal"));
347 EXPECT_EQ(ASCIIToUTF16("Patt"), entry_1->GetName());
348 EXPECT_EQ(ASCIIToUTF16("Patt (Personal)"), entry_3->GetName());
349
350 // Set one of the profile names to be equal to GAIA name, we should show
351 // the profile name even if it is Person n to clear ambiguity.
352 entry_3->SetLocalProfileName(ASCIIToUTF16("patt"));
353 EXPECT_EQ(ASCIIToUTF16("Patt (Person 1)"), entry_1->GetName());
354 EXPECT_EQ(ASCIIToUTF16("Patt"), entry_3->GetName());
355
356 // Never show the profile name if it is equal GAIA name.
357 entry_1->SetLocalProfileName(ASCIIToUTF16("Patt"));
358 EXPECT_EQ(ASCIIToUTF16("Patt"), entry_1->GetName());
359 EXPECT_EQ(ASCIIToUTF16("Patt"), entry_3->GetName());
360 EXPECT_EQ(ASCIIToUTF16("Olly"), entry_2->GetName());
361 }
362
TEST_F(ProfileInfoCacheTest,DeleteProfile)363 TEST_F(ProfileInfoCacheTest, DeleteProfile) {
364 EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
365
366 base::FilePath path_1 = GetProfilePath("path_1");
367 GetCache()->AddProfileToCache(path_1, ASCIIToUTF16("name_1"), std::string(),
368 base::string16(), false, 0, std::string(),
369 EmptyAccountId());
370 EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles());
371
372 base::FilePath path_2 = GetProfilePath("path_2");
373 base::string16 name_2 = ASCIIToUTF16("name_2");
374 GetCache()->AddProfileToCache(path_2, name_2, std::string(), base::string16(),
375 false, 0, std::string(), EmptyAccountId());
376 ProfileAttributesEntry* entry = nullptr;
377 GetCache()->GetProfileAttributesWithPath(path_2, &entry);
378 EXPECT_EQ(2u, GetCache()->GetNumberOfProfiles());
379
380 GetCache()->DeleteProfileFromCache(path_1);
381 EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles());
382 EXPECT_EQ(name_2, entry->GetName());
383
384 GetCache()->DeleteProfileFromCache(path_2);
385 EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
386 }
387
TEST_F(ProfileInfoCacheTest,MutateProfile)388 TEST_F(ProfileInfoCacheTest, MutateProfile) {
389 base::FilePath profile_path_1 = GetProfilePath("path_1");
390 GetCache()->AddProfileToCache(profile_path_1, ASCIIToUTF16("name_1"),
391 std::string(), base::string16(), false, 0,
392 std::string(), EmptyAccountId());
393
394 base::FilePath profile_path_2 = GetProfilePath("path_2");
395 GetCache()->AddProfileToCache(profile_path_2, ASCIIToUTF16("name_2"),
396 std::string(), base::string16(), false, 0,
397 std::string(), EmptyAccountId());
398 ProfileAttributesEntry* entry_1;
399 GetCache()->GetProfileAttributesWithPath(profile_path_1, &entry_1);
400 ProfileAttributesEntry* entry_2;
401 GetCache()->GetProfileAttributesWithPath(profile_path_2, &entry_2);
402
403 base::string16 new_name = ASCIIToUTF16("new_name");
404 entry_2->SetLocalProfileName(new_name);
405 EXPECT_EQ(new_name, entry_2->GetName());
406 EXPECT_NE(new_name, entry_1->GetName());
407
408 base::string16 new_user_name = ASCIIToUTF16("user_name");
409 std::string new_gaia_id = "12345";
410 entry_2->SetAuthInfo(new_gaia_id, new_user_name, true);
411 EXPECT_EQ(new_user_name, entry_2->GetUserName());
412 EXPECT_EQ(new_gaia_id, entry_2->GetGAIAId());
413 EXPECT_NE(new_user_name, entry_1->GetUserName());
414
415 // Avatar icons not used on Android.
416 #if !defined(OS_ANDROID)
417 const size_t new_icon_index = 3;
418 GetCache()->SetAvatarIconOfProfileAtIndex(1, new_icon_index);
419 EXPECT_EQ(new_icon_index, GetCache()->GetAvatarIconIndexOfProfileAtIndex(1));
420
421 const size_t wrong_icon_index = profiles::GetDefaultAvatarIconCount() + 1;
422 const size_t generic_icon_index = 0;
423 GetCache()->SetAvatarIconOfProfileAtIndex(1, wrong_icon_index);
424 EXPECT_EQ(generic_icon_index,
425 GetCache()->GetAvatarIconIndexOfProfileAtIndex(1));
426 #endif
427 }
428
429 // Will be removed SOON with ProfileInfoCache tests.
TEST_F(ProfileInfoCacheTest,BackgroundModeStatus)430 TEST_F(ProfileInfoCacheTest, BackgroundModeStatus) {
431 base::FilePath path_1 = GetProfilePath("path_1");
432 base::FilePath path_2 = GetProfilePath("path_2");
433 GetCache()->AddProfileToCache(path_1, ASCIIToUTF16("name_1"), std::string(),
434 base::string16(), false, 0, std::string(),
435 EmptyAccountId());
436 GetCache()->AddProfileToCache(path_2, ASCIIToUTF16("name_2"), std::string(),
437 base::string16(), false, 0, std::string(),
438 EmptyAccountId());
439
440 ProfileAttributesEntry* entry_1 = nullptr;
441 GetCache()->GetProfileAttributesWithPath(path_1, &entry_1);
442 ProfileAttributesEntry* entry_2 = nullptr;
443 GetCache()->GetProfileAttributesWithPath(path_2, &entry_2);
444 EXPECT_FALSE(entry_1->GetBackgroundStatus());
445 EXPECT_FALSE(entry_2->GetBackgroundStatus());
446
447 entry_2->SetBackgroundStatus(true);
448
449 EXPECT_FALSE(entry_1->GetBackgroundStatus());
450 EXPECT_TRUE(entry_2->GetBackgroundStatus());
451
452 entry_1->SetBackgroundStatus(true);
453
454 EXPECT_TRUE(entry_1->GetBackgroundStatus());
455 EXPECT_TRUE(entry_2->GetBackgroundStatus());
456
457 entry_2->SetBackgroundStatus(false);
458
459 EXPECT_TRUE(entry_1->GetBackgroundStatus());
460 EXPECT_FALSE(entry_2->GetBackgroundStatus());
461 }
462
TEST_F(ProfileInfoCacheTest,GAIAPicture)463 TEST_F(ProfileInfoCacheTest, GAIAPicture) {
464 const int kDefaultAvatarIndex = 0;
465 const int kOtherAvatarIndex = 1;
466 const int kGaiaPictureSize = 256; // Standard size of a Gaia account picture.
467 base::FilePath path_2 = GetProfilePath("path_2");
468 GetCache()->AddProfileToCache(GetProfilePath("path_1"),
469 ASCIIToUTF16("name_1"), std::string(),
470 base::string16(), false, kDefaultAvatarIndex,
471 std::string(), EmptyAccountId());
472 GetCache()->AddProfileToCache(path_2, ASCIIToUTF16("name_2"), std::string(),
473 base::string16(), false, kDefaultAvatarIndex,
474 std::string(), EmptyAccountId());
475 ProfileAttributesEntry* entry = nullptr;
476 GetCache()->GetProfileAttributesWithPath(path_2, &entry);
477
478 // Sanity check.
479 EXPECT_EQ(NULL, GetCache()->GetGAIAPictureOfProfileAtIndex(0));
480 EXPECT_EQ(NULL, GetCache()->GetGAIAPictureOfProfileAtIndex(1));
481 EXPECT_FALSE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(0));
482 EXPECT_FALSE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(1));
483
484 // The profile icon should be the default one.
485 EXPECT_TRUE(GetCache()->ProfileIsUsingDefaultAvatarAtIndex(0));
486 EXPECT_TRUE(GetCache()->ProfileIsUsingDefaultAvatarAtIndex(1));
487 size_t default_avatar_id =
488 GetDefaultAvatarIconResourceIDAtIndex(kDefaultAvatarIndex);
489 const gfx::Image& default_avatar_image(
490 ui::ResourceBundle::GetSharedInstance().GetImageNamed(default_avatar_id));
491 EXPECT_TRUE(
492 gfx::test::AreImagesEqual(default_avatar_image, entry->GetAvatarIcon()));
493
494 // Set GAIA picture.
495 gfx::Image gaia_image(gfx::test::CreateImage(
496 kGaiaPictureSize, kGaiaPictureSize));
497 GetCache()->SetGAIAPictureOfProfileAtIndex(1, "GAIA_IMAGE_URL_WITH_SIZE_1",
498 gaia_image);
499 EXPECT_EQ(nullptr, GetCache()->GetGAIAPictureOfProfileAtIndex(0));
500 EXPECT_TRUE(gfx::test::AreImagesEqual(
501 gaia_image, *GetCache()->GetGAIAPictureOfProfileAtIndex(1)));
502 // Since we're still using the default avatar, the GAIA image should be
503 // preferred over the generic avatar image.
504 EXPECT_TRUE(GetCache()->ProfileIsUsingDefaultAvatarAtIndex(1));
505 EXPECT_TRUE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(1));
506 EXPECT_TRUE(gfx::test::AreImagesEqual(gaia_image, entry->GetAvatarIcon()));
507
508 // Set a non-default avatar. This should be preferred over the GAIA image.
509 GetCache()->SetAvatarIconOfProfileAtIndex(1, kOtherAvatarIndex);
510 GetCache()->SetProfileIsUsingDefaultAvatarAtIndex(1, false);
511 EXPECT_FALSE(GetCache()->ProfileIsUsingDefaultAvatarAtIndex(1));
512 EXPECT_FALSE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(1));
513 // Avatar icons not used on Android.
514 #if !defined(OS_ANDROID)
515
516 size_t other_avatar_id =
517 GetDefaultAvatarIconResourceIDAtIndex(kOtherAvatarIndex);
518 const gfx::Image& other_avatar_image(
519 ui::ResourceBundle::GetSharedInstance().GetImageNamed(other_avatar_id));
520 EXPECT_TRUE(
521 gfx::test::AreImagesEqual(other_avatar_image, entry->GetAvatarIcon()));
522 #endif // !defined(OS_ANDROID)
523
524 // Explicitly setting the GAIA picture should make it preferred again.
525 GetCache()->SetIsUsingGAIAPictureOfProfileAtIndex(1, true);
526 EXPECT_TRUE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(1));
527 EXPECT_TRUE(gfx::test::AreImagesEqual(
528 gaia_image, *GetCache()->GetGAIAPictureOfProfileAtIndex(1)));
529 EXPECT_TRUE(gfx::test::AreImagesEqual(gaia_image, entry->GetAvatarIcon()));
530
531 // Clearing the IsUsingGAIAPicture flag should result in the generic image
532 // being used again.
533 GetCache()->SetIsUsingGAIAPictureOfProfileAtIndex(1, false);
534 EXPECT_FALSE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(1));
535 EXPECT_TRUE(gfx::test::AreImagesEqual(
536 gaia_image, *GetCache()->GetGAIAPictureOfProfileAtIndex(1)));
537 #if !defined(OS_ANDROID)
538 EXPECT_TRUE(
539 gfx::test::AreImagesEqual(other_avatar_image, entry->GetAvatarIcon()));
540 #endif
541 }
542
TEST_F(ProfileInfoCacheTest,PersistGAIAPicture)543 TEST_F(ProfileInfoCacheTest, PersistGAIAPicture) {
544 GetCache()->AddProfileToCache(
545 GetProfilePath("path_1"), ASCIIToUTF16("name_1"), std::string(),
546 base::string16(), false, 0, std::string(), EmptyAccountId());
547 gfx::Image gaia_image(gfx::test::CreateImage());
548
549 GetCache()->SetGAIAPictureOfProfileAtIndex(0, "GAIA_IMAGE_URL_WITH_SIZE_0",
550 gaia_image);
551
552 // Make sure everything has completed, and the file has been written to disk.
553 content::RunAllTasksUntilIdle();
554
555 EXPECT_EQ(
556 GetCache()->GetLastDownloadedGAIAPictureUrlWithSizeOfProfileAtIndex(0),
557 "GAIA_IMAGE_URL_WITH_SIZE_0");
558 EXPECT_TRUE(gfx::test::AreImagesEqual(
559 gaia_image, *GetCache()->GetGAIAPictureOfProfileAtIndex(0)));
560
561 ResetCache();
562 // Try to get the GAIA picture. This should return NULL until the read from
563 // disk is done.
564 EXPECT_EQ(nullptr, GetCache()->GetGAIAPictureOfProfileAtIndex(0));
565 EXPECT_EQ(
566 GetCache()->GetLastDownloadedGAIAPictureUrlWithSizeOfProfileAtIndex(0),
567 "GAIA_IMAGE_URL_WITH_SIZE_0");
568 content::RunAllTasksUntilIdle();
569
570 EXPECT_TRUE(gfx::test::AreImagesEqual(
571 gaia_image, *GetCache()->GetGAIAPictureOfProfileAtIndex(0)));
572 }
573
574 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
TEST_F(ProfileInfoCacheTest,SetSupervisedUserId)575 TEST_F(ProfileInfoCacheTest, SetSupervisedUserId) {
576 base::FilePath profile_path = GetProfilePath("test");
577 GetCache()->AddProfileToCache(profile_path, ASCIIToUTF16("Test"),
578 std::string(), base::string16(), false, 0,
579 std::string(), EmptyAccountId());
580 ProfileAttributesEntry* entry = nullptr;
581 GetCache()->GetProfileAttributesWithPath(profile_path, &entry);
582 EXPECT_FALSE(entry->IsSupervised());
583
584 entry->SetSupervisedUserId(supervised_users::kChildAccountSUID);
585 EXPECT_TRUE(entry->IsSupervised());
586 EXPECT_EQ(supervised_users::kChildAccountSUID, entry->GetSupervisedUserId());
587
588 ResetCache();
589 entry = nullptr;
590 GetCache()->GetProfileAttributesWithPath(profile_path, &entry);
591 EXPECT_TRUE(entry->IsSupervised());
592
593 entry->SetSupervisedUserId(std::string());
594 EXPECT_FALSE(entry->IsSupervised());
595 EXPECT_EQ("", entry->GetSupervisedUserId());
596 }
597 #endif // BUILDFLAG(ENABLE_SUPERVISED_USERS)
598
TEST_F(ProfileInfoCacheTest,EmptyGAIAInfo)599 TEST_F(ProfileInfoCacheTest, EmptyGAIAInfo) {
600 base::string16 profile_name = ASCIIToUTF16("name_1");
601 size_t id = GetDefaultAvatarIconResourceIDAtIndex(0);
602 const gfx::Image& profile_image(
603 ui::ResourceBundle::GetSharedInstance().GetImageNamed(id));
604
605 base::FilePath profile_path = GetProfilePath("path_1");
606 GetCache()->AddProfileToCache(profile_path, profile_name, std::string(),
607 base::string16(), false, 0, std::string(),
608 EmptyAccountId());
609
610 ProfileAttributesEntry* entry = nullptr;
611 GetCache()->GetProfileAttributesWithPath(profile_path, &entry);
612
613 gfx::Image gaia_image(gfx::test::CreateImage());
614 GetCache()->SetGAIAPictureOfProfileAtIndex(0, "GAIA_IMAGE_URL_WITH_SIZE_0",
615 gaia_image);
616
617 // Make sure everything has completed, and the file has been written to disk.
618 content::RunAllTasksUntilIdle();
619
620 // Set empty GAIA info.
621 entry->SetGAIAName(base::string16());
622 GetCache()->SetGAIAPictureOfProfileAtIndex(0, std::string(), gfx::Image());
623 GetCache()->SetIsUsingGAIAPictureOfProfileAtIndex(0, true);
624
625 EXPECT_TRUE(GetCache()
626 ->GetLastDownloadedGAIAPictureUrlWithSizeOfProfileAtIndex(0)
627 .empty());
628
629 // Verify that the profile name and picture are not empty.
630 EXPECT_EQ(profile_name, entry->GetName());
631 EXPECT_TRUE(gfx::test::AreImagesEqual(profile_image, entry->GetAvatarIcon()));
632 }
633
634 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
TEST_F(ProfileInfoCacheTest,CreateSupervisedTestingProfile)635 TEST_F(ProfileInfoCacheTest, CreateSupervisedTestingProfile) {
636 base::FilePath path_1 =
637 testing_profile_manager_.CreateTestingProfile("default")->GetPath();
638 base::string16 supervised_user_name = ASCIIToUTF16("Supervised User");
639 base::FilePath path_2 =
640 testing_profile_manager_
641 .CreateTestingProfile(
642 "test1", std::unique_ptr<sync_preferences::PrefServiceSyncable>(),
643 supervised_user_name, 0, supervised_users::kChildAccountSUID,
644 TestingProfile::TestingFactories())
645 ->GetPath();
646 base::FilePath profile_path[] = {path_1, path_2};
647 for (const base::FilePath& path : profile_path) {
648 ProfileAttributesEntry* entry = nullptr;
649 GetCache()->GetProfileAttributesWithPath(path, &entry);
650 bool is_supervised = entry->GetName() == supervised_user_name;
651 EXPECT_EQ(is_supervised, entry->IsSupervised());
652 std::string supervised_user_id =
653 is_supervised ? supervised_users::kChildAccountSUID : "";
654 EXPECT_EQ(supervised_user_id, entry->GetSupervisedUserId());
655 }
656
657 // Supervised profiles have a custom theme, which needs to be deleted on the
658 // FILE thread. Reset the profile manager now so everything is deleted while
659 // we still have a FILE thread.
660 TestingBrowserProcess::GetGlobal()->SetProfileManager(NULL);
661 }
662 #endif
663
TEST_F(ProfileInfoCacheTest,AddStubProfile)664 TEST_F(ProfileInfoCacheTest, AddStubProfile) {
665 EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
666
667 // Add some profiles with and without a '.' in their paths.
668 const struct {
669 const char* profile_path;
670 const char* profile_name;
671 } kTestCases[] = {
672 { "path.test0", "name_0" },
673 { "path_test1", "name_1" },
674 { "path.test2", "name_2" },
675 { "path_test3", "name_3" },
676 };
677
678 for (size_t i = 0; i < base::size(kTestCases); ++i) {
679 base::FilePath profile_path = GetProfilePath(kTestCases[i].profile_path);
680 base::string16 profile_name = ASCIIToUTF16(kTestCases[i].profile_name);
681
682 GetCache()->AddProfileToCache(profile_path, profile_name, std::string(),
683 base::string16(), false, i, "",
684 EmptyAccountId());
685 ProfileAttributesEntry* entry = nullptr;
686 GetCache()->GetProfileAttributesWithPath(profile_path, &entry);
687 EXPECT_TRUE(entry);
688 EXPECT_EQ(profile_name, entry->GetName());
689 }
690
691 ASSERT_EQ(4U, GetCache()->GetNumberOfProfiles());
692
693 // Check that the profiles can be extracted from the local state.
694 std::vector<base::string16> names;
695 PrefService* local_state = g_browser_process->local_state();
696 const base::DictionaryValue* cache = local_state->GetDictionary(
697 prefs::kProfileInfoCache);
698 base::string16 name;
699 for (base::DictionaryValue::Iterator it(*cache); !it.IsAtEnd();
700 it.Advance()) {
701 const base::DictionaryValue* info = NULL;
702 it.value().GetAsDictionary(&info);
703 info->GetString("name", &name);
704 names.push_back(name);
705 }
706
707 for (size_t i = 0; i < 4; i++)
708 ASSERT_FALSE(names[i].empty());
709 }
710
TEST_F(ProfileInfoCacheTest,EntriesInAttributesStorage)711 TEST_F(ProfileInfoCacheTest, EntriesInAttributesStorage) {
712 EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
713
714 // Add some profiles with and without a '.' in their paths.
715 const struct {
716 const char* profile_path;
717 const char* profile_name;
718 } kTestCases[] = {
719 { "path.test0", "name_0" },
720 { "path_test1", "name_1" },
721 { "path.test2", "name_2" },
722 { "path_test3", "name_3" },
723 };
724
725 // Profiles are added and removed using all combinations of the old and the
726 // new interfaces. The content of |profile_attributes_entries_| in
727 // ProfileAttributesStorage is checked after each insert and delete operation.
728
729 // Add profiles.
730 for (size_t i = 0; i < base::size(kTestCases); ++i) {
731 base::FilePath profile_path = GetProfilePath(kTestCases[i].profile_path);
732 base::string16 profile_name = ASCIIToUTF16(kTestCases[i].profile_name);
733
734 ASSERT_EQ(0u, GetCache()->profile_attributes_entries_.count(
735 profile_path.value()));
736
737 // Use ProfileInfoCache in profiles 0 and 2, and ProfileAttributesStorage in
738 // profiles 1 and 3.
739 if (i == 0 || i == 2) {
740 GetCache()->AddProfileToCache(profile_path, profile_name, std::string(),
741 base::string16(), false, i, "",
742 EmptyAccountId());
743 } else {
744 GetCache()->AddProfile(profile_path, profile_name, std::string(),
745 base::string16(), false, i, "", EmptyAccountId());
746 }
747
748 ASSERT_EQ(i + 1, GetCache()->GetNumberOfProfiles());
749 ASSERT_EQ(i + 1, GetCache()->profile_attributes_entries_.size());
750
751 ASSERT_EQ(1u, GetCache()->profile_attributes_entries_.count(
752 profile_path.value()));
753 // TODO(anthonyvd) : check that the entry in |profile_attributes_entries_|
754 // is null before GetProfileAttributesWithPath is run. Currently this is
755 // impossible to check because GetProfileAttributesWithPath is called during
756 // profile creation.
757
758 ProfileAttributesEntry* entry = nullptr;
759 GetCache()->GetProfileAttributesWithPath(profile_path, &entry);
760 EXPECT_EQ(
761 entry,
762 GetCache()->profile_attributes_entries_[profile_path.value()].get());
763 }
764
765 // Remove profiles.
766 for (size_t i = 0; i < base::size(kTestCases); ++i) {
767 base::FilePath profile_path = GetProfilePath(kTestCases[i].profile_path);
768 ASSERT_EQ(1u, GetCache()->profile_attributes_entries_.count(
769 profile_path.value()));
770
771 // Use ProfileInfoCache in profiles 0 and 1, and ProfileAttributesStorage in
772 // profiles 2 and 3.
773 if (i == 0 || i == 1)
774 GetCache()->DeleteProfileFromCache(profile_path);
775 else
776 GetCache()->RemoveProfile(profile_path);
777
778 ASSERT_EQ(0u, GetCache()->profile_attributes_entries_.count(
779 profile_path.value()));
780
781 ProfileAttributesEntry* entry = nullptr;
782 EXPECT_FALSE(GetCache()->GetProfileAttributesWithPath(profile_path,
783 &entry));
784 ASSERT_EQ(0u, GetCache()->profile_attributes_entries_.count(
785 profile_path.value()));
786 }
787 }
788
789 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
TEST_F(ProfileInfoCacheTest,MigrateLegacyProfileNamesAndRecomputeIfNeeded)790 TEST_F(ProfileInfoCacheTest, MigrateLegacyProfileNamesAndRecomputeIfNeeded) {
791 EXPECT_EQ(0U, GetCache()->GetNumberOfProfiles());
792 // Mimick a pre-existing Directory with profiles that has legacy profile
793 // names.
794 const struct {
795 const char* profile_path;
796 const char* profile_name;
797 bool is_using_default_name;
798 } kTestCases[] = {
799 {"path_1", "Default Profile", true}, {"path_2", "First user", true},
800 {"path_3", "Lemonade", true}, {"path_4", "Batman", true},
801 {"path_5", "Batman", false}, {"path_6", "Person 2", true},
802 {"path_7", "Person 3", true}, {"path_8", "Person 1", true},
803 {"path_9", "Person 2", true}, {"path_10", "Person 1", true},
804 {"path_11", "Smith", false}, {"path_12", "Person 2", true}};
805
806 ProfileAttributesEntry* entry = nullptr;
807 for (size_t i = 0; i < base::size(kTestCases); ++i) {
808 base::FilePath profile_path = GetProfilePath(kTestCases[i].profile_path);
809 base::string16 profile_name = ASCIIToUTF16(kTestCases[i].profile_name);
810 entry = nullptr;
811
812 GetCache()->AddProfileToCache(profile_path, profile_name, std::string(),
813 base::string16(), false, i, "",
814 EmptyAccountId());
815 GetCache()->GetProfileAttributesWithPath(profile_path, &entry);
816 EXPECT_TRUE(entry);
817 entry->SetIsUsingDefaultName(kTestCases[i].is_using_default_name);
818 }
819
820 EXPECT_EQ(12U, GetCache()->GetNumberOfProfiles());
821
822 ResetCache();
823 ProfileInfoCache::SetLegacyProfileMigrationForTesting(true);
824 GetCache();
825 ProfileInfoCache::SetLegacyProfileMigrationForTesting(false);
826
827 entry = nullptr;
828 GetCache()->GetProfileAttributesWithPath(
829 GetProfilePath(kTestCases[4].profile_path), &entry);
830 EXPECT_EQ(ASCIIToUTF16(kTestCases[4].profile_name), entry->GetName());
831 GetCache()->GetProfileAttributesWithPath(
832 GetProfilePath(kTestCases[10].profile_path), &entry);
833 EXPECT_EQ(ASCIIToUTF16(kTestCases[10].profile_name), entry->GetName());
834
835 // Legacy profile names like "Default Profile" and "First user" should be
836 // migrated to "Person %n" type names, i.e. any permutation of "Person %n".
837 std::set<base::string16> expected_profile_names{
838 ASCIIToUTF16("Person 1"), ASCIIToUTF16("Person 2"),
839 ASCIIToUTF16("Person 3"), ASCIIToUTF16("Person 4"),
840 ASCIIToUTF16("Person 5"), ASCIIToUTF16("Person 6"),
841 ASCIIToUTF16("Person 7"), ASCIIToUTF16("Person 8"),
842 ASCIIToUTF16("Person 9"), ASCIIToUTF16("Person 10")};
843
844 const char* profile_path[] = {
845 kTestCases[0].profile_path, kTestCases[1].profile_path,
846 kTestCases[2].profile_path, kTestCases[3].profile_path,
847 kTestCases[5].profile_path, kTestCases[6].profile_path,
848 kTestCases[7].profile_path, kTestCases[8].profile_path,
849 kTestCases[9].profile_path, kTestCases[11].profile_path};
850
851 std::set<base::string16> actual_profile_names;
852 for (auto* path : profile_path) {
853 entry = nullptr;
854 GetCache()->GetProfileAttributesWithPath(GetProfilePath(path), &entry);
855 actual_profile_names.insert(entry->GetName());
856 }
857 EXPECT_EQ(actual_profile_names, expected_profile_names);
858 }
859
TEST_F(ProfileInfoCacheTest,GetGaiaImageForAvatarMenu)860 TEST_F(ProfileInfoCacheTest, GetGaiaImageForAvatarMenu) {
861 // The TestingProfileManager's ProfileInfoCache doesn't download avatars.
862 ProfileInfoCache profile_info_cache(
863 g_browser_process->local_state(),
864 testing_profile_manager_.profile_manager()->user_data_dir());
865
866 base::FilePath profile_path = GetProfilePath("path_1");
867
868 GetCache()->AddProfileToCache(profile_path, ASCIIToUTF16("name_1"),
869 std::string(), base::string16(), false, 0,
870 std::string(), EmptyAccountId());
871
872 gfx::Image gaia_image(gfx::test::CreateImage());
873 GetCache()->SetGAIAPictureOfProfileAtIndex(0, "GAIA_IMAGE_URL_WITH_SIZE_0",
874 gaia_image);
875
876 // Make sure everything has completed, and the file has been written to disk.
877 content::RunAllTasksUntilIdle();
878
879 // Make sure this profile is using GAIA picture.
880 EXPECT_TRUE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(0));
881
882 ResetCache();
883
884 // We need to explicitly set the GAIA usage flag after resetting the cache.
885 GetCache()->SetIsUsingGAIAPictureOfProfileAtIndex(0, true);
886 EXPECT_TRUE(GetCache()->IsUsingGAIAPictureOfProfileAtIndex(0));
887
888 gfx::Image image_loaded;
889
890 // Try to get the GAIA image. For the first time, it triggers an async image
891 // load from disk. The load status indicates the image is still being loaded.
892 constexpr int kArbitraryPreferredSize = 96;
893 EXPECT_EQ(AvatarMenu::ImageLoadStatus::LOADING,
894 AvatarMenu::GetImageForMenuButton(profile_path, &image_loaded,
895 kArbitraryPreferredSize));
896 EXPECT_FALSE(gfx::test::AreImagesEqual(gaia_image, image_loaded));
897
898 // Wait until the async image load finishes.
899 content::RunAllTasksUntilIdle();
900
901 // Since the GAIA image is loaded now, we can get it this time.
902 EXPECT_EQ(AvatarMenu::ImageLoadStatus::LOADED,
903 AvatarMenu::GetImageForMenuButton(profile_path, &image_loaded,
904 kArbitraryPreferredSize));
905 EXPECT_TRUE(gfx::test::AreImagesEqual(gaia_image, image_loaded));
906 }
907 #endif
908
909 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
TEST_F(ProfileInfoCacheTest,DontMigrateLegacyProfileNamesWithoutNewAvatarMenu)910 TEST_F(ProfileInfoCacheTest,
911 DontMigrateLegacyProfileNamesWithoutNewAvatarMenu) {
912 EXPECT_EQ(0U, GetCache()->GetNumberOfProfiles());
913
914 const struct {
915 const char* profile_path;
916 const char* profile_name;
917 } kTestCases[] = {{"path_1", "Default Profile"},
918 {"path_2", "First user"},
919 {"path_3", "Lemonade"},
920 {"path_4", "Batman"}};
921
922 for (size_t i = 0; i < base::size(kTestCases); ++i) {
923 base::FilePath profile_path = GetProfilePath(kTestCases[i].profile_path);
924 base::string16 profile_name = ASCIIToUTF16(kTestCases[i].profile_name);
925 ProfileAttributesEntry* entry = nullptr;
926 GetCache()->AddProfileToCache(profile_path, profile_name, std::string(),
927 base::string16(), false, i, "",
928 EmptyAccountId());
929 GetCache()->GetProfileAttributesWithPath(profile_path, &entry);
930 EXPECT_TRUE(entry);
931 entry->SetIsUsingDefaultName(true);
932 }
933 EXPECT_EQ(4U, GetCache()->GetNumberOfProfiles());
934
935 ResetCache();
936
937 // Profile names should have been preserved.
938 for (size_t i = 0; i < base::size(kTestCases); ++i) {
939 base::FilePath profile_path = GetProfilePath(kTestCases[i].profile_path);
940 base::string16 profile_name = ASCIIToUTF16(kTestCases[i].profile_name);
941 ProfileAttributesEntry* entry = nullptr;
942 GetCache()->GetProfileAttributesWithPath(profile_path, &entry);
943 EXPECT_TRUE(entry);
944 EXPECT_EQ(profile_name, entry->GetName());
945 }
946 }
947 #endif
948
TEST_F(ProfileInfoCacheTest,RemoveProfileByAccountId)949 TEST_F(ProfileInfoCacheTest, RemoveProfileByAccountId) {
950 EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
951 const struct {
952 const char* profile_path;
953 const char* profile_name;
954 AccountId account_id;
955 bool is_consented_primary_account;
956 } kTestCases[] = {
957 {"path_1", "name_1", AccountId::FromUserEmailGaiaId("email1", "111111"),
958 true},
959 {"path_2", "name_3", AccountId::FromUserEmailGaiaId("email2", "222222"),
960 true},
961 {"path_3", "name_3", AccountId::FromUserEmailGaiaId("email3", "333333"),
962 false},
963 {"path_4", "name_4", AccountId::FromUserEmailGaiaId("email4", "444444"),
964 false}};
965
966 for (size_t i = 0; i < base::size(kTestCases); ++i) {
967 base::FilePath profile_path = GetProfilePath(kTestCases[i].profile_path);
968 base::string16 profile_name = ASCIIToUTF16(kTestCases[i].profile_name);
969 GetCache()->AddProfileToCache(
970 profile_path, profile_name, kTestCases[i].account_id.GetGaiaId(),
971 UTF8ToUTF16(kTestCases[i].account_id.GetUserEmail()),
972 kTestCases[i].is_consented_primary_account, 0, std::string(),
973 EmptyAccountId());
974 EXPECT_EQ(i + 1, GetCache()->GetNumberOfProfiles());
975 }
976
977 GetCache()->RemoveProfileByAccountId(kTestCases[2].account_id);
978 EXPECT_EQ(3u, GetCache()->GetNumberOfProfiles());
979
980 GetCache()->RemoveProfileByAccountId(kTestCases[0].account_id);
981 EXPECT_EQ(2u, GetCache()->GetNumberOfProfiles());
982
983 // this profile is already deleted.
984 GetCache()->RemoveProfileByAccountId(kTestCases[2].account_id);
985 EXPECT_EQ(2u, GetCache()->GetNumberOfProfiles());
986
987 // Remove profile by partial match
988 GetCache()->RemoveProfileByAccountId(
989 AccountId::FromUserEmail(kTestCases[1].account_id.GetUserEmail()));
990 EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles());
991
992 // Remove last profile
993 GetCache()->RemoveProfileByAccountId(kTestCases[3].account_id);
994 EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
995 }
996