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.
5 #include "chrome/browser/profiles/gaia_info_update_service.h"
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/profiles/profiles_state.h"
15 #include "chrome/browser/signin/chrome_signin_client_factory.h"
16 #include "chrome/browser/signin/signin_manager_factory.h"
17 #include "chrome/browser/signin/test_signin_client_builder.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/test/base/testing_browser_process.h"
20 #include "chrome/test/base/testing_profile.h"
21 #include "chrome/test/base/testing_profile_manager.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "ui/gfx/image/image.h"
24 #include "ui/gfx/image/image_unittest_util.h"
26 using ::testing::Return
;
27 using ::testing::NiceMock
;
31 class ProfileDownloaderMock
: public ProfileDownloader
{
33 explicit ProfileDownloaderMock(ProfileDownloaderDelegate
* delegate
)
34 : ProfileDownloader(delegate
) {
37 virtual ~ProfileDownloaderMock() {
40 MOCK_CONST_METHOD0(GetProfileFullName
, base::string16());
41 MOCK_CONST_METHOD0(GetProfileGivenName
, base::string16());
42 MOCK_CONST_METHOD0(GetProfilePicture
, SkBitmap());
43 MOCK_CONST_METHOD0(GetProfilePictureStatus
,
44 ProfileDownloader::PictureStatus());
45 MOCK_CONST_METHOD0(GetProfilePictureURL
, std::string());
46 MOCK_CONST_METHOD0(GetProfileHostedDomain
, base::string16());
49 class GAIAInfoUpdateServiceMock
: public GAIAInfoUpdateService
{
51 explicit GAIAInfoUpdateServiceMock(Profile
* profile
)
52 : GAIAInfoUpdateService(profile
) {
55 virtual ~GAIAInfoUpdateServiceMock() {
58 MOCK_METHOD0(Update
, void());
61 class GAIAInfoUpdateServiceTest
: public ProfileInfoCacheTest
{
63 GAIAInfoUpdateServiceTest() : profile_(NULL
) {
68 profile_
= CreateProfile("Person 1");
72 NiceMock
<GAIAInfoUpdateServiceMock
>* service() { return service_
.get(); }
73 NiceMock
<ProfileDownloaderMock
>* downloader() { return downloader_
.get(); }
75 Profile
* CreateProfile(const std::string
& name
) {
76 TestingProfile::TestingFactories testing_factories
;
77 testing_factories
.push_back(std::make_pair(
78 ChromeSigninClientFactory::GetInstance(),
79 signin::BuildTestSigninClient
));
80 Profile
* profile
= testing_profile_manager_
.CreateTestingProfile(name
,
81 scoped_ptr
<PrefServiceSyncable
>(), base::UTF8ToUTF16(name
), 0,
82 std::string(), testing_factories
);
83 // The testing manager sets the profile name manually, which counts as
84 // a user-customized profile name. Reset this to match the default name
85 // we are actually using.
86 size_t index
= GetCache()->GetIndexOfProfileWithPath(profile
->GetPath());
87 GetCache()->SetProfileIsUsingDefaultNameAtIndex(index
, true);
91 static std::string
GivenName(const std::string
& id
) {
94 static std::string
FullName(const std::string
& id
) {
95 return GivenName(id
) + " " + id
+ "last";
97 static base::string16
GivenName16(const std::string
& id
) {
98 return base::UTF8ToUTF16(GivenName(id
));
100 static base::string16
FullName16(const std::string
& id
) {
101 return base::UTF8ToUTF16(FullName(id
));
104 void ProfileDownloadSuccess(
105 const base::string16
& full_name
,
106 const base::string16
& given_name
,
107 const gfx::Image
& image
,
108 const std::string
& url
,
109 const base::string16
& hosted_domain
) {
110 EXPECT_CALL(*downloader(), GetProfileFullName()).
111 WillOnce(Return(full_name
));
112 EXPECT_CALL(*downloader(), GetProfileGivenName()).
113 WillOnce(Return(given_name
));
114 const SkBitmap
* bmp
= image
.ToSkBitmap();
115 EXPECT_CALL(*downloader(), GetProfilePicture()).WillOnce(Return(*bmp
));
116 EXPECT_CALL(*downloader(), GetProfilePictureStatus()).
117 WillOnce(Return(ProfileDownloader::PICTURE_SUCCESS
));
118 EXPECT_CALL(*downloader(), GetProfilePictureURL()).WillOnce(Return(url
));
119 EXPECT_CALL(*downloader(), GetProfileHostedDomain()).
120 WillOnce(Return(hosted_domain
));
122 service()->OnProfileDownloadSuccess(downloader());
125 void RenameProfile(const base::string16
& full_name
,
126 const base::string16
& given_name
) {
127 gfx::Image image
= gfx::test::CreateImage(256,256);
128 std::string
url("foo.com");
129 ProfileDownloadSuccess(full_name
, given_name
, image
, url
, base::string16());
131 // Make sure the right profile was updated correctly.
132 size_t index
= GetCache()->GetIndexOfProfileWithPath(profile()->GetPath());
133 EXPECT_EQ(full_name
, GetCache()->GetGAIANameOfProfileAtIndex(index
));
134 EXPECT_EQ(given_name
, GetCache()->GetGAIAGivenNameOfProfileAtIndex(index
));
138 void SetUp() override
;
139 void TearDown() override
;
142 scoped_ptr
<NiceMock
<GAIAInfoUpdateServiceMock
> > service_
;
143 scoped_ptr
<NiceMock
<ProfileDownloaderMock
> > downloader_
;
146 void GAIAInfoUpdateServiceTest::SetUp() {
147 ProfileInfoCacheTest::SetUp();
148 service_
.reset(new NiceMock
<GAIAInfoUpdateServiceMock
>(profile()));
149 downloader_
.reset(new NiceMock
<ProfileDownloaderMock
>(service()));
152 void GAIAInfoUpdateServiceTest::TearDown() {
154 service_
->Shutdown();
156 ProfileInfoCacheTest::TearDown();
161 TEST_F(GAIAInfoUpdateServiceTest
, DownloadSuccess
) {
162 // No URL should be cached yet.
163 EXPECT_EQ(std::string(), service()->GetCachedPictureURL());
164 EXPECT_EQ(std::string(), profile()->GetPrefs()->
165 GetString(prefs::kGoogleServicesHostedDomain
));
167 base::string16 name
= base::ASCIIToUTF16("Pat Smith");
168 base::string16 given_name
= base::ASCIIToUTF16("Pat");
169 gfx::Image image
= gfx::test::CreateImage(256, 256);
170 std::string
url("foo.com");
171 base::string16
hosted_domain(base::ASCIIToUTF16(""));
172 ProfileDownloadSuccess(name
, given_name
, image
, url
, hosted_domain
);
174 // On success the GAIA info should be updated.
175 size_t index
= GetCache()->GetIndexOfProfileWithPath(profile()->GetPath());
176 EXPECT_EQ(name
, GetCache()->GetGAIANameOfProfileAtIndex(index
));
177 EXPECT_EQ(given_name
, GetCache()->GetGAIAGivenNameOfProfileAtIndex(index
));
178 EXPECT_TRUE(gfx::test::IsEqual(
179 image
, *GetCache()->GetGAIAPictureOfProfileAtIndex(index
)));
180 EXPECT_EQ(url
, service()->GetCachedPictureURL());
181 EXPECT_EQ(Profile::kNoHostedDomainFound
, profile()->GetPrefs()->
182 GetString(prefs::kGoogleServicesHostedDomain
));
185 TEST_F(GAIAInfoUpdateServiceTest
, DownloadFailure
) {
186 size_t index
= GetCache()->GetIndexOfProfileWithPath(profile()->GetPath());
187 base::string16 old_name
= GetCache()->GetNameOfProfileAtIndex(index
);
188 gfx::Image old_image
= GetCache()->GetAvatarIconOfProfileAtIndex(index
);
190 EXPECT_EQ(std::string(), service()->GetCachedPictureURL());
192 service()->OnProfileDownloadFailure(downloader(),
193 ProfileDownloaderDelegate::SERVICE_ERROR
);
195 // On failure nothing should be updated.
196 EXPECT_EQ(old_name
, GetCache()->GetNameOfProfileAtIndex(index
));
197 EXPECT_EQ(base::string16(), GetCache()->GetGAIANameOfProfileAtIndex(index
));
198 EXPECT_EQ(base::string16(),
199 GetCache()->GetGAIAGivenNameOfProfileAtIndex(index
));
200 EXPECT_TRUE(gfx::test::IsEqual(
201 old_image
, GetCache()->GetAvatarIconOfProfileAtIndex(index
)));
202 EXPECT_EQ(NULL
, GetCache()->GetGAIAPictureOfProfileAtIndex(index
));
203 EXPECT_EQ(std::string(), service()->GetCachedPictureURL());
204 EXPECT_EQ(std::string(),
205 profile()->GetPrefs()->GetString(prefs::kGoogleServicesHostedDomain
));
208 TEST_F(GAIAInfoUpdateServiceTest
, ProfileLockEnabledForWhitelist
) {
209 // No URL should be cached yet.
210 EXPECT_EQ(std::string(), service()->GetCachedPictureURL());
212 base::string16 name
= base::ASCIIToUTF16("Pat Smith");
213 base::string16 given_name
= base::ASCIIToUTF16("Pat");
214 gfx::Image image
= gfx::test::CreateImage(256, 256);
215 std::string
url("foo.com");
216 base::string16
hosted_domain(base::ASCIIToUTF16("google.com"));
217 ProfileDownloadSuccess(name
, given_name
, image
, url
, hosted_domain
);
219 EXPECT_EQ("google.com", profile()->GetPrefs()->
220 GetString(prefs::kGoogleServicesHostedDomain
));
223 TEST_F(GAIAInfoUpdateServiceTest
, HandlesProfileReordering
) {
224 size_t index
= GetCache()->GetIndexOfProfileWithPath(profile()->GetPath());
225 GetCache()->SetNameOfProfileAtIndex(index
, FullName16("B"));
226 GetCache()->SetProfileIsUsingDefaultNameAtIndex(index
, true);
228 CreateProfile(FullName("A"));
229 CreateProfile(FullName("C"));
230 CreateProfile(FullName("E"));
232 size_t index_before
=
233 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath());
235 // Rename our profile.
236 RenameProfile(FullName16("D"), GivenName16("D"));
237 // Profiles should have been reordered in the cache.
238 EXPECT_NE(index_before
,
239 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath()));
240 // Rename the profile back to the original name, it should go back to its
241 // original position.
242 RenameProfile(FullName16("B"), GivenName16("B"));
243 EXPECT_EQ(index_before
,
244 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath()));
246 // Rename only the given name of our profile.
247 RenameProfile(FullName16("B"), GivenName16("D"));
248 // Rename the profile back to the original name, it should go back to its
249 // original position.
250 RenameProfile(FullName16("B"), GivenName16("B"));
251 EXPECT_EQ(index_before
,
252 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath()));
254 // Rename only the full name of our profile.
255 RenameProfile(FullName16("D"), GivenName16("B"));
256 // Rename the profile back to the original name, it should go back to its
257 // original position.
258 RenameProfile(FullName16("B"), GivenName16("B"));
259 EXPECT_EQ(index_before
,
260 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath()));
263 TEST_F(GAIAInfoUpdateServiceTest
, ShouldUseGAIAProfileInfo
) {
264 #if defined(OS_CHROMEOS)
265 // This feature should never be enabled on ChromeOS.
266 EXPECT_FALSE(GAIAInfoUpdateService::ShouldUseGAIAProfileInfo(profile()));
270 TEST_F(GAIAInfoUpdateServiceTest
, ScheduleUpdate
) {
271 EXPECT_TRUE(service()->timer_
.IsRunning());
272 service()->timer_
.Stop();
273 EXPECT_FALSE(service()->timer_
.IsRunning());
274 service()->ScheduleNextUpdate();
275 EXPECT_TRUE(service()->timer_
.IsRunning());
278 #if !defined(OS_CHROMEOS)
280 TEST_F(GAIAInfoUpdateServiceTest
, LogOut
) {
281 SigninManager
* signin_manager
=
282 SigninManagerFactory::GetForProfile(profile());
283 signin_manager
->SetAuthenticatedUsername("pat@example.com");
284 base::string16 gaia_name
= base::UTF8ToUTF16("Pat Foo");
285 GetCache()->SetGAIANameOfProfileAtIndex(0, gaia_name
);
286 gfx::Image gaia_picture
= gfx::test::CreateImage(256,256);
287 GetCache()->SetGAIAPictureOfProfileAtIndex(0, &gaia_picture
);
289 // Set a fake picture URL.
290 profile()->GetPrefs()->SetString(prefs::kProfileGAIAInfoPictureURL
,
293 EXPECT_FALSE(service()->GetCachedPictureURL().empty());
296 signin_manager
->SignOut(signin_metrics::SIGNOUT_TEST
);
297 // Verify that the GAIA name and picture, and picture URL are unset.
298 EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(0).empty());
299 EXPECT_EQ(NULL
, GetCache()->GetGAIAPictureOfProfileAtIndex(0));
300 EXPECT_TRUE(service()->GetCachedPictureURL().empty());
303 TEST_F(GAIAInfoUpdateServiceTest
, LogIn
) {
305 EXPECT_CALL(*service(), Update());
306 SigninManager
* signin_manager
=
307 SigninManagerFactory::GetForProfile(profile());
308 signin_manager
->OnExternalSigninCompleted("pat@example.com");