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/account_tracker_service_factory.h"
16 #include "chrome/browser/signin/chrome_signin_client_factory.h"
17 #include "chrome/browser/signin/signin_manager_factory.h"
18 #include "chrome/browser/signin/test_signin_client_builder.h"
19 #include "chrome/common/pref_names.h"
20 #include "chrome/test/base/testing_browser_process.h"
21 #include "chrome/test/base/testing_profile.h"
22 #include "chrome/test/base/testing_profile_manager.h"
23 #include "components/signin/core/browser/account_tracker_service.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "ui/gfx/image/image.h"
26 #include "ui/gfx/image/image_unittest_util.h"
28 using ::testing::Return
;
29 using ::testing::NiceMock
;
33 class ProfileDownloaderMock
: public ProfileDownloader
{
35 explicit ProfileDownloaderMock(ProfileDownloaderDelegate
* delegate
)
36 : ProfileDownloader(delegate
) {
39 virtual ~ProfileDownloaderMock() {
42 MOCK_CONST_METHOD0(GetProfileFullName
, base::string16());
43 MOCK_CONST_METHOD0(GetProfileGivenName
, base::string16());
44 MOCK_CONST_METHOD0(GetProfilePicture
, SkBitmap());
45 MOCK_CONST_METHOD0(GetProfilePictureStatus
,
46 ProfileDownloader::PictureStatus());
47 MOCK_CONST_METHOD0(GetProfilePictureURL
, std::string());
48 MOCK_CONST_METHOD0(GetProfileHostedDomain
, base::string16());
51 class GAIAInfoUpdateServiceMock
: public GAIAInfoUpdateService
{
53 explicit GAIAInfoUpdateServiceMock(Profile
* profile
)
54 : GAIAInfoUpdateService(profile
) {
57 virtual ~GAIAInfoUpdateServiceMock() {
60 MOCK_METHOD0(Update
, void());
63 class GAIAInfoUpdateServiceTest
: public ProfileInfoCacheTest
{
65 GAIAInfoUpdateServiceTest() : profile_(NULL
) {
70 profile_
= CreateProfile("Person 1");
74 NiceMock
<GAIAInfoUpdateServiceMock
>* service() { return service_
.get(); }
75 NiceMock
<ProfileDownloaderMock
>* downloader() { return downloader_
.get(); }
77 Profile
* CreateProfile(const std::string
& name
) {
78 TestingProfile::TestingFactories testing_factories
;
79 testing_factories
.push_back(std::make_pair(
80 ChromeSigninClientFactory::GetInstance(),
81 signin::BuildTestSigninClient
));
82 Profile
* profile
= testing_profile_manager_
.CreateTestingProfile(name
,
83 scoped_ptr
<PrefServiceSyncable
>(), base::UTF8ToUTF16(name
), 0,
84 std::string(), testing_factories
);
85 // The testing manager sets the profile name manually, which counts as
86 // a user-customized profile name. Reset this to match the default name
87 // we are actually using.
88 size_t index
= GetCache()->GetIndexOfProfileWithPath(profile
->GetPath());
89 GetCache()->SetProfileIsUsingDefaultNameAtIndex(index
, true);
93 static std::string
GivenName(const std::string
& id
) {
96 static std::string
FullName(const std::string
& id
) {
97 return GivenName(id
) + " " + id
+ "last";
99 static base::string16
GivenName16(const std::string
& id
) {
100 return base::UTF8ToUTF16(GivenName(id
));
102 static base::string16
FullName16(const std::string
& id
) {
103 return base::UTF8ToUTF16(FullName(id
));
106 void ProfileDownloadSuccess(
107 const base::string16
& full_name
,
108 const base::string16
& given_name
,
109 const gfx::Image
& image
,
110 const std::string
& url
,
111 const base::string16
& hosted_domain
) {
112 EXPECT_CALL(*downloader(), GetProfileFullName()).
113 WillOnce(Return(full_name
));
114 EXPECT_CALL(*downloader(), GetProfileGivenName()).
115 WillOnce(Return(given_name
));
116 const SkBitmap
* bmp
= image
.ToSkBitmap();
117 EXPECT_CALL(*downloader(), GetProfilePicture()).WillOnce(Return(*bmp
));
118 EXPECT_CALL(*downloader(), GetProfilePictureStatus()).
119 WillOnce(Return(ProfileDownloader::PICTURE_SUCCESS
));
120 EXPECT_CALL(*downloader(), GetProfilePictureURL()).WillOnce(Return(url
));
121 EXPECT_CALL(*downloader(), GetProfileHostedDomain()).
122 WillOnce(Return(hosted_domain
));
124 service()->OnProfileDownloadSuccess(downloader());
127 void RenameProfile(const base::string16
& full_name
,
128 const base::string16
& given_name
) {
129 gfx::Image image
= gfx::test::CreateImage(256,256);
130 std::string
url("foo.com");
131 ProfileDownloadSuccess(full_name
, given_name
, image
, url
, base::string16());
133 // Make sure the right profile was updated correctly.
134 size_t index
= GetCache()->GetIndexOfProfileWithPath(profile()->GetPath());
135 EXPECT_EQ(full_name
, GetCache()->GetGAIANameOfProfileAtIndex(index
));
136 EXPECT_EQ(given_name
, GetCache()->GetGAIAGivenNameOfProfileAtIndex(index
));
140 void SetUp() override
;
141 void TearDown() override
;
144 scoped_ptr
<NiceMock
<GAIAInfoUpdateServiceMock
> > service_
;
145 scoped_ptr
<NiceMock
<ProfileDownloaderMock
> > downloader_
;
148 void GAIAInfoUpdateServiceTest::SetUp() {
149 ProfileInfoCacheTest::SetUp();
150 service_
.reset(new NiceMock
<GAIAInfoUpdateServiceMock
>(profile()));
151 downloader_
.reset(new NiceMock
<ProfileDownloaderMock
>(service()));
154 void GAIAInfoUpdateServiceTest::TearDown() {
156 service_
->Shutdown();
158 ProfileInfoCacheTest::TearDown();
163 TEST_F(GAIAInfoUpdateServiceTest
, DownloadSuccess
) {
164 // No URL should be cached yet.
165 EXPECT_EQ(std::string(), service()->GetCachedPictureURL());
166 EXPECT_EQ(std::string(), profile()->GetPrefs()->
167 GetString(prefs::kGoogleServicesHostedDomain
));
169 base::string16 name
= base::ASCIIToUTF16("Pat Smith");
170 base::string16 given_name
= base::ASCIIToUTF16("Pat");
171 gfx::Image image
= gfx::test::CreateImage(256, 256);
172 std::string
url("foo.com");
173 base::string16
hosted_domain(base::ASCIIToUTF16(""));
174 ProfileDownloadSuccess(name
, given_name
, image
, url
, hosted_domain
);
176 // On success the GAIA info should be updated.
177 size_t index
= GetCache()->GetIndexOfProfileWithPath(profile()->GetPath());
178 EXPECT_EQ(name
, GetCache()->GetGAIANameOfProfileAtIndex(index
));
179 EXPECT_EQ(given_name
, GetCache()->GetGAIAGivenNameOfProfileAtIndex(index
));
180 EXPECT_TRUE(gfx::test::IsEqual(
181 image
, *GetCache()->GetGAIAPictureOfProfileAtIndex(index
)));
182 EXPECT_EQ(url
, service()->GetCachedPictureURL());
183 EXPECT_EQ(Profile::kNoHostedDomainFound
, profile()->GetPrefs()->
184 GetString(prefs::kGoogleServicesHostedDomain
));
187 TEST_F(GAIAInfoUpdateServiceTest
, DownloadFailure
) {
188 size_t index
= GetCache()->GetIndexOfProfileWithPath(profile()->GetPath());
189 base::string16 old_name
= GetCache()->GetNameOfProfileAtIndex(index
);
190 gfx::Image old_image
= GetCache()->GetAvatarIconOfProfileAtIndex(index
);
192 EXPECT_EQ(std::string(), service()->GetCachedPictureURL());
194 service()->OnProfileDownloadFailure(downloader(),
195 ProfileDownloaderDelegate::SERVICE_ERROR
);
197 // On failure nothing should be updated.
198 EXPECT_EQ(old_name
, GetCache()->GetNameOfProfileAtIndex(index
));
199 EXPECT_EQ(base::string16(), GetCache()->GetGAIANameOfProfileAtIndex(index
));
200 EXPECT_EQ(base::string16(),
201 GetCache()->GetGAIAGivenNameOfProfileAtIndex(index
));
202 EXPECT_TRUE(gfx::test::IsEqual(
203 old_image
, GetCache()->GetAvatarIconOfProfileAtIndex(index
)));
204 EXPECT_EQ(NULL
, GetCache()->GetGAIAPictureOfProfileAtIndex(index
));
205 EXPECT_EQ(std::string(), service()->GetCachedPictureURL());
206 EXPECT_EQ(std::string(),
207 profile()->GetPrefs()->GetString(prefs::kGoogleServicesHostedDomain
));
210 TEST_F(GAIAInfoUpdateServiceTest
, ProfileLockEnabledForWhitelist
) {
211 // No URL should be cached yet.
212 EXPECT_EQ(std::string(), service()->GetCachedPictureURL());
214 base::string16 name
= base::ASCIIToUTF16("Pat Smith");
215 base::string16 given_name
= base::ASCIIToUTF16("Pat");
216 gfx::Image image
= gfx::test::CreateImage(256, 256);
217 std::string
url("foo.com");
218 base::string16
hosted_domain(base::ASCIIToUTF16("google.com"));
219 ProfileDownloadSuccess(name
, given_name
, image
, url
, hosted_domain
);
221 EXPECT_EQ("google.com", profile()->GetPrefs()->
222 GetString(prefs::kGoogleServicesHostedDomain
));
225 TEST_F(GAIAInfoUpdateServiceTest
, HandlesProfileReordering
) {
226 size_t index
= GetCache()->GetIndexOfProfileWithPath(profile()->GetPath());
227 GetCache()->SetNameOfProfileAtIndex(index
, FullName16("B"));
228 GetCache()->SetProfileIsUsingDefaultNameAtIndex(index
, true);
230 CreateProfile(FullName("A"));
231 CreateProfile(FullName("C"));
232 CreateProfile(FullName("E"));
234 size_t index_before
=
235 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath());
237 // Rename our profile.
238 RenameProfile(FullName16("D"), GivenName16("D"));
239 // Profiles should have been reordered in the cache.
240 EXPECT_NE(index_before
,
241 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath()));
242 // Rename the profile back to the original name, it should go back to its
243 // original position.
244 RenameProfile(FullName16("B"), GivenName16("B"));
245 EXPECT_EQ(index_before
,
246 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath()));
248 // Rename only the given name of our profile.
249 RenameProfile(FullName16("B"), GivenName16("D"));
250 // Rename the profile back to the original name, it should go back to its
251 // original position.
252 RenameProfile(FullName16("B"), GivenName16("B"));
253 EXPECT_EQ(index_before
,
254 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath()));
256 // Rename only the full name of our profile.
257 RenameProfile(FullName16("D"), GivenName16("B"));
258 // Rename the profile back to the original name, it should go back to its
259 // original position.
260 RenameProfile(FullName16("B"), GivenName16("B"));
261 EXPECT_EQ(index_before
,
262 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath()));
265 TEST_F(GAIAInfoUpdateServiceTest
, ShouldUseGAIAProfileInfo
) {
266 #if defined(OS_CHROMEOS)
267 // This feature should never be enabled on ChromeOS.
268 EXPECT_FALSE(GAIAInfoUpdateService::ShouldUseGAIAProfileInfo(profile()));
272 TEST_F(GAIAInfoUpdateServiceTest
, ScheduleUpdate
) {
273 EXPECT_TRUE(service()->timer_
.IsRunning());
274 service()->timer_
.Stop();
275 EXPECT_FALSE(service()->timer_
.IsRunning());
276 service()->ScheduleNextUpdate();
277 EXPECT_TRUE(service()->timer_
.IsRunning());
280 #if !defined(OS_CHROMEOS)
282 TEST_F(GAIAInfoUpdateServiceTest
, LogOut
) {
283 SigninManager
* signin_manager
=
284 SigninManagerFactory::GetForProfile(profile());
285 signin_manager
->SetAuthenticatedAccountInfo("gaia_id", "pat@example.com");
286 base::string16 gaia_name
= base::UTF8ToUTF16("Pat Foo");
287 GetCache()->SetGAIANameOfProfileAtIndex(0, gaia_name
);
288 gfx::Image gaia_picture
= gfx::test::CreateImage(256,256);
289 GetCache()->SetGAIAPictureOfProfileAtIndex(0, &gaia_picture
);
291 // Set a fake picture URL.
292 profile()->GetPrefs()->SetString(prefs::kProfileGAIAInfoPictureURL
,
295 EXPECT_FALSE(service()->GetCachedPictureURL().empty());
298 signin_manager
->SignOut(signin_metrics::SIGNOUT_TEST
);
299 // Verify that the GAIA name and picture, and picture URL are unset.
300 EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(0).empty());
301 EXPECT_EQ(NULL
, GetCache()->GetGAIAPictureOfProfileAtIndex(0));
302 EXPECT_TRUE(service()->GetCachedPictureURL().empty());
305 TEST_F(GAIAInfoUpdateServiceTest
, LogIn
) {
307 EXPECT_CALL(*service(), Update());
308 AccountTrackerServiceFactory::GetForProfile(profile())
309 ->SeedAccountInfo("gaia_id", "pat@example.com");
310 SigninManager
* signin_manager
=
311 SigninManagerFactory::GetForProfile(profile());
312 signin_manager
->OnExternalSigninCompleted("pat@example.com");