Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / login / user_image_manager_browsertest.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 <map>
6 #include <string>
7 #include <vector>
8
9 #include "base/basictypes.h"
10 #include "base/compiler_specific.h"
11 #include "base/file_util.h"
12 #include "base/files/file_path.h"
13 #include "base/json/json_writer.h"
14 #include "base/memory/linked_ptr.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/memory/ref_counted_memory.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/message_loop/message_loop_proxy.h"
19 #include "base/path_service.h"
20 #include "base/prefs/pref_change_registrar.h"
21 #include "base/prefs/pref_service.h"
22 #include "base/prefs/scoped_user_pref_update.h"
23 #include "base/run_loop.h"
24 #include "base/time/time.h"
25 #include "base/values.h"
26 #include "chrome/browser/browser_process.h"
27 #include "chrome/browser/chrome_notification_types.h"
28 #include "chrome/browser/chromeos/login/default_user_images.h"
29 #include "chrome/browser/chromeos/login/login_manager_test.h"
30 #include "chrome/browser/chromeos/login/mock_user_manager.h"
31 #include "chrome/browser/chromeos/login/startup_utils.h"
32 #include "chrome/browser/chromeos/login/user.h"
33 #include "chrome/browser/chromeos/login/user_image.h"
34 #include "chrome/browser/chromeos/login/user_image_manager.h"
35 #include "chrome/browser/chromeos/login/user_image_manager_impl.h"
36 #include "chrome/browser/chromeos/login/user_image_manager_test_util.h"
37 #include "chrome/browser/chromeos/login/user_manager.h"
38 #include "chrome/browser/chromeos/policy/cloud_external_data_manager_base_test_util.h"
39 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
40 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h"
41 #include "chrome/browser/profiles/profile.h"
42 #include "chrome/browser/profiles/profile_downloader.h"
43 #include "chrome/common/chrome_paths.h"
44 #include "chrome/test/base/in_process_browser_test.h"
45 #include "chrome/test/base/testing_browser_process.h"
46 #include "chromeos/chromeos_paths.h"
47 #include "chromeos/dbus/cryptohome_client.h"
48 #include "chromeos/dbus/dbus_thread_manager.h"
49 #include "chromeos/dbus/fake_dbus_thread_manager.h"
50 #include "chromeos/dbus/fake_session_manager_client.h"
51 #include "chromeos/dbus/session_manager_client.h"
52 #include "components/policy/core/common/cloud/cloud_policy_core.h"
53 #include "components/policy/core/common/cloud/cloud_policy_store.h"
54 #include "components/policy/core/common/cloud/policy_builder.h"
55 #include "content/public/browser/notification_service.h"
56 #include "content/public/browser/notification_source.h"
57 #include "content/public/test/test_utils.h"
58 #include "crypto/rsa_private_key.h"
59 #include "google_apis/gaia/gaia_oauth_client.h"
60 #include "google_apis/gaia/oauth2_token_service.h"
61 #include "net/test/embedded_test_server/embedded_test_server.h"
62 #include "net/url_request/test_url_fetcher_factory.h"
63 #include "net/url_request/url_fetcher_delegate.h"
64 #include "net/url_request/url_request_status.h"
65 #include "policy/proto/cloud_policy.pb.h"
66 #include "testing/gtest/include/gtest/gtest.h"
67 #include "third_party/skia/include/core/SkBitmap.h"
68 #include "ui/base/layout.h"
69 #include "ui/base/resource/resource_bundle.h"
70 #include "ui/gfx/image/image_skia.h"
71 #include "url/gurl.h"
72
73 namespace chromeos {
74
75 namespace {
76
77 const char kTestUser1[] = "test-user@example.com";
78 const char kTestUser2[] = "test-user2@example.com";
79
80 policy::CloudPolicyStore* GetStoreForUser(const User* user) {
81   Profile* profile = UserManager::Get()->GetProfileByUser(user);
82   if (!profile) {
83     ADD_FAILURE();
84     return NULL;
85   }
86   policy::UserCloudPolicyManagerChromeOS* policy_manager =
87       policy::UserCloudPolicyManagerFactoryChromeOS::GetForProfile(profile);
88   if (!policy_manager) {
89     ADD_FAILURE();
90     return NULL;
91   }
92   return policy_manager->core()->store();
93 }
94
95 }  // namespace
96
97 class UserImageManagerTest : public LoginManagerTest,
98                              public UserManager::Observer {
99  protected:
100   UserImageManagerTest() : LoginManagerTest(true) {
101   }
102
103   // LoginManagerTest overrides:
104   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
105     LoginManagerTest::SetUpInProcessBrowserTestFixture();
106
107     ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_));
108     ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir_));
109   }
110
111   virtual void SetUpOnMainThread() OVERRIDE {
112     LoginManagerTest::SetUpOnMainThread();
113     local_state_ = g_browser_process->local_state();
114     UserManager::Get()->AddObserver(this);
115   }
116
117   virtual void TearDownOnMainThread() OVERRIDE {
118     UserManager::Get()->RemoveObserver(this);
119     LoginManagerTest::TearDownOnMainThread();
120   }
121
122   // UserManager::Observer overrides:
123   virtual void LocalStateChanged(UserManager* user_manager) OVERRIDE {
124     if (run_loop_)
125       run_loop_->Quit();
126   }
127
128   // Logs in |username|.
129   void LogIn(const std::string& username) {
130     UserManager::Get()->UserLoggedIn(username, username, false);
131   }
132
133   // Stores old (pre-migration) user image info.
134   void SetOldUserImageInfo(const std::string& username,
135                            int image_index,
136                            const base::FilePath& image_path) {
137     RegisterUser(username);
138     DictionaryPrefUpdate images_pref(local_state_, "UserImages");
139     base::DictionaryValue* image_properties = new base::DictionaryValue();
140     image_properties->Set(
141         "index", base::Value::CreateIntegerValue(image_index));
142     image_properties->Set(
143         "path" , new base::StringValue(image_path.value()));
144     images_pref->SetWithoutPathExpansion(username, image_properties);
145   }
146
147   // Verifies user image info in |images_pref| dictionary.
148   void ExpectUserImageInfo(const base::DictionaryValue* images_pref,
149                            const std::string& username,
150                            int image_index,
151                            const base::FilePath& image_path) {
152     ASSERT_TRUE(images_pref);
153     const base::DictionaryValue* image_properties = NULL;
154     images_pref->GetDictionaryWithoutPathExpansion(username, &image_properties);
155     ASSERT_TRUE(image_properties);
156     int actual_image_index;
157     std::string actual_image_path;
158     ASSERT_TRUE(image_properties->GetInteger("index", &actual_image_index) &&
159                 image_properties->GetString("path", &actual_image_path));
160     EXPECT_EQ(image_index, actual_image_index);
161     EXPECT_EQ(image_path.value(), actual_image_path);
162   }
163
164   // Verifies that there is no image info for |username| in dictionary
165   // |images_pref|.
166   void ExpectNoUserImageInfo(const base::DictionaryValue* images_pref,
167                              const std::string& username) {
168     ASSERT_TRUE(images_pref);
169     const base::DictionaryValue* image_properties = NULL;
170     images_pref->GetDictionaryWithoutPathExpansion(username, &image_properties);
171     ASSERT_FALSE(image_properties);
172   }
173
174   // Verifies that old user image info matches |image_index| and |image_path|
175   // and that new user image info does not exist.
176   void ExpectOldUserImageInfo(const std::string& username,
177                               int image_index,
178                               const base::FilePath& image_path) {
179     ExpectUserImageInfo(local_state_->GetDictionary("UserImages"),
180                         username, image_index, image_path);
181     ExpectNoUserImageInfo(local_state_->GetDictionary("user_image_info"),
182                           username);
183   }
184
185   // Verifies that new user image info matches |image_index| and |image_path|
186   // and that old user image info does not exist.
187   void ExpectNewUserImageInfo(const std::string& username,
188                               int image_index,
189                               const base::FilePath& image_path) {
190     ExpectUserImageInfo(local_state_->GetDictionary("user_image_info"),
191                         username, image_index, image_path);
192     ExpectNoUserImageInfo(local_state_->GetDictionary("UserImages"),
193                           username);
194   }
195
196   // Sets bitmap |resource_id| as image for |username| and saves it to disk.
197   void SaveUserImagePNG(const std::string& username,
198                         int resource_id) {
199     base::FilePath image_path = GetUserImagePath(username, "png");
200     scoped_refptr<base::RefCountedStaticMemory> image_data(
201         ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale(
202             resource_id, ui::SCALE_FACTOR_100P));
203     int written = base::WriteFile(
204         image_path,
205         reinterpret_cast<const char*>(image_data->front()),
206         image_data->size());
207     EXPECT_EQ(static_cast<int>(image_data->size()), written);
208     SetOldUserImageInfo(username, User::kExternalImageIndex, image_path);
209   }
210
211   // Returns the image path for user |username| with specified |extension|.
212   base::FilePath GetUserImagePath(const std::string& username,
213                                   const std::string& extension) {
214     return user_data_dir_.Append(username).AddExtension(extension);
215   }
216
217   // Completes the download of all non-image profile data for the user
218   // |username|.  This method must only be called after a profile data
219   // download has been started.  |url_fetcher_factory| will capture
220   // the net::TestURLFetcher created by the ProfileDownloader to
221   // download the profile image.
222   void CompleteProfileMetadataDownload(
223       const std::string& username,
224       net::TestURLFetcherFactory* url_fetcher_factory) {
225     ProfileDownloader* profile_downloader =
226         reinterpret_cast<UserImageManagerImpl*>(
227             UserManager::Get()->GetUserImageManager(username))->
228                 profile_downloader_.get();
229     ASSERT_TRUE(profile_downloader);
230
231     static_cast<OAuth2TokenService::Consumer*>(profile_downloader)->
232         OnGetTokenSuccess(NULL,
233                           "token",
234                           base::Time::Now() + base::TimeDelta::FromDays(1));
235
236     net::TestURLFetcher* fetcher =
237         url_fetcher_factory->GetFetcherByID(
238             gaia::GaiaOAuthClient::kUrlFetcherId);
239     ASSERT_TRUE(fetcher);
240     fetcher->SetResponseString(
241         "{ \"image\": {\"url\": \"http://localhost/avatar.jpg\"} }");
242     fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
243                                               net::OK));
244     fetcher->set_response_code(200);
245     fetcher->delegate()->OnURLFetchComplete(fetcher);
246     base::RunLoop().RunUntilIdle();
247   }
248
249   // Completes the download of the currently logged-in user's profile image.
250   // This method must only be called after a profile data download including
251   // the profile image has been started, the download of all non-image data has
252   // been completed by calling CompleteProfileMetadataDownload() and the
253   // net::TestURLFetcher created by the ProfileDownloader to download the
254   // profile image has been captured by |url_fetcher_factory|.
255   void CompleteProfileImageDownload(
256       net::TestURLFetcherFactory* url_fetcher_factory) {
257     std::string profile_image_data;
258     base::FilePath test_data_dir;
259     ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
260     EXPECT_TRUE(ReadFileToString(
261         test_data_dir.Append("chromeos").Append("avatar1.jpg"),
262         &profile_image_data));
263
264     base::RunLoop run_loop;
265     PrefChangeRegistrar pref_change_registrar;
266     pref_change_registrar.Init(local_state_);
267     pref_change_registrar.Add("UserDisplayName", run_loop.QuitClosure());
268     net::TestURLFetcher* fetcher = url_fetcher_factory->GetFetcherByID(0);
269     ASSERT_TRUE(fetcher);
270     fetcher->SetResponseString(profile_image_data);
271     fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
272                                               net::OK));
273     fetcher->set_response_code(200);
274     fetcher->delegate()->OnURLFetchComplete(fetcher);
275     run_loop.Run();
276
277     const User* user = UserManager::Get()->GetLoggedInUser();
278     ASSERT_TRUE(user);
279     UserImageManagerImpl* uim = reinterpret_cast<UserImageManagerImpl*>(
280         UserManager::Get()->GetUserImageManager(user->email()));
281     if (uim->job_.get()) {
282       run_loop_.reset(new base::RunLoop);
283       run_loop_->Run();
284     }
285   }
286
287   base::FilePath test_data_dir_;
288   base::FilePath user_data_dir_;
289
290   PrefService* local_state_;
291
292   scoped_ptr<gfx::ImageSkia> decoded_image_;
293
294   scoped_ptr<base::RunLoop> run_loop_;
295
296  private:
297   DISALLOW_COPY_AND_ASSIGN(UserImageManagerTest);
298 };
299
300 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_DefaultUserImagePreserved) {
301   // Setup an old default (stock) user image.
302   ScopedUserManagerEnabler(new MockUserManager);
303   SetOldUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
304 }
305
306 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, DefaultUserImagePreserved) {
307   UserManager::Get()->GetUsers();  // Load users.
308   // Old info preserved.
309   ExpectOldUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
310   LogIn(kTestUser1);
311   // Image info is migrated now.
312   ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
313 }
314
315 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_OtherUsersUnaffected) {
316   // Setup two users with stock images.
317   ScopedUserManagerEnabler(new MockUserManager);
318   SetOldUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
319   SetOldUserImageInfo(kTestUser2, kFirstDefaultImageIndex + 1,
320                       base::FilePath());
321 }
322
323 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, OtherUsersUnaffected) {
324   UserManager::Get()->GetUsers();  // Load users.
325   // Old info preserved.
326   ExpectOldUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
327   ExpectOldUserImageInfo(kTestUser2, kFirstDefaultImageIndex + 1,
328                          base::FilePath());
329   LogIn(kTestUser1);
330   // Image info is migrated for the first user and unaffected for the rest.
331   ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
332   ExpectOldUserImageInfo(kTestUser2, kFirstDefaultImageIndex + 1,
333                          base::FilePath());
334 }
335
336 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_PRE_NonJPEGImageFromFile) {
337   // Setup a user with non-JPEG image.
338   ScopedUserManagerEnabler(new MockUserManager);
339   SaveUserImagePNG(
340       kTestUser1, kDefaultImageResourceIDs[kFirstDefaultImageIndex]);
341 }
342
343 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_NonJPEGImageFromFile) {
344   UserManager::Get()->GetUsers();  // Load users.
345   // Old info preserved.
346   ExpectOldUserImageInfo(kTestUser1, User::kExternalImageIndex,
347                          GetUserImagePath(kTestUser1, "png"));
348   const User* user = UserManager::Get()->FindUser(kTestUser1);
349   EXPECT_TRUE(user->image_is_stub());
350
351   base::RunLoop run_loop;
352   PrefChangeRegistrar pref_change_registrar_;
353   pref_change_registrar_.Init(local_state_);
354   pref_change_registrar_.Add("UserImages", run_loop.QuitClosure());
355   LogIn(kTestUser1);
356
357   // Wait for migration.
358   run_loop.Run();
359
360   // Image info is migrated and the image is converted to JPG.
361   ExpectNewUserImageInfo(kTestUser1, User::kExternalImageIndex,
362                          GetUserImagePath(kTestUser1, "jpg"));
363   user = UserManager::Get()->GetLoggedInUser();
364   ASSERT_TRUE(user);
365   EXPECT_FALSE(user->image_is_safe_format());
366   // Check image dimensions.
367   const gfx::ImageSkia& saved_image = GetDefaultImage(kFirstDefaultImageIndex);
368   EXPECT_EQ(saved_image.width(), user->GetImage().width());
369   EXPECT_EQ(saved_image.height(), user->GetImage().height());
370 }
371
372 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, NonJPEGImageFromFile) {
373   UserManager::Get()->GetUsers();  // Load users.
374   const User* user = UserManager::Get()->FindUser(kTestUser1);
375   ASSERT_TRUE(user);
376   // Wait for image load.
377   if (user->image_index() == User::kInvalidImageIndex) {
378     content::WindowedNotificationObserver(
379         chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
380         content::NotificationService::AllSources()).Wait();
381   }
382   // Now the migrated image is used.
383   EXPECT_TRUE(user->image_is_safe_format());
384   // Check image dimensions. Images can't be compared since JPEG is lossy.
385   const gfx::ImageSkia& saved_image = GetDefaultImage(kFirstDefaultImageIndex);
386   EXPECT_EQ(saved_image.width(), user->GetImage().width());
387   EXPECT_EQ(saved_image.height(), user->GetImage().height());
388 }
389
390 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_SaveUserDefaultImageIndex) {
391   RegisterUser(kTestUser1);
392 }
393
394 // Verifies that SaveUserDefaultImageIndex() correctly sets and persists the
395 // chosen user image.
396 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserDefaultImageIndex) {
397   const User* user = UserManager::Get()->FindUser(kTestUser1);
398   ASSERT_TRUE(user);
399
400   const gfx::ImageSkia& default_image =
401       GetDefaultImage(kFirstDefaultImageIndex);
402
403   UserImageManager* user_image_manager =
404       UserManager::Get()->GetUserImageManager(kTestUser1);
405   user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex);
406
407   EXPECT_TRUE(user->HasDefaultImage());
408   EXPECT_EQ(kFirstDefaultImageIndex, user->image_index());
409   EXPECT_TRUE(test::AreImagesEqual(default_image, user->GetImage()));
410   ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
411 }
412
413 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_SaveUserImage) {
414   RegisterUser(kTestUser1);
415 }
416
417 // Verifies that SaveUserImage() correctly sets and persists the chosen user
418 // image.
419 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserImage) {
420   const User* user = UserManager::Get()->FindUser(kTestUser1);
421   ASSERT_TRUE(user);
422
423   SkBitmap custom_image_bitmap;
424   custom_image_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10);
425   custom_image_bitmap.allocPixels();
426   custom_image_bitmap.setImmutable();
427   const gfx::ImageSkia custom_image =
428       gfx::ImageSkia::CreateFrom1xBitmap(custom_image_bitmap);
429
430   run_loop_.reset(new base::RunLoop);
431   UserImageManager* user_image_manager =
432       UserManager::Get()->GetUserImageManager(kTestUser1);
433   user_image_manager->SaveUserImage(UserImage::CreateAndEncode(custom_image));
434   run_loop_->Run();
435
436   EXPECT_FALSE(user->HasDefaultImage());
437   EXPECT_EQ(User::kExternalImageIndex, user->image_index());
438   EXPECT_TRUE(test::AreImagesEqual(custom_image, user->GetImage()));
439   ExpectNewUserImageInfo(kTestUser1,
440                          User::kExternalImageIndex,
441                          GetUserImagePath(kTestUser1, "jpg"));
442
443   const scoped_ptr<gfx::ImageSkia> saved_image =
444       test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
445   ASSERT_TRUE(saved_image);
446
447   // Check image dimensions. Images can't be compared since JPEG is lossy.
448   EXPECT_EQ(custom_image.width(), saved_image->width());
449   EXPECT_EQ(custom_image.height(), saved_image->height());
450 }
451
452 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, PRE_SaveUserImageFromFile) {
453   RegisterUser(kTestUser1);
454 }
455
456 // Verifies that SaveUserImageFromFile() correctly sets and persists the chosen
457 // user image.
458 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserImageFromFile) {
459   const User* user = UserManager::Get()->FindUser(kTestUser1);
460   ASSERT_TRUE(user);
461
462   const base::FilePath custom_image_path =
463       test_data_dir_.Append(test::kUserAvatarImage1RelativePath);
464   const scoped_ptr<gfx::ImageSkia> custom_image =
465       test::ImageLoader(custom_image_path).Load();
466   ASSERT_TRUE(custom_image);
467
468   run_loop_.reset(new base::RunLoop);
469   UserImageManager* user_image_manager =
470       UserManager::Get()->GetUserImageManager(kTestUser1);
471   user_image_manager->SaveUserImageFromFile(custom_image_path);
472   run_loop_->Run();
473
474   EXPECT_FALSE(user->HasDefaultImage());
475   EXPECT_EQ(User::kExternalImageIndex, user->image_index());
476   EXPECT_TRUE(test::AreImagesEqual(*custom_image, user->GetImage()));
477   ExpectNewUserImageInfo(kTestUser1,
478                          User::kExternalImageIndex,
479                          GetUserImagePath(kTestUser1, "jpg"));
480
481   const scoped_ptr<gfx::ImageSkia> saved_image =
482       test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
483   ASSERT_TRUE(saved_image);
484
485   // Check image dimensions. Images can't be compared since JPEG is lossy.
486   EXPECT_EQ(custom_image->width(), saved_image->width());
487   EXPECT_EQ(custom_image->height(), saved_image->height());
488 }
489
490 IN_PROC_BROWSER_TEST_F(UserImageManagerTest,
491                        PRE_SaveUserImageFromProfileImage) {
492   RegisterUser(kTestUser1);
493   chromeos::StartupUtils::MarkOobeCompleted();
494 }
495
496 // Verifies that SaveUserImageFromProfileImage() correctly downloads, sets and
497 // persists the chosen user image.
498 IN_PROC_BROWSER_TEST_F(UserImageManagerTest, SaveUserImageFromProfileImage) {
499   const User* user = UserManager::Get()->FindUser(kTestUser1);
500   ASSERT_TRUE(user);
501
502   UserImageManagerImpl::IgnoreProfileDataDownloadDelayForTesting();
503   LoginUser(kTestUser1);
504
505   run_loop_.reset(new base::RunLoop);
506   UserImageManager* user_image_manager =
507       UserManager::Get()->GetUserImageManager(kTestUser1);
508   user_image_manager->SaveUserImageFromProfileImage();
509   run_loop_->Run();
510
511   net::TestURLFetcherFactory url_fetcher_factory;
512   CompleteProfileMetadataDownload(kTestUser1, &url_fetcher_factory);
513   CompleteProfileImageDownload(&url_fetcher_factory);
514
515   const gfx::ImageSkia& profile_image =
516       user_image_manager->DownloadedProfileImage();
517
518   EXPECT_FALSE(user->HasDefaultImage());
519   EXPECT_EQ(User::kProfileImageIndex, user->image_index());
520   EXPECT_TRUE(test::AreImagesEqual(profile_image, user->GetImage()));
521   ExpectNewUserImageInfo(kTestUser1,
522                          User::kProfileImageIndex,
523                          GetUserImagePath(kTestUser1, "jpg"));
524
525   const scoped_ptr<gfx::ImageSkia> saved_image =
526       test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
527   ASSERT_TRUE(saved_image);
528
529   // Check image dimensions. Images can't be compared since JPEG is lossy.
530   EXPECT_EQ(profile_image.width(), saved_image->width());
531   EXPECT_EQ(profile_image.height(), saved_image->height());
532 }
533
534 IN_PROC_BROWSER_TEST_F(UserImageManagerTest,
535                        PRE_ProfileImageDownloadDoesNotClobber) {
536   RegisterUser(kTestUser1);
537   chromeos::StartupUtils::MarkOobeCompleted();
538 }
539
540 // Sets the user image to the profile image, then sets it to one of the default
541 // images while the profile image download is still in progress. Verifies that
542 // when the download completes, the profile image is ignored and does not
543 // clobber the default image chosen in the meantime.
544 IN_PROC_BROWSER_TEST_F(UserImageManagerTest,
545                        ProfileImageDownloadDoesNotClobber) {
546   const User* user = UserManager::Get()->FindUser(kTestUser1);
547   ASSERT_TRUE(user);
548
549   const gfx::ImageSkia& default_image =
550       GetDefaultImage(kFirstDefaultImageIndex);
551
552   UserImageManagerImpl::IgnoreProfileDataDownloadDelayForTesting();
553   LoginUser(kTestUser1);
554
555   run_loop_.reset(new base::RunLoop);
556   UserImageManager* user_image_manager =
557       UserManager::Get()->GetUserImageManager(kTestUser1);
558   user_image_manager->SaveUserImageFromProfileImage();
559   run_loop_->Run();
560
561   net::TestURLFetcherFactory url_fetcher_factory;
562   CompleteProfileMetadataDownload(kTestUser1, &url_fetcher_factory);
563
564   user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex);
565
566   CompleteProfileImageDownload(&url_fetcher_factory);
567
568   EXPECT_TRUE(user->HasDefaultImage());
569   EXPECT_EQ(kFirstDefaultImageIndex, user->image_index());
570   EXPECT_TRUE(test::AreImagesEqual(default_image, user->GetImage()));
571   ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
572 }
573
574 class UserImageManagerPolicyTest : public UserImageManagerTest,
575                                    public policy::CloudPolicyStore::Observer {
576  protected:
577   UserImageManagerPolicyTest()
578       : fake_dbus_thread_manager_(new chromeos::FakeDBusThreadManager),
579         fake_session_manager_client_(new chromeos::FakeSessionManagerClient) {
580     fake_dbus_thread_manager_->SetFakeClients();
581     fake_dbus_thread_manager_->SetSessionManagerClient(
582         scoped_ptr<SessionManagerClient>(fake_session_manager_client_));
583   }
584
585   // UserImageManagerTest overrides:
586   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
587     DBusThreadManager::SetInstanceForTesting(fake_dbus_thread_manager_);
588     UserImageManagerTest::SetUpInProcessBrowserTestFixture();
589   }
590
591   virtual void SetUpOnMainThread() OVERRIDE {
592     UserImageManagerTest::SetUpOnMainThread();
593
594     base::FilePath user_keys_dir;
595     ASSERT_TRUE(PathService::Get(chromeos::DIR_USER_POLICY_KEYS,
596                                  &user_keys_dir));
597     const std::string sanitized_username =
598         chromeos::CryptohomeClient::GetStubSanitizedUsername(kTestUser1);
599     const base::FilePath user_key_file =
600         user_keys_dir.AppendASCII(sanitized_username)
601                      .AppendASCII("policy.pub");
602     std::vector<uint8> user_key_bits;
603     ASSERT_TRUE(user_policy_.GetSigningKey()->ExportPublicKey(&user_key_bits));
604     ASSERT_TRUE(base::CreateDirectory(user_key_file.DirName()));
605     ASSERT_EQ(base::WriteFile(
606                   user_key_file,
607                   reinterpret_cast<const char*>(user_key_bits.data()),
608                   user_key_bits.size()),
609               static_cast<int>(user_key_bits.size()));
610     user_policy_.policy_data().set_username(kTestUser1);
611
612     ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
613
614     policy_image_ = test::ImageLoader(test_data_dir_.Append(
615         test::kUserAvatarImage2RelativePath)).Load();
616     ASSERT_TRUE(policy_image_);
617   }
618
619   // policy::CloudPolicyStore::Observer overrides:
620   virtual void OnStoreLoaded(policy::CloudPolicyStore* store) OVERRIDE {
621     if (run_loop_)
622       run_loop_->Quit();
623   }
624
625   virtual void OnStoreError(policy::CloudPolicyStore* store) OVERRIDE {
626     if (run_loop_)
627       run_loop_->Quit();
628   }
629
630   std::string ConstructPolicy(const std::string& relative_path) {
631     std::string image_data;
632     if (!base::ReadFileToString(test_data_dir_.Append(relative_path),
633                                 &image_data)) {
634       ADD_FAILURE();
635     }
636     std::string policy;
637     base::JSONWriter::Write(policy::test::ConstructExternalDataReference(
638         embedded_test_server()->GetURL(std::string("/") + relative_path).spec(),
639         image_data).get(),
640         &policy);
641     return policy;
642   }
643
644   policy::UserPolicyBuilder user_policy_;
645   FakeDBusThreadManager* fake_dbus_thread_manager_;
646   FakeSessionManagerClient* fake_session_manager_client_;
647
648   scoped_ptr<gfx::ImageSkia> policy_image_;
649
650  private:
651   DISALLOW_COPY_AND_ASSIGN(UserImageManagerPolicyTest);
652 };
653
654 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, PRE_SetAndClear) {
655   RegisterUser(kTestUser1);
656   chromeos::StartupUtils::MarkOobeCompleted();
657 }
658
659 // Verifies that the user image can be set through policy. Also verifies that
660 // after the policy has been cleared, the user is able to choose a different
661 // image.
662 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, SetAndClear) {
663   const User* user = UserManager::Get()->FindUser(kTestUser1);
664   ASSERT_TRUE(user);
665
666   LoginUser(kTestUser1);
667   base::RunLoop().RunUntilIdle();
668
669   policy::CloudPolicyStore* store = GetStoreForUser(user);
670   ASSERT_TRUE(store);
671
672   // Set policy. Verify that the policy-provided user image is downloaded, set
673   // and persisted.
674   user_policy_.payload().mutable_useravatarimage()->set_value(
675       ConstructPolicy(test::kUserAvatarImage2RelativePath));
676   user_policy_.Build();
677   fake_session_manager_client_->set_user_policy(kTestUser1,
678                                                 user_policy_.GetBlob());
679   run_loop_.reset(new base::RunLoop);
680   store->Load();
681   run_loop_->Run();
682
683   EXPECT_FALSE(user->HasDefaultImage());
684   EXPECT_EQ(User::kExternalImageIndex, user->image_index());
685   EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->GetImage()));
686   ExpectNewUserImageInfo(kTestUser1,
687                          User::kExternalImageIndex,
688                          GetUserImagePath(kTestUser1, "jpg"));
689
690   scoped_ptr<gfx::ImageSkia> saved_image =
691       test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
692   ASSERT_TRUE(saved_image);
693
694   // Check image dimensions. Images can't be compared since JPEG is lossy.
695   EXPECT_EQ(policy_image_->width(), saved_image->width());
696   EXPECT_EQ(policy_image_->height(), saved_image->height());
697
698   // Clear policy. Verify that the policy-provided user image remains set as no
699   // different user image has been chosen yet.
700   user_policy_.payload().Clear();
701   user_policy_.Build();
702   fake_session_manager_client_->set_user_policy(kTestUser1,
703                                                 user_policy_.GetBlob());
704   run_loop_.reset(new base::RunLoop);
705   store->AddObserver(this);
706   store->Load();
707   run_loop_->Run();
708   store->RemoveObserver(this);
709   base::RunLoop().RunUntilIdle();
710
711   EXPECT_FALSE(user->HasDefaultImage());
712   EXPECT_EQ(User::kExternalImageIndex, user->image_index());
713   EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->GetImage()));
714   ExpectNewUserImageInfo(kTestUser1,
715                          User::kExternalImageIndex,
716                          GetUserImagePath(kTestUser1, "jpg"));
717
718   saved_image = test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
719   ASSERT_TRUE(saved_image);
720
721   // Check image dimensions. Images can't be compared since JPEG is lossy.
722   EXPECT_EQ(policy_image_->width(), saved_image->width());
723   EXPECT_EQ(policy_image_->height(), saved_image->height());
724
725   // Choose a different user image. Verify that the chosen user image is set and
726   // persisted.
727   const gfx::ImageSkia& default_image =
728       GetDefaultImage(kFirstDefaultImageIndex);
729
730   UserImageManager* user_image_manager =
731       UserManager::Get()->GetUserImageManager(kTestUser1);
732   user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex);
733
734   EXPECT_TRUE(user->HasDefaultImage());
735   EXPECT_EQ(kFirstDefaultImageIndex, user->image_index());
736   EXPECT_TRUE(test::AreImagesEqual(default_image, user->GetImage()));
737   ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
738 }
739
740 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, PRE_PolicyOverridesUser) {
741   RegisterUser(kTestUser1);
742   chromeos::StartupUtils::MarkOobeCompleted();
743 }
744
745 // Verifies that when the user chooses a user image and a different image is
746 // then set through policy, the policy takes precedence, overriding the
747 // previously chosen image.
748 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, PolicyOverridesUser) {
749   const User* user = UserManager::Get()->FindUser(kTestUser1);
750   ASSERT_TRUE(user);
751
752   LoginUser(kTestUser1);
753   base::RunLoop().RunUntilIdle();
754
755   policy::CloudPolicyStore* store = GetStoreForUser(user);
756   ASSERT_TRUE(store);
757
758   // Choose a user image. Verify that the chosen user image is set and
759   // persisted.
760   const gfx::ImageSkia& default_image =
761       GetDefaultImage(kFirstDefaultImageIndex);
762
763   UserImageManager* user_image_manager =
764       UserManager::Get()->GetUserImageManager(kTestUser1);
765   user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex);
766
767   EXPECT_TRUE(user->HasDefaultImage());
768   EXPECT_EQ(kFirstDefaultImageIndex, user->image_index());
769   EXPECT_TRUE(test::AreImagesEqual(default_image, user->GetImage()));
770   ExpectNewUserImageInfo(kTestUser1, kFirstDefaultImageIndex, base::FilePath());
771
772   // Set policy. Verify that the policy-provided user image is downloaded, set
773   // and persisted, overriding the previously set image.
774   user_policy_.payload().mutable_useravatarimage()->set_value(
775       ConstructPolicy(test::kUserAvatarImage2RelativePath));
776   user_policy_.Build();
777   fake_session_manager_client_->set_user_policy(kTestUser1,
778                                                 user_policy_.GetBlob());
779   run_loop_.reset(new base::RunLoop);
780   store->Load();
781   run_loop_->Run();
782
783   EXPECT_FALSE(user->HasDefaultImage());
784   EXPECT_EQ(User::kExternalImageIndex, user->image_index());
785   EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->GetImage()));
786   ExpectNewUserImageInfo(kTestUser1,
787                          User::kExternalImageIndex,
788                          GetUserImagePath(kTestUser1, "jpg"));
789
790   scoped_ptr<gfx::ImageSkia> saved_image =
791       test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
792   ASSERT_TRUE(saved_image);
793
794   // Check image dimensions. Images can't be compared since JPEG is lossy.
795   EXPECT_EQ(policy_image_->width(), saved_image->width());
796   EXPECT_EQ(policy_image_->height(), saved_image->height());
797 }
798
799 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest,
800                        PRE_UserDoesNotOverridePolicy) {
801   RegisterUser(kTestUser1);
802   chromeos::StartupUtils::MarkOobeCompleted();
803 }
804
805 // Verifies that when the user image has been set through policy and the user
806 // chooses a different image, the policy takes precedence, preventing the user
807 // from overriding the previously chosen image.
808 IN_PROC_BROWSER_TEST_F(UserImageManagerPolicyTest, UserDoesNotOverridePolicy) {
809   const User* user = UserManager::Get()->FindUser(kTestUser1);
810   ASSERT_TRUE(user);
811
812   LoginUser(kTestUser1);
813   base::RunLoop().RunUntilIdle();
814
815   policy::CloudPolicyStore* store = GetStoreForUser(user);
816   ASSERT_TRUE(store);
817
818   // Set policy. Verify that the policy-provided user image is downloaded, set
819   // and persisted.
820   user_policy_.payload().mutable_useravatarimage()->set_value(
821       ConstructPolicy(test::kUserAvatarImage2RelativePath));
822   user_policy_.Build();
823   fake_session_manager_client_->set_user_policy(kTestUser1,
824                                                 user_policy_.GetBlob());
825   run_loop_.reset(new base::RunLoop);
826   store->Load();
827   run_loop_->Run();
828
829   EXPECT_FALSE(user->HasDefaultImage());
830   EXPECT_EQ(User::kExternalImageIndex, user->image_index());
831   EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->GetImage()));
832   ExpectNewUserImageInfo(kTestUser1,
833                          User::kExternalImageIndex,
834                          GetUserImagePath(kTestUser1, "jpg"));
835
836   scoped_ptr<gfx::ImageSkia> saved_image =
837       test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
838   ASSERT_TRUE(saved_image);
839
840   // Check image dimensions. Images can't be compared since JPEG is lossy.
841   EXPECT_EQ(policy_image_->width(), saved_image->width());
842   EXPECT_EQ(policy_image_->height(), saved_image->height());
843
844   // Choose a different user image. Verify that the user image does not change
845   // as policy takes precedence.
846   UserImageManager* user_image_manager =
847       UserManager::Get()->GetUserImageManager(kTestUser1);
848   user_image_manager->SaveUserDefaultImageIndex(kFirstDefaultImageIndex);
849
850   EXPECT_FALSE(user->HasDefaultImage());
851   EXPECT_EQ(User::kExternalImageIndex, user->image_index());
852   EXPECT_TRUE(test::AreImagesEqual(*policy_image_, user->GetImage()));
853   ExpectNewUserImageInfo(kTestUser1,
854                          User::kExternalImageIndex,
855                          GetUserImagePath(kTestUser1, "jpg"));
856
857   saved_image = test::ImageLoader(GetUserImagePath(kTestUser1, "jpg")).Load();
858   ASSERT_TRUE(saved_image);
859
860   // Check image dimensions. Images can't be compared since JPEG is lossy.
861   EXPECT_EQ(policy_image_->width(), saved_image->width());
862   EXPECT_EQ(policy_image_->height(), saved_image->height());
863 }
864
865 }  // namespace chromeos