1 // Copyright 2014 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/signin/mutable_profile_oauth2_token_service_delegate.h"
7 #include "base/run_loop.h"
8 #include "base/prefs/pref_registry_simple.h"
9 #include "base/prefs/scoped_user_pref_update.h"
10 #include "base/prefs/testing_pref_service.h"
11 #include "components/signin/core/browser/profile_oauth2_token_service.h"
12 #include "components/signin/core/browser/signin_error_controller.h"
13 #include "components/signin/core/browser/test_signin_client.h"
14 #include "components/signin/core/browser/webdata/token_web_data.h"
15 #include "components/signin/core/common/signin_pref_names.h"
16 #include "google_apis/gaia/gaia_constants.h"
17 #include "google_apis/gaia/gaia_urls.h"
18 #include "google_apis/gaia/google_service_auth_error.h"
19 #include "google_apis/gaia/oauth2_access_token_consumer.h"
20 #include "google_apis/gaia/oauth2_token_service_test_util.h"
21 #include "net/http/http_status_code.h"
22 #include "net/url_request/test_url_fetcher_factory.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 #if defined(OS_MACOSX)
26 #include "components/os_crypt/os_crypt.h"
29 // Defining constant here to handle backward compatiblity tests, but this
30 // constant is no longer used in current versions of chrome.
31 static const char kLSOService
[] = "lso";
32 static const char kEmail
[] = "user@gmail.com";
34 class MutableProfileOAuth2TokenServiceDelegateTest
35 : public testing::Test
,
36 public OAuth2AccessTokenConsumer
,
37 public OAuth2TokenService::Observer
{
39 MutableProfileOAuth2TokenServiceDelegateTest()
41 access_token_success_count_(0),
42 access_token_failure_count_(0),
43 access_token_failure_(GoogleServiceAuthError::NONE
),
44 token_available_count_(0),
45 token_revoked_count_(0),
46 tokens_loaded_count_(0),
47 start_batch_changes_(0),
48 end_batch_changes_(0) {}
50 void SetUp() override
{
51 #if defined(OS_MACOSX)
52 OSCrypt::UseMockKeychain(true);
55 factory_
.SetFakeResponse(GaiaUrls::GetInstance()->oauth2_revoke_url(), "",
56 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
58 pref_service_
.registry()->RegisterListPref(
59 AccountTrackerService::kAccountInfoPref
);
60 pref_service_
.registry()->RegisterIntegerPref(
61 prefs::kAccountIdMigrationState
,
62 AccountTrackerService::MIGRATION_NOT_STARTED
);
63 client_
.reset(new TestSigninClient(&pref_service_
));
64 client_
->SetURLRequestContext(new net::TestURLRequestContextGetter(
65 base::ThreadTaskRunnerHandle::Get()));
66 client_
->LoadTokenDatabase();
67 account_tracker_service_
.Initialize(client_
.get());
68 oauth2_service_delegate_
.reset(new MutableProfileOAuth2TokenServiceDelegate(
69 client_
.get(), &signin_error_controller_
, &account_tracker_service_
));
70 // Make sure PO2TS has a chance to load itself before continuing.
71 base::RunLoop().RunUntilIdle();
72 oauth2_service_delegate_
->AddObserver(this);
75 void TearDown() override
{
76 oauth2_service_delegate_
->RemoveObserver(this);
77 oauth2_service_delegate_
->Shutdown();
80 void AddAuthTokenManually(const std::string
& service
,
81 const std::string
& value
) {
82 scoped_refptr
<TokenWebData
> token_web_data
= client_
->GetDatabase();
83 if (token_web_data
.get())
84 token_web_data
->SetTokenForService(service
, value
);
87 // OAuth2AccessTokenConusmer implementation
88 void OnGetTokenSuccess(const std::string
& access_token
,
89 const base::Time
& expiration_time
) override
{
90 ++access_token_success_count_
;
93 void OnGetTokenFailure(const GoogleServiceAuthError
& error
) override
{
94 ++access_token_failure_count_
;
95 access_token_failure_
= error
;
98 // OAuth2TokenService::Observer implementation.
99 void OnRefreshTokenAvailable(const std::string
& account_id
) override
{
100 ++token_available_count_
;
102 void OnRefreshTokenRevoked(const std::string
& account_id
) override
{
103 ++token_revoked_count_
;
105 void OnRefreshTokensLoaded() override
{ ++tokens_loaded_count_
; }
107 void OnStartBatchChanges() override
{ ++start_batch_changes_
; }
109 void OnEndBatchChanges() override
{ ++end_batch_changes_
; }
111 void ResetObserverCounts() {
112 token_available_count_
= 0;
113 token_revoked_count_
= 0;
114 tokens_loaded_count_
= 0;
115 start_batch_changes_
= 0;
116 end_batch_changes_
= 0;
119 void ExpectNoNotifications() {
120 EXPECT_EQ(0, token_available_count_
);
121 EXPECT_EQ(0, token_revoked_count_
);
122 EXPECT_EQ(0, tokens_loaded_count_
);
123 ResetObserverCounts();
126 void ExpectOneTokenAvailableNotification() {
127 EXPECT_EQ(1, token_available_count_
);
128 EXPECT_EQ(0, token_revoked_count_
);
129 EXPECT_EQ(0, tokens_loaded_count_
);
130 ResetObserverCounts();
133 void ExpectOneTokenRevokedNotification() {
134 EXPECT_EQ(0, token_available_count_
);
135 EXPECT_EQ(1, token_revoked_count_
);
136 EXPECT_EQ(0, tokens_loaded_count_
);
137 ResetObserverCounts();
140 void ExpectOneTokensLoadedNotification() {
141 EXPECT_EQ(0, token_available_count_
);
142 EXPECT_EQ(0, token_revoked_count_
);
143 EXPECT_EQ(1, tokens_loaded_count_
);
144 ResetObserverCounts();
148 base::MessageLoop message_loop_
;
149 net::FakeURLFetcherFactory factory_
;
150 scoped_ptr
<TestSigninClient
> client_
;
151 scoped_ptr
<MutableProfileOAuth2TokenServiceDelegate
> oauth2_service_delegate_
;
152 TestingOAuth2TokenServiceConsumer consumer_
;
153 SigninErrorController signin_error_controller_
;
154 TestingPrefServiceSimple pref_service_
;
155 AccountTrackerService account_tracker_service_
;
156 int access_token_success_count_
;
157 int access_token_failure_count_
;
158 GoogleServiceAuthError access_token_failure_
;
159 int token_available_count_
;
160 int token_revoked_count_
;
161 int tokens_loaded_count_
;
162 int start_batch_changes_
;
163 int end_batch_changes_
;
166 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest
, PersistenceDBUpgrade
) {
167 std::string
main_account_id(kEmail
);
168 std::string
main_refresh_token("old_refresh_token");
170 // Populate DB with legacy tokens.
171 AddAuthTokenManually(GaiaConstants::kSyncService
, "syncServiceToken");
172 AddAuthTokenManually(kLSOService
, "lsoToken");
173 AddAuthTokenManually(GaiaConstants::kGaiaOAuth2LoginRefreshToken
,
176 // Force LoadCredentials.
177 oauth2_service_delegate_
->LoadCredentials(main_account_id
);
178 base::RunLoop().RunUntilIdle();
180 // Legacy tokens get discarded, but the old refresh token is kept.
181 EXPECT_EQ(1, tokens_loaded_count_
);
182 EXPECT_EQ(1, token_available_count_
);
183 EXPECT_EQ(1, start_batch_changes_
);
184 EXPECT_EQ(1, end_batch_changes_
);
186 oauth2_service_delegate_
->RefreshTokenIsAvailable(main_account_id
));
187 EXPECT_EQ(1U, oauth2_service_delegate_
->refresh_tokens_
.size());
188 EXPECT_EQ(main_refresh_token
,
189 oauth2_service_delegate_
->refresh_tokens_
[main_account_id
]
192 // Add an old legacy token to the DB, to ensure it will not overwrite existing
193 // credentials for main account.
194 AddAuthTokenManually(GaiaConstants::kGaiaOAuth2LoginRefreshToken
,
195 "secondOldRefreshToken");
196 // Add some other legacy token. (Expected to get discarded).
197 AddAuthTokenManually(kLSOService
, "lsoToken");
198 // Also add a token using PO2TS.UpdateCredentials and make sure upgrade does
200 std::string
other_account_id("other_account_id");
201 std::string
other_refresh_token("other_refresh_token");
202 oauth2_service_delegate_
->UpdateCredentials(other_account_id
,
203 other_refresh_token
);
204 ResetObserverCounts();
206 // Force LoadCredentials.
207 oauth2_service_delegate_
->LoadCredentials(main_account_id
);
208 base::RunLoop().RunUntilIdle();
210 // Again legacy tokens get discarded, but since the main porfile account
211 // token is present it is not overwritten.
212 EXPECT_EQ(2, token_available_count_
);
213 EXPECT_EQ(1, tokens_loaded_count_
);
214 EXPECT_EQ(1, start_batch_changes_
);
215 EXPECT_EQ(1, end_batch_changes_
);
216 EXPECT_EQ(main_refresh_token
,
217 oauth2_service_delegate_
->GetRefreshToken(main_account_id
));
219 oauth2_service_delegate_
->RefreshTokenIsAvailable(main_account_id
));
220 // TODO(fgorski): cover both using RefreshTokenIsAvailable() and then get the
221 // tokens using GetRefreshToken()
222 EXPECT_EQ(2U, oauth2_service_delegate_
->refresh_tokens_
.size());
223 EXPECT_EQ(main_refresh_token
,
224 oauth2_service_delegate_
->refresh_tokens_
[main_account_id
]
226 EXPECT_EQ(other_refresh_token
,
227 oauth2_service_delegate_
->refresh_tokens_
[other_account_id
]
230 oauth2_service_delegate_
->RevokeAllCredentials();
231 EXPECT_EQ(2, start_batch_changes_
);
232 EXPECT_EQ(2, end_batch_changes_
);
235 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest
,
236 PersistenceRevokeCredentials
) {
237 std::string account_id_1
= "account_id_1";
238 std::string refresh_token_1
= "refresh_token_1";
239 std::string account_id_2
= "account_id_2";
240 std::string refresh_token_2
= "refresh_token_2";
242 // TODO(fgorski): Enable below when implemented:
243 // EXPECT_FALSE(oauth2_servive_->RefreshTokenIsAvailable(account_id_1));
244 // EXPECT_FALSE(oauth2_servive_->RefreshTokenIsAvailable(account_id_2));
246 oauth2_service_delegate_
->UpdateCredentials(account_id_1
, refresh_token_1
);
247 oauth2_service_delegate_
->UpdateCredentials(account_id_2
, refresh_token_2
);
248 EXPECT_EQ(2, start_batch_changes_
);
249 EXPECT_EQ(2, end_batch_changes_
);
251 // TODO(fgorski): Enable below when implemented:
252 // EXPECT_TRUE(oauth2_servive_->RefreshTokenIsAvailable(account_id_1));
253 EXPECT_TRUE(oauth2_service_delegate_
->RefreshTokenIsAvailable(account_id_2
));
255 ResetObserverCounts();
256 oauth2_service_delegate_
->RevokeCredentials(account_id_1
);
257 EXPECT_EQ(1, start_batch_changes_
);
258 EXPECT_EQ(1, end_batch_changes_
);
259 ExpectOneTokenRevokedNotification();
261 // TODO(fgorski): Enable below when implemented:
262 // EXPECT_FALSE(oauth2_servive_->RefreshTokenIsAvailable(account_id_1));
263 EXPECT_TRUE(oauth2_service_delegate_
->RefreshTokenIsAvailable(account_id_2
));
265 oauth2_service_delegate_
->RevokeAllCredentials();
266 EXPECT_EQ(0, token_available_count_
);
267 EXPECT_EQ(1, token_revoked_count_
);
268 EXPECT_EQ(0, tokens_loaded_count_
);
269 EXPECT_EQ(1, start_batch_changes_
);
270 EXPECT_EQ(1, end_batch_changes_
);
271 ResetObserverCounts();
274 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest
,
275 PersistenceLoadCredentials
) {
276 // Ensure DB is clean.
277 oauth2_service_delegate_
->RevokeAllCredentials();
278 ResetObserverCounts();
279 // Perform a load from an empty DB.
280 oauth2_service_delegate_
->LoadCredentials("account_id");
281 base::RunLoop().RunUntilIdle();
282 EXPECT_EQ(1, start_batch_changes_
);
283 EXPECT_EQ(1, end_batch_changes_
);
284 ExpectOneTokensLoadedNotification();
285 // LoadCredentials() guarantees that the account given to it as argument
286 // is in the refresh_token map.
287 EXPECT_EQ(1U, oauth2_service_delegate_
->refresh_tokens_
.size());
288 EXPECT_TRUE(oauth2_service_delegate_
->refresh_tokens_
["account_id"]
291 // Setup a DB with tokens that don't require upgrade and clear memory.
292 oauth2_service_delegate_
->UpdateCredentials("account_id", "refresh_token");
293 oauth2_service_delegate_
->UpdateCredentials("account_id2", "refresh_token2");
294 oauth2_service_delegate_
->refresh_tokens_
.clear();
295 EXPECT_EQ(2, start_batch_changes_
);
296 EXPECT_EQ(2, end_batch_changes_
);
297 ResetObserverCounts();
299 oauth2_service_delegate_
->LoadCredentials("account_id");
300 base::RunLoop().RunUntilIdle();
301 EXPECT_EQ(2, token_available_count_
);
302 EXPECT_EQ(0, token_revoked_count_
);
303 EXPECT_EQ(1, tokens_loaded_count_
);
304 EXPECT_EQ(1, start_batch_changes_
);
305 EXPECT_EQ(1, end_batch_changes_
);
306 ResetObserverCounts();
308 // TODO(fgorski): Enable below when implemented:
309 // EXPECT_TRUE(oauth2_servive_->RefreshTokenIsAvailable("account_id"));
310 EXPECT_TRUE(oauth2_service_delegate_
->RefreshTokenIsAvailable("account_id2"));
312 oauth2_service_delegate_
->RevokeAllCredentials();
313 EXPECT_EQ(0, token_available_count_
);
314 EXPECT_EQ(2, token_revoked_count_
);
315 EXPECT_EQ(0, tokens_loaded_count_
);
316 EXPECT_EQ(1, start_batch_changes_
);
317 EXPECT_EQ(1, end_batch_changes_
);
318 ResetObserverCounts();
321 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest
, PersistanceNotifications
) {
322 oauth2_service_delegate_
->UpdateCredentials("account_id", "refresh_token");
323 ExpectOneTokenAvailableNotification();
325 oauth2_service_delegate_
->UpdateCredentials("account_id", "refresh_token");
326 ExpectNoNotifications();
328 oauth2_service_delegate_
->UpdateCredentials("account_id", "refresh_token2");
329 ExpectOneTokenAvailableNotification();
331 oauth2_service_delegate_
->RevokeCredentials("account_id");
332 ExpectOneTokenRevokedNotification();
334 oauth2_service_delegate_
->UpdateCredentials("account_id", "refresh_token2");
335 ExpectOneTokenAvailableNotification();
337 oauth2_service_delegate_
->RevokeAllCredentials();
338 ResetObserverCounts();
341 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest
, GetAccounts
) {
342 EXPECT_TRUE(oauth2_service_delegate_
->GetAccounts().empty());
343 oauth2_service_delegate_
->UpdateCredentials("account_id1", "refresh_token1");
344 oauth2_service_delegate_
->UpdateCredentials("account_id2", "refresh_token2");
345 std::vector
<std::string
> accounts
= oauth2_service_delegate_
->GetAccounts();
346 EXPECT_EQ(2u, accounts
.size());
347 EXPECT_EQ(1, count(accounts
.begin(), accounts
.end(), "account_id1"));
348 EXPECT_EQ(1, count(accounts
.begin(), accounts
.end(), "account_id2"));
349 oauth2_service_delegate_
->RevokeCredentials("account_id2");
350 accounts
= oauth2_service_delegate_
->GetAccounts();
351 EXPECT_EQ(1u, oauth2_service_delegate_
->GetAccounts().size());
352 EXPECT_EQ(1, count(accounts
.begin(), accounts
.end(), "account_id1"));
355 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest
, FetchPersistentError
) {
356 oauth2_service_delegate_
->UpdateCredentials(kEmail
, "refreshToken");
357 EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
358 signin_error_controller_
.auth_error());
360 GoogleServiceAuthError
authfail(GoogleServiceAuthError::ACCOUNT_DELETED
);
361 oauth2_service_delegate_
->UpdateAuthError(kEmail
, authfail
);
362 EXPECT_NE(GoogleServiceAuthError::AuthErrorNone(),
363 signin_error_controller_
.auth_error());
365 // Create a "success" fetch we don't expect to get called.
366 factory_
.SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_url(),
367 GetValidTokenResponse("token", 3600), net::HTTP_OK
,
368 net::URLRequestStatus::SUCCESS
);
370 EXPECT_EQ(0, access_token_success_count_
);
371 EXPECT_EQ(0, access_token_failure_count_
);
372 std::vector
<std::string
> scope_list
;
373 scope_list
.push_back("scope");
374 scoped_ptr
<OAuth2AccessTokenFetcher
> fetcher(
375 oauth2_service_delegate_
->CreateAccessTokenFetcher(
376 kEmail
, oauth2_service_delegate_
->GetRequestContext(), this));
377 fetcher
->Start("foo", "bar", scope_list
);
378 base::RunLoop().RunUntilIdle();
379 EXPECT_EQ(0, access_token_success_count_
);
380 EXPECT_EQ(1, access_token_failure_count_
);
383 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest
, RetryBackoff
) {
384 oauth2_service_delegate_
->UpdateCredentials(kEmail
, "refreshToken");
385 EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
386 signin_error_controller_
.auth_error());
388 GoogleServiceAuthError
authfail(GoogleServiceAuthError::SERVICE_UNAVAILABLE
);
389 oauth2_service_delegate_
->UpdateAuthError(kEmail
, authfail
);
390 EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
391 signin_error_controller_
.auth_error());
393 // Create a "success" fetch we don't expect to get called just yet.
394 factory_
.SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_url(),
395 GetValidTokenResponse("token", 3600), net::HTTP_OK
,
396 net::URLRequestStatus::SUCCESS
);
398 // Transient error will repeat until backoff period expires.
399 EXPECT_EQ(0, access_token_success_count_
);
400 EXPECT_EQ(0, access_token_failure_count_
);
401 std::vector
<std::string
> scope_list
;
402 scope_list
.push_back("scope");
403 scoped_ptr
<OAuth2AccessTokenFetcher
> fetcher1(
404 oauth2_service_delegate_
->CreateAccessTokenFetcher(
405 kEmail
, oauth2_service_delegate_
->GetRequestContext(), this));
406 fetcher1
->Start("foo", "bar", scope_list
);
407 base::RunLoop().RunUntilIdle();
408 EXPECT_EQ(0, access_token_success_count_
);
409 EXPECT_EQ(1, access_token_failure_count_
);
411 // Pretend that backoff has expired and try again.
412 oauth2_service_delegate_
->backoff_entry_
.SetCustomReleaseTime(
414 scoped_ptr
<OAuth2AccessTokenFetcher
> fetcher2(
415 oauth2_service_delegate_
->CreateAccessTokenFetcher(
416 kEmail
, oauth2_service_delegate_
->GetRequestContext(), this));
417 fetcher2
->Start("foo", "bar", scope_list
);
418 base::RunLoop().RunUntilIdle();
419 EXPECT_EQ(1, access_token_success_count_
);
420 EXPECT_EQ(1, access_token_failure_count_
);
423 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest
, CanonicalizeAccountId
) {
424 std::map
<std::string
, std::string
> tokens
;
425 tokens
["AccountId-user@gmail.com"] = "refresh_token";
426 tokens
["AccountId-Foo.Bar@gmail.com"] = "refresh_token";
427 tokens
["AccountId-12345"] = "refresh_token";
429 oauth2_service_delegate_
->LoadAllCredentialsIntoMemory(tokens
);
432 oauth2_service_delegate_
->RefreshTokenIsAvailable("user@gmail.com"));
434 oauth2_service_delegate_
->RefreshTokenIsAvailable("foobar@gmail.com"));
435 EXPECT_TRUE(oauth2_service_delegate_
->RefreshTokenIsAvailable("12345"));
438 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest
,
439 CanonAndNonCanonAccountId
) {
440 std::map
<std::string
, std::string
> tokens
;
441 tokens
["AccountId-Foo.Bar@gmail.com"] = "bad_token";
442 tokens
["AccountId-foobar@gmail.com"] = "good_token";
444 oauth2_service_delegate_
->LoadAllCredentialsIntoMemory(tokens
);
446 EXPECT_EQ(1u, oauth2_service_delegate_
->GetAccounts().size());
448 oauth2_service_delegate_
->RefreshTokenIsAvailable("foobar@gmail.com"));
451 oauth2_service_delegate_
->GetRefreshToken("foobar@gmail.com").c_str());
454 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest
, ShutdownService
) {
455 EXPECT_TRUE(oauth2_service_delegate_
->GetAccounts().empty());
456 oauth2_service_delegate_
->UpdateCredentials("account_id1", "refresh_token1");
457 oauth2_service_delegate_
->UpdateCredentials("account_id2", "refresh_token2");
458 std::vector
<std::string
> accounts
= oauth2_service_delegate_
->GetAccounts();
459 EXPECT_EQ(2u, accounts
.size());
460 EXPECT_EQ(1, count(accounts
.begin(), accounts
.end(), "account_id1"));
461 EXPECT_EQ(1, count(accounts
.begin(), accounts
.end(), "account_id2"));
462 oauth2_service_delegate_
->LoadCredentials("account_id1");
463 oauth2_service_delegate_
->UpdateCredentials("account_id1", "refresh_token3");
464 oauth2_service_delegate_
->Shutdown();
465 EXPECT_TRUE(oauth2_service_delegate_
->server_revokes_
.empty());
466 EXPECT_TRUE(oauth2_service_delegate_
->refresh_tokens_
.empty());
467 EXPECT_EQ(0, oauth2_service_delegate_
->web_data_service_request_
);
470 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest
, GaiaIdMigration
) {
471 if (account_tracker_service_
.GetMigrationState() !=
472 AccountTrackerService::MIGRATION_NOT_STARTED
) {
473 std::string email
= "foo@gmail.com";
474 std::string gaia_id
= "foo's gaia id";
476 pref_service_
.SetInteger(prefs::kAccountIdMigrationState
,
477 AccountTrackerService::MIGRATION_NOT_STARTED
);
479 ListPrefUpdate
update(&pref_service_
,
480 AccountTrackerService::kAccountInfoPref
);
482 base::DictionaryValue
* dict
= new base::DictionaryValue();
483 update
->Append(dict
);
484 dict
->SetString("account_id", base::UTF8ToUTF16(email
));
485 dict
->SetString("email", base::UTF8ToUTF16(email
));
486 dict
->SetString("gaia", base::UTF8ToUTF16(gaia_id
));
487 account_tracker_service_
.Shutdown();
488 account_tracker_service_
.Initialize(client_
.get());
490 AddAuthTokenManually("AccountId-" + email
, "refresh_token");
491 oauth2_service_delegate_
->LoadCredentials(gaia_id
);
492 base::RunLoop().RunUntilIdle();
494 EXPECT_EQ(1, tokens_loaded_count_
);
495 EXPECT_EQ(1, token_available_count_
);
496 EXPECT_EQ(1, start_batch_changes_
);
497 EXPECT_EQ(1, end_batch_changes_
);
499 std::vector
<std::string
> accounts
= oauth2_service_delegate_
->GetAccounts();
500 EXPECT_EQ(1u, accounts
.size());
502 EXPECT_FALSE(oauth2_service_delegate_
->RefreshTokenIsAvailable(email
));
503 EXPECT_TRUE(oauth2_service_delegate_
->RefreshTokenIsAvailable(gaia_id
));
505 account_tracker_service_
.SetMigrationDone();
506 oauth2_service_delegate_
->Shutdown();
507 ResetObserverCounts();
509 oauth2_service_delegate_
->LoadCredentials(gaia_id
);
510 base::RunLoop().RunUntilIdle();
512 EXPECT_EQ(1, tokens_loaded_count_
);
513 EXPECT_EQ(1, token_available_count_
);
514 EXPECT_EQ(1, start_batch_changes_
);
515 EXPECT_EQ(1, end_batch_changes_
);
517 EXPECT_FALSE(oauth2_service_delegate_
->RefreshTokenIsAvailable(email
));
518 EXPECT_TRUE(oauth2_service_delegate_
->RefreshTokenIsAvailable(gaia_id
));
519 accounts
= oauth2_service_delegate_
->GetAccounts();
520 EXPECT_EQ(1u, accounts
.size());
524 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest
,
525 GaiaIdMigrationCrashInTheMiddle
) {
526 if (account_tracker_service_
.GetMigrationState() !=
527 AccountTrackerService::MIGRATION_NOT_STARTED
) {
528 std::string email1
= "foo@gmail.com";
529 std::string gaia_id1
= "foo's gaia id";
530 std::string email2
= "bar@gmail.com";
531 std::string gaia_id2
= "bar's gaia id";
533 pref_service_
.SetInteger(prefs::kAccountIdMigrationState
,
534 AccountTrackerService::MIGRATION_NOT_STARTED
);
536 ListPrefUpdate
update(&pref_service_
,
537 AccountTrackerService::kAccountInfoPref
);
539 base::DictionaryValue
* dict
= new base::DictionaryValue();
540 update
->Append(dict
);
541 dict
->SetString("account_id", base::UTF8ToUTF16(email1
));
542 dict
->SetString("email", base::UTF8ToUTF16(email1
));
543 dict
->SetString("gaia", base::UTF8ToUTF16(gaia_id1
));
544 dict
= new base::DictionaryValue();
545 update
->Append(dict
);
546 dict
->SetString("account_id", base::UTF8ToUTF16(email2
));
547 dict
->SetString("email", base::UTF8ToUTF16(email2
));
548 dict
->SetString("gaia", base::UTF8ToUTF16(gaia_id2
));
549 account_tracker_service_
.Shutdown();
550 account_tracker_service_
.Initialize(client_
.get());
552 AddAuthTokenManually("AccountId-" + email1
, "refresh_token");
553 AddAuthTokenManually("AccountId-" + email2
, "refresh_token");
554 AddAuthTokenManually("AccountId-" + gaia_id1
, "refresh_token");
555 oauth2_service_delegate_
->LoadCredentials(gaia_id1
);
556 base::RunLoop().RunUntilIdle();
558 EXPECT_EQ(1, tokens_loaded_count_
);
559 EXPECT_EQ(2, token_available_count_
);
560 EXPECT_EQ(1, start_batch_changes_
);
561 EXPECT_EQ(1, end_batch_changes_
);
563 std::vector
<std::string
> accounts
= oauth2_service_delegate_
->GetAccounts();
564 EXPECT_EQ(2u, accounts
.size());
566 EXPECT_FALSE(oauth2_service_delegate_
->RefreshTokenIsAvailable(email1
));
567 EXPECT_TRUE(oauth2_service_delegate_
->RefreshTokenIsAvailable(gaia_id1
));
568 EXPECT_FALSE(oauth2_service_delegate_
->RefreshTokenIsAvailable(email2
));
569 EXPECT_TRUE(oauth2_service_delegate_
->RefreshTokenIsAvailable(gaia_id2
));
571 account_tracker_service_
.SetMigrationDone();
572 oauth2_service_delegate_
->Shutdown();
573 ResetObserverCounts();
575 oauth2_service_delegate_
->LoadCredentials(gaia_id1
);
576 base::RunLoop().RunUntilIdle();
578 EXPECT_EQ(1, tokens_loaded_count_
);
579 EXPECT_EQ(2, token_available_count_
);
580 EXPECT_EQ(1, start_batch_changes_
);
581 EXPECT_EQ(1, end_batch_changes_
);
583 EXPECT_FALSE(oauth2_service_delegate_
->RefreshTokenIsAvailable(email1
));
584 EXPECT_TRUE(oauth2_service_delegate_
->RefreshTokenIsAvailable(gaia_id1
));
585 EXPECT_FALSE(oauth2_service_delegate_
->RefreshTokenIsAvailable(email2
));
586 EXPECT_TRUE(oauth2_service_delegate_
->RefreshTokenIsAvailable(gaia_id2
));
587 accounts
= oauth2_service_delegate_
->GetAccounts();
588 EXPECT_EQ(2u, accounts
.size());