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/gaia_info_update_service.h" 6 7#include "base/prefs/pref_service.h" 8#include "base/strings/utf_string_conversions.h" 9#include "chrome/browser/browser_process.h" 10#include "chrome/browser/prefs/pref_service_syncable.h" 11#include "chrome/browser/profiles/profile_downloader.h" 12#include "chrome/browser/profiles/profile_info_cache.h" 13#include "chrome/browser/profiles/profile_info_cache_unittest.h" 14#include "chrome/browser/signin/chrome_signin_client_factory.h" 15#include "chrome/browser/signin/signin_manager_factory.h" 16#include "chrome/browser/signin/test_signin_client_builder.h" 17#include "chrome/common/pref_names.h" 18#include "chrome/test/base/testing_browser_process.h" 19#include "chrome/test/base/testing_profile.h" 20#include "chrome/test/base/testing_profile_manager.h" 21#include "testing/gmock/include/gmock/gmock.h" 22#include "ui/gfx/image/image.h" 23#include "ui/gfx/image/image_unittest_util.h" 24 25using ::testing::Return; 26using ::testing::NiceMock; 27 28namespace { 29 30class ProfileDownloaderMock : public ProfileDownloader { 31 public: 32 explicit ProfileDownloaderMock(ProfileDownloaderDelegate* delegate) 33 : ProfileDownloader(delegate) { 34 } 35 36 virtual ~ProfileDownloaderMock() { 37 } 38 39 MOCK_CONST_METHOD0(GetProfileFullName, base::string16()); 40 MOCK_CONST_METHOD0(GetProfileGivenName, base::string16()); 41 MOCK_CONST_METHOD0(GetProfilePicture, SkBitmap()); 42 MOCK_CONST_METHOD0(GetProfilePictureStatus, 43 ProfileDownloader::PictureStatus()); 44 MOCK_CONST_METHOD0(GetProfilePictureURL, std::string()); 45}; 46 47class GAIAInfoUpdateServiceMock : public GAIAInfoUpdateService { 48 public: 49 explicit GAIAInfoUpdateServiceMock(Profile* profile) 50 : GAIAInfoUpdateService(profile) { 51 } 52 53 virtual ~GAIAInfoUpdateServiceMock() { 54 } 55 56 MOCK_METHOD0(Update, void()); 57}; 58 59class GAIAInfoUpdateServiceTest : public ProfileInfoCacheTest { 60 protected: 61 GAIAInfoUpdateServiceTest() : profile_(NULL) { 62 } 63 64 Profile* profile() { 65 if (!profile_) 66 profile_ = CreateProfile("Person 1"); 67 return profile_; 68 } 69 70 NiceMock<GAIAInfoUpdateServiceMock>* service() { return service_.get(); } 71 NiceMock<ProfileDownloaderMock>* downloader() { return downloader_.get(); } 72 73 Profile* CreateProfile(const std::string& name) { 74 TestingProfile::TestingFactories testing_factories; 75 testing_factories.push_back(std::make_pair( 76 ChromeSigninClientFactory::GetInstance(), 77 signin::BuildTestSigninClient)); 78 Profile* profile = testing_profile_manager_.CreateTestingProfile(name, 79 scoped_ptr<PrefServiceSyncable>(), base::UTF8ToUTF16(name), 0, 80 std::string(), testing_factories); 81 // The testing manager sets the profile name manually, which counts as 82 // a user-customized profile name. Reset this to match the default name 83 // we are actually using. 84 size_t index = GetCache()->GetIndexOfProfileWithPath(profile->GetPath()); 85 GetCache()->SetProfileIsUsingDefaultNameAtIndex(index, true); 86 return profile; 87 } 88 89 static std::string GivenName(const std::string& id) { 90 return id + "first"; 91 } 92 static std::string FullName(const std::string& id) { 93 return GivenName(id) + " " + id + "last"; 94 } 95 static base::string16 GivenName16(const std::string& id) { 96 return base::UTF8ToUTF16(GivenName(id)); 97 } 98 static base::string16 FullName16(const std::string& id) { 99 return base::UTF8ToUTF16(FullName(id)); 100 } 101 102 void ProfileDownloadSuccess( 103 const base::string16& full_name, 104 const base::string16& given_name, 105 const gfx::Image& image, 106 const std::string& url) { 107 EXPECT_CALL(*downloader(), GetProfileFullName()). 108 WillOnce(Return(full_name)); 109 EXPECT_CALL(*downloader(), GetProfileGivenName()). 110 WillOnce(Return(given_name)); 111 const SkBitmap* bmp = image.ToSkBitmap(); 112 EXPECT_CALL(*downloader(), GetProfilePicture()).WillOnce(Return(*bmp)); 113 EXPECT_CALL(*downloader(), GetProfilePictureStatus()). 114 WillOnce(Return(ProfileDownloader::PICTURE_SUCCESS)); 115 EXPECT_CALL(*downloader(), GetProfilePictureURL()).WillOnce(Return(url)); 116 117 service()->OnProfileDownloadSuccess(downloader()); 118 } 119 120 void RenameProfile(const base::string16& full_name, 121 const base::string16& given_name) { 122 gfx::Image image = gfx::test::CreateImage(256,256); 123 std::string url("foo.com"); 124 ProfileDownloadSuccess(full_name, given_name, image, url); 125 126 // Make sure the right profile was updated correctly. 127 size_t index = GetCache()->GetIndexOfProfileWithPath(profile()->GetPath()); 128 EXPECT_EQ(full_name, GetCache()->GetGAIANameOfProfileAtIndex(index)); 129 EXPECT_EQ(given_name, GetCache()->GetGAIAGivenNameOfProfileAtIndex(index)); 130 } 131 132 private: 133 virtual void SetUp() OVERRIDE; 134 virtual void TearDown() OVERRIDE; 135 136 Profile* profile_; 137 scoped_ptr<NiceMock<GAIAInfoUpdateServiceMock> > service_; 138 scoped_ptr<NiceMock<ProfileDownloaderMock> > downloader_; 139}; 140 141void GAIAInfoUpdateServiceTest::SetUp() { 142 ProfileInfoCacheTest::SetUp(); 143 service_.reset(new NiceMock<GAIAInfoUpdateServiceMock>(profile())); 144 downloader_.reset(new NiceMock<ProfileDownloaderMock>(service())); 145} 146 147void GAIAInfoUpdateServiceTest::TearDown() { 148 downloader_.reset(); 149 service_->Shutdown(); 150 service_.reset(); 151 ProfileInfoCacheTest::TearDown(); 152} 153 154} // namespace 155 156TEST_F(GAIAInfoUpdateServiceTest, DownloadSuccess) { 157 // No URL should be cached yet. 158 EXPECT_EQ(std::string(), service()->GetCachedPictureURL()); 159 160 base::string16 name = base::ASCIIToUTF16("Pat Smith"); 161 base::string16 given_name = base::ASCIIToUTF16("Pat"); 162 gfx::Image image = gfx::test::CreateImage(256, 256); 163 std::string url("foo.com"); 164 ProfileDownloadSuccess(name, given_name, image, url); 165 166 // On success the GAIA info should be updated. 167 size_t index = GetCache()->GetIndexOfProfileWithPath(profile()->GetPath()); 168 EXPECT_EQ(name, GetCache()->GetGAIANameOfProfileAtIndex(index)); 169 EXPECT_EQ(given_name, GetCache()->GetGAIAGivenNameOfProfileAtIndex(index)); 170 EXPECT_TRUE(gfx::test::IsEqual( 171 image, *GetCache()->GetGAIAPictureOfProfileAtIndex(index))); 172 EXPECT_EQ(url, service()->GetCachedPictureURL()); 173} 174 175TEST_F(GAIAInfoUpdateServiceTest, DownloadFailure) { 176 size_t index = GetCache()->GetIndexOfProfileWithPath(profile()->GetPath()); 177 base::string16 old_name = GetCache()->GetNameOfProfileAtIndex(index); 178 gfx::Image old_image = GetCache()->GetAvatarIconOfProfileAtIndex(index); 179 180 EXPECT_EQ(std::string(), service()->GetCachedPictureURL()); 181 182 service()->OnProfileDownloadFailure(downloader(), 183 ProfileDownloaderDelegate::SERVICE_ERROR); 184 185 // On failure nothing should be updated. 186 EXPECT_EQ(old_name, GetCache()->GetNameOfProfileAtIndex(index)); 187 EXPECT_EQ(base::string16(), GetCache()->GetGAIANameOfProfileAtIndex(index)); 188 EXPECT_EQ(base::string16(), 189 GetCache()->GetGAIAGivenNameOfProfileAtIndex(index)); 190 EXPECT_TRUE(gfx::test::IsEqual( 191 old_image, GetCache()->GetAvatarIconOfProfileAtIndex(index))); 192 EXPECT_EQ(NULL, GetCache()->GetGAIAPictureOfProfileAtIndex(index)); 193 EXPECT_EQ(std::string(), service()->GetCachedPictureURL()); 194} 195 196TEST_F(GAIAInfoUpdateServiceTest, HandlesProfileReordering) { 197 size_t index = GetCache()->GetIndexOfProfileWithPath(profile()->GetPath()); 198 GetCache()->SetNameOfProfileAtIndex(index, FullName16("B")); 199 GetCache()->SetProfileIsUsingDefaultNameAtIndex(index, true); 200 201 CreateProfile(FullName("A")); 202 CreateProfile(FullName("C")); 203 CreateProfile(FullName("E")); 204 205 size_t index_before = 206 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath()); 207 208 // Rename our profile. 209 RenameProfile(FullName16("D"), GivenName16("D")); 210 // Profiles should have been reordered in the cache. 211 EXPECT_NE(index_before, 212 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath())); 213 // Rename the profile back to the original name, it should go back to its 214 // original position. 215 RenameProfile(FullName16("B"), GivenName16("B")); 216 EXPECT_EQ(index_before, 217 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath())); 218 219 // Rename only the given name of our profile. 220 RenameProfile(FullName16("B"), GivenName16("D")); 221 // Rename the profile back to the original name, it should go back to its 222 // original position. 223 RenameProfile(FullName16("B"), GivenName16("B")); 224 EXPECT_EQ(index_before, 225 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath())); 226 227 // Rename only the full name of our profile. 228 RenameProfile(FullName16("D"), GivenName16("B")); 229 // Rename the profile back to the original name, it should go back to its 230 // original position. 231 RenameProfile(FullName16("B"), GivenName16("B")); 232 EXPECT_EQ(index_before, 233 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath())); 234} 235 236TEST_F(GAIAInfoUpdateServiceTest, ShouldUseGAIAProfileInfo) { 237#if defined(OS_CHROMEOS) 238 // This feature should never be enabled on ChromeOS. 239 EXPECT_FALSE(GAIAInfoUpdateService::ShouldUseGAIAProfileInfo(profile())); 240#endif 241} 242 243TEST_F(GAIAInfoUpdateServiceTest, ScheduleUpdate) { 244 EXPECT_TRUE(service()->timer_.IsRunning()); 245 service()->timer_.Stop(); 246 EXPECT_FALSE(service()->timer_.IsRunning()); 247 service()->ScheduleNextUpdate(); 248 EXPECT_TRUE(service()->timer_.IsRunning()); 249} 250 251#if !defined(OS_CHROMEOS) 252 253TEST_F(GAIAInfoUpdateServiceTest, LogOut) { 254 SigninManager* signin_manager = 255 SigninManagerFactory::GetForProfile(profile()); 256 signin_manager->SetAuthenticatedUsername("pat@example.com"); 257 base::string16 gaia_name = base::UTF8ToUTF16("Pat Foo"); 258 GetCache()->SetGAIANameOfProfileAtIndex(0, gaia_name); 259 gfx::Image gaia_picture = gfx::test::CreateImage(256,256); 260 GetCache()->SetGAIAPictureOfProfileAtIndex(0, &gaia_picture); 261 262 // Set a fake picture URL. 263 profile()->GetPrefs()->SetString(prefs::kProfileGAIAInfoPictureURL, 264 "example.com"); 265 266 EXPECT_FALSE(service()->GetCachedPictureURL().empty()); 267 268 // Log out. 269 signin_manager->SignOut(signin_metrics::SIGNOUT_TEST); 270 // Verify that the GAIA name and picture, and picture URL are unset. 271 EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(0).empty()); 272 EXPECT_EQ(NULL, GetCache()->GetGAIAPictureOfProfileAtIndex(0)); 273 EXPECT_TRUE(service()->GetCachedPictureURL().empty()); 274} 275 276TEST_F(GAIAInfoUpdateServiceTest, LogIn) { 277 // Log in. 278 EXPECT_CALL(*service(), Update()); 279 SigninManager* signin_manager = 280 SigninManagerFactory::GetForProfile(profile()); 281 signin_manager->OnExternalSigninCompleted("pat@example.com"); 282} 283 284#endif 285