1 // Copyright 2013 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 "base/command_line.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/run_loop.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "base/test/histogram_tester.h"
10 #include "base/time/time.h"
11 #include "build/build_config.h"
12 #include "chrome/browser/prefs/pref_service_syncable.h"
13 #include "chrome/browser/signin/account_reconcilor_factory.h"
14 #include "chrome/browser/signin/account_tracker_service_factory.h"
15 #include "chrome/browser/signin/chrome_signin_client_factory.h"
16 #include "chrome/browser/signin/fake_gaia_cookie_manager_service.h"
17 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
18 #include "chrome/browser/signin/fake_signin_manager_builder.h"
19 #include "chrome/browser/signin/gaia_cookie_manager_service_factory.h"
20 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
21 #include "chrome/browser/signin/signin_manager_factory.h"
22 #include "chrome/browser/signin/test_signin_client_builder.h"
23 #include "chrome/test/base/testing_browser_process.h"
24 #include "chrome/test/base/testing_profile.h"
25 #include "chrome/test/base/testing_profile_manager.h"
26 #include "components/signin/core/browser/account_reconcilor.h"
27 #include "components/signin/core/browser/account_tracker_service.h"
28 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
29 #include "components/signin/core/browser/profile_oauth2_token_service.h"
30 #include "components/signin/core/browser/signin_manager.h"
31 #include "components/signin/core/browser/signin_metrics.h"
32 #include "components/signin/core/browser/test_signin_client.h"
33 #include "components/signin/core/common/profile_management_switches.h"
34 #include "components/signin/core/common/signin_switches.h"
35 #include "content/public/test/test_browser_thread_bundle.h"
36 #include "google_apis/gaia/gaia_constants.h"
37 #include "google_apis/gaia/gaia_urls.h"
38 #include "net/url_request/test_url_fetcher_factory.h"
39 #include "testing/gmock/include/gmock/gmock.h"
40 #include "testing/gtest/include/gtest/gtest.h"
44 class MockAccountReconcilor
: public testing::StrictMock
<AccountReconcilor
> {
46 static scoped_ptr
<KeyedService
> Build(content::BrowserContext
* context
);
48 MockAccountReconcilor(ProfileOAuth2TokenService
* token_service
,
49 SigninManagerBase
* signin_manager
,
51 GaiaCookieManagerService
* cookie_manager_service
);
52 ~MockAccountReconcilor() override
{}
54 MOCK_METHOD1(PerformMergeAction
, void(const std::string
& account_id
));
55 MOCK_METHOD0(PerformLogoutAllAccountsAction
, void());
59 scoped_ptr
<KeyedService
> MockAccountReconcilor::Build(
60 content::BrowserContext
* context
) {
61 Profile
* profile
= Profile::FromBrowserContext(context
);
62 scoped_ptr
<AccountReconcilor
> reconcilor(new MockAccountReconcilor(
63 ProfileOAuth2TokenServiceFactory::GetForProfile(profile
),
64 SigninManagerFactory::GetForProfile(profile
),
65 ChromeSigninClientFactory::GetForProfile(profile
),
66 GaiaCookieManagerServiceFactory::GetForProfile(profile
)));
67 reconcilor
->Initialize(false /* start_reconcile_if_tokens_available */);
68 return reconcilor
.Pass();
71 MockAccountReconcilor::MockAccountReconcilor(
72 ProfileOAuth2TokenService
* token_service
,
73 SigninManagerBase
* signin_manager
,
75 GaiaCookieManagerService
* cookie_manager_service
)
76 : testing::StrictMock
<AccountReconcilor
>(token_service
,
79 cookie_manager_service
) {}
83 class AccountReconcilorTest
: public ::testing::TestWithParam
<bool> {
85 AccountReconcilorTest();
86 void SetUp() override
;
88 TestingProfile
* profile() { return profile_
; }
89 FakeSigninManagerForTesting
* signin_manager() { return signin_manager_
; }
90 FakeProfileOAuth2TokenService
* token_service() { return token_service_
; }
91 TestSigninClient
* test_signin_client() { return test_signin_client_
; }
92 AccountTrackerService
* account_tracker() { return account_tracker_
; }
93 FakeGaiaCookieManagerService
* cookie_manager_service() {
94 return cookie_manager_service_
;
96 base::HistogramTester
* histogram_tester() { return &histogram_tester_
; }
98 void SetFakeResponse(const std::string
& url
,
99 const std::string
& data
,
100 net::HttpStatusCode code
,
101 net::URLRequestStatus::Status status
) {
102 url_fetcher_factory_
.SetFakeResponse(GURL(url
), data
, code
, status
);
105 MockAccountReconcilor
* GetMockReconcilor();
107 std::string
ConnectProfileToAccount(const std::string
& gaia_id
,
108 const std::string
& username
);
110 std::string
PickAccountIdForAccount(const std::string
& gaia_id
,
111 const std::string
& username
);
113 void SimulateAddAccountToCookieCompleted(
114 GaiaCookieManagerService::Observer
* observer
,
115 const std::string
& account_id
,
116 const GoogleServiceAuthError
& error
);
118 void SimulateCookieContentSettingsChanged(
119 content_settings::Observer
* observer
,
120 const ContentSettingsPattern
& primary_pattern
);
122 GURL
get_check_connection_info_url() {
123 return get_check_connection_info_url_
;
127 content::TestBrowserThreadBundle bundle_
;
128 TestingProfile
* profile_
;
129 FakeSigninManagerForTesting
* signin_manager_
;
130 FakeProfileOAuth2TokenService
* token_service_
;
131 TestSigninClient
* test_signin_client_
;
132 AccountTrackerService
* account_tracker_
;
133 FakeGaiaCookieManagerService
* cookie_manager_service_
;
134 MockAccountReconcilor
* mock_reconcilor_
;
135 net::FakeURLFetcherFactory url_fetcher_factory_
;
136 scoped_ptr
<TestingProfileManager
> testing_profile_manager_
;
137 base::HistogramTester histogram_tester_
;
138 GURL get_check_connection_info_url_
;
140 DISALLOW_COPY_AND_ASSIGN(AccountReconcilorTest
);
143 AccountReconcilorTest::AccountReconcilorTest()
144 : signin_manager_(NULL
),
145 token_service_(NULL
),
146 test_signin_client_(NULL
),
147 cookie_manager_service_(NULL
),
148 mock_reconcilor_(NULL
),
149 url_fetcher_factory_(NULL
) {}
151 void AccountReconcilorTest::SetUp() {
152 // If it's a non-parameterized test, or we have a parameter of true, set flag.
153 if (!::testing::UnitTest::GetInstance()->current_test_info()->value_param() ||
155 base::CommandLine::ForCurrentProcess()->AppendSwitch(
156 switches::kEnableNewProfileManagement
);
159 get_check_connection_info_url_
=
160 GaiaUrls::GetInstance()->GetCheckConnectionInfoURLWithSource(
161 GaiaConstants::kChromeSource
);
163 testing_profile_manager_
.reset(
164 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
165 ASSERT_TRUE(testing_profile_manager_
.get()->SetUp());
167 TestingProfile::TestingFactories factories
;
168 factories
.push_back(std::make_pair(ChromeSigninClientFactory::GetInstance(),
169 signin::BuildTestSigninClient
));
170 factories
.push_back(std::make_pair(
171 ProfileOAuth2TokenServiceFactory::GetInstance(),
172 BuildFakeProfileOAuth2TokenService
));
173 factories
.push_back(std::make_pair(
174 GaiaCookieManagerServiceFactory::GetInstance(),
175 FakeGaiaCookieManagerService::Build
));
176 factories
.push_back(std::make_pair(SigninManagerFactory::GetInstance(),
177 BuildFakeSigninManagerBase
));
178 factories
.push_back(std::make_pair(AccountReconcilorFactory::GetInstance(),
179 MockAccountReconcilor::Build
));
181 profile_
= testing_profile_manager_
.get()->CreateTestingProfile("name",
182 scoped_ptr
<PrefServiceSyncable
>(),
183 base::UTF8ToUTF16("name"), 0, std::string(),
186 test_signin_client_
=
187 static_cast<TestSigninClient
*>(
188 ChromeSigninClientFactory::GetForProfile(profile()));
191 static_cast<FakeProfileOAuth2TokenService
*>(
192 ProfileOAuth2TokenServiceFactory::GetForProfile(profile()));
195 AccountTrackerServiceFactory::GetForProfile(profile());
198 static_cast<FakeSigninManagerForTesting
*>(
199 SigninManagerFactory::GetForProfile(profile()));
201 test_signin_client_
=
202 static_cast<TestSigninClient
*>(
203 ChromeSigninClientFactory::GetForProfile(profile()));
205 cookie_manager_service_
=
206 static_cast<FakeGaiaCookieManagerService
*>(
207 GaiaCookieManagerServiceFactory::GetForProfile(profile()));
208 cookie_manager_service_
->Init(&url_fetcher_factory_
);
210 cookie_manager_service_
->SetListAccountsResponseHttpNotFound();
213 MockAccountReconcilor
* AccountReconcilorTest::GetMockReconcilor() {
214 if (!mock_reconcilor_
) {
216 static_cast<MockAccountReconcilor
*>(
217 AccountReconcilorFactory::GetForProfile(profile()));
220 return mock_reconcilor_
;
223 std::string
AccountReconcilorTest::ConnectProfileToAccount(
224 const std::string
& gaia_id
,
225 const std::string
& username
) {
226 const std::string account_id
= PickAccountIdForAccount(gaia_id
, username
);
227 #if !defined(OS_CHROMEOS)
228 signin_manager()->set_password("password");
230 signin_manager()->SetAuthenticatedAccountInfo(gaia_id
, username
);
231 token_service()->UpdateCredentials(account_id
, "refresh_token");
235 std::string
AccountReconcilorTest::PickAccountIdForAccount(
236 const std::string
& gaia_id
,
237 const std::string
& username
) {
238 return account_tracker()->PickAccountIdForAccount(gaia_id
, username
);
241 void AccountReconcilorTest::SimulateAddAccountToCookieCompleted(
242 GaiaCookieManagerService::Observer
* observer
,
243 const std::string
& account_id
,
244 const GoogleServiceAuthError
& error
) {
245 observer
->OnAddAccountToCookieCompleted(account_id
, error
);
248 void AccountReconcilorTest::SimulateCookieContentSettingsChanged(
249 content_settings::Observer
* observer
,
250 const ContentSettingsPattern
& primary_pattern
) {
251 observer
->OnContentSettingChanged(
253 ContentSettingsPattern::Wildcard(),
254 CONTENT_SETTINGS_TYPE_COOKIES
,
258 TEST_F(AccountReconcilorTest
, Basic
) {
259 AccountReconcilor
* reconcilor
=
260 AccountReconcilorFactory::GetForProfile(profile());
261 ASSERT_TRUE(reconcilor
);
264 #if !defined(OS_CHROMEOS)
266 // This method requires the use of the |TestSigninClient| to be created from the
267 // |ChromeSigninClientFactory| because it overrides the |GoogleSigninSucceeded|
268 // method with an empty implementation. On MacOS, the normal implementation
269 // causes the try_bots to time out.
270 TEST_F(AccountReconcilorTest
, SigninManagerRegistration
) {
271 AccountReconcilor
* reconcilor
=
272 AccountReconcilorFactory::GetForProfile(profile());
273 ASSERT_TRUE(reconcilor
);
274 ASSERT_FALSE(reconcilor
->IsRegisteredWithTokenService());
276 account_tracker()->SeedAccountInfo("12345", "user@gmail.com");
277 signin_manager()->SignIn("12345", "user@gmail.com", "password");
278 ASSERT_TRUE(reconcilor
->IsRegisteredWithTokenService());
280 EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
282 signin_manager()->SignOut(signin_metrics::SIGNOUT_TEST
);
283 ASSERT_FALSE(reconcilor
->IsRegisteredWithTokenService());
286 // This method requires the use of the |TestSigninClient| to be created from the
287 // |ChromeSigninClientFactory| because it overrides the |GoogleSigninSucceeded|
288 // method with an empty implementation. On MacOS, the normal implementation
289 // causes the try_bots to time out.
290 TEST_F(AccountReconcilorTest
, Reauth
) {
291 const std::string email
= "user@gmail.com";
292 const std::string account_id
=
293 ConnectProfileToAccount("12345", email
);
295 AccountReconcilor
* reconcilor
=
296 AccountReconcilorFactory::GetForProfile(profile());
297 ASSERT_TRUE(reconcilor
);
298 ASSERT_TRUE(reconcilor
->IsRegisteredWithTokenService());
300 // Simulate reauth. The state of the reconcilor should not change.
301 signin_manager()->OnExternalSigninCompleted(email
);
302 ASSERT_TRUE(reconcilor
->IsRegisteredWithTokenService());
305 #endif // !defined(OS_CHROMEOS)
307 TEST_F(AccountReconcilorTest
, ProfileAlreadyConnected
) {
308 ConnectProfileToAccount("12345", "user@gmail.com");
310 AccountReconcilor
* reconcilor
=
311 AccountReconcilorFactory::GetForProfile(profile());
312 ASSERT_TRUE(reconcilor
);
313 ASSERT_TRUE(reconcilor
->IsRegisteredWithTokenService());
316 TEST_F(AccountReconcilorTest
, GetAccountsFromCookieSuccess
) {
317 const std::string account_id
=
318 ConnectProfileToAccount("12345", "user@gmail.com");
319 cookie_manager_service()->SetListAccountsResponseOneAccountWithExpiry(
320 "user@gmail.com", "12345", true);
321 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id
));
323 AccountReconcilor
* reconcilor
=
324 AccountReconcilorFactory::GetForProfile(profile());
325 ASSERT_TRUE(reconcilor
);
327 ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_OK
, reconcilor
->GetState());
328 reconcilor
->StartReconcile();
329 ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_RUNNING
,
330 reconcilor
->GetState());
331 base::RunLoop().RunUntilIdle();
332 ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_RUNNING
, reconcilor
->GetState());
334 std::vector
<gaia::ListedAccount
> accounts
;
335 ASSERT_TRUE(cookie_manager_service()->ListAccounts(&accounts
));
336 ASSERT_EQ(1u, accounts
.size());
337 ASSERT_EQ(account_id
, accounts
[0].id
);
340 TEST_F(AccountReconcilorTest
, GetAccountsFromCookieFailure
) {
341 ConnectProfileToAccount("12345", "user@gmail.com");
342 cookie_manager_service()->SetListAccountsResponseWebLoginRequired();
344 AccountReconcilor
* reconcilor
=
345 AccountReconcilorFactory::GetForProfile(profile());
346 ASSERT_TRUE(reconcilor
);
348 ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_OK
, reconcilor
->GetState());
349 reconcilor
->StartReconcile();
350 ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_RUNNING
,
351 reconcilor
->GetState());
352 base::RunLoop().RunUntilIdle();
354 std::vector
<gaia::ListedAccount
> accounts
;
355 ASSERT_FALSE(cookie_manager_service()->ListAccounts(&accounts
));
356 ASSERT_EQ(0u, accounts
.size());
358 base::RunLoop().RunUntilIdle();
359 ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_ERROR
,
360 reconcilor
->GetState());
363 TEST_P(AccountReconcilorTest
, StartReconcileNoop
) {
364 const std::string account_id
=
365 ConnectProfileToAccount("12345", "user@gmail.com");
367 AccountReconcilor
* reconcilor
=
368 AccountReconcilorFactory::GetForProfile(profile());
369 ASSERT_TRUE(reconcilor
);
371 cookie_manager_service()->SetListAccountsResponseOneAccount(
372 "user@gmail.com", "12345");
374 reconcilor
->StartReconcile();
375 ASSERT_TRUE(reconcilor
->is_reconcile_started_
);
377 base::RunLoop().RunUntilIdle();
378 ASSERT_FALSE(reconcilor
->is_reconcile_started_
);
380 histogram_tester()->ExpectTotalCount(
381 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun", 1);
382 histogram_tester()->ExpectUniqueSample(
383 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
384 signin_metrics::ACCOUNTS_SAME
,
388 TEST_P(AccountReconcilorTest
, StartReconcileCookiesDisabled
) {
389 const std::string account_id
=
390 ConnectProfileToAccount("12345", "user@gmail.com");
391 token_service()->UpdateCredentials(account_id
, "refresh_token");
392 test_signin_client()->set_are_signin_cookies_allowed(false);
394 AccountReconcilor
* reconcilor
=
395 AccountReconcilorFactory::GetForProfile(profile());
396 ASSERT_TRUE(reconcilor
);
398 reconcilor
->StartReconcile();
399 ASSERT_FALSE(reconcilor
->is_reconcile_started_
);
401 base::RunLoop().RunUntilIdle();
402 std::vector
<gaia::ListedAccount
> accounts
;
403 // This will be the first call to ListAccounts.
404 ASSERT_FALSE(cookie_manager_service()->ListAccounts(&accounts
));
405 ASSERT_FALSE(reconcilor
->is_reconcile_started_
);
408 TEST_P(AccountReconcilorTest
, StartReconcileContentSettings
) {
409 const std::string account_id
=
410 ConnectProfileToAccount("12345", "user@gmail.com");
411 token_service()->UpdateCredentials(account_id
, "refresh_token");
413 AccountReconcilor
* reconcilor
=
414 AccountReconcilorFactory::GetForProfile(profile());
415 ASSERT_TRUE(reconcilor
);
417 test_signin_client()->set_are_signin_cookies_allowed(false);
418 SimulateCookieContentSettingsChanged(reconcilor
,
419 ContentSettingsPattern::Wildcard());
420 ASSERT_FALSE(reconcilor
->is_reconcile_started_
);
422 test_signin_client()->set_are_signin_cookies_allowed(true);
423 SimulateCookieContentSettingsChanged(reconcilor
,
424 ContentSettingsPattern::Wildcard());
425 ASSERT_TRUE(reconcilor
->is_reconcile_started_
);
428 TEST_P(AccountReconcilorTest
, StartReconcileContentSettingsGaiaUrl
) {
429 const std::string account_id
=
430 ConnectProfileToAccount("12345", "user@gmail.com");
431 token_service()->UpdateCredentials(account_id
, "refresh_token");
433 AccountReconcilor
* reconcilor
=
434 AccountReconcilorFactory::GetForProfile(profile());
435 ASSERT_TRUE(reconcilor
);
437 SimulateCookieContentSettingsChanged(
439 ContentSettingsPattern::FromURL(GaiaUrls::GetInstance()->gaia_url()));
440 ASSERT_TRUE(reconcilor
->is_reconcile_started_
);
443 TEST_P(AccountReconcilorTest
, StartReconcileContentSettingsNonGaiaUrl
) {
444 const std::string account_id
=
445 ConnectProfileToAccount("12345", "user@gmail.com");
446 token_service()->UpdateCredentials(account_id
, "refresh_token");
448 AccountReconcilor
* reconcilor
=
449 AccountReconcilorFactory::GetForProfile(profile());
450 ASSERT_TRUE(reconcilor
);
452 SimulateCookieContentSettingsChanged(
454 ContentSettingsPattern::FromURL(GURL("http://www.example.com")));
455 ASSERT_FALSE(reconcilor
->is_reconcile_started_
);
458 TEST_P(AccountReconcilorTest
, StartReconcileContentSettingsInvalidPattern
) {
459 const std::string account_id
=
460 ConnectProfileToAccount("12345", "user@gmail.com");
461 token_service()->UpdateCredentials(account_id
, "refresh_token");
463 AccountReconcilor
* reconcilor
=
464 AccountReconcilorFactory::GetForProfile(profile());
465 ASSERT_TRUE(reconcilor
);
467 scoped_ptr
<ContentSettingsPattern::BuilderInterface
>
468 builder(ContentSettingsPattern::CreateBuilder(false));
471 SimulateCookieContentSettingsChanged(reconcilor
, builder
->Build());
472 ASSERT_TRUE(reconcilor
->is_reconcile_started_
);
475 // This test is needed until chrome changes to use gaia obfuscated id.
476 // The signin manager and token service use the gaia "email" property, which
477 // preserves dots in usernames and preserves case. gaia::ParseListAccountsData()
478 // however uses gaia "displayEmail" which does not preserve case, and then
479 // passes the string through gaia::CanonicalizeEmail() which removes dots. This
480 // tests makes sure that an email like "Dot.S@hmail.com", as seen by the
481 // token service, will be considered the same as "dots@gmail.com" as returned
482 // by gaia::ParseListAccountsData().
483 TEST_P(AccountReconcilorTest
, StartReconcileNoopWithDots
) {
484 if (account_tracker()->GetMigrationState() !=
485 AccountTrackerService::MIGRATION_NOT_STARTED
) {
489 const std::string account_id
=
490 ConnectProfileToAccount("12345", "Dot.S@gmail.com");
491 cookie_manager_service()->SetListAccountsResponseOneAccount(
492 "dot.s@gmail.com", "12345");
493 AccountReconcilor
* reconcilor
=
494 AccountReconcilorFactory::GetForProfile(profile());
495 ASSERT_TRUE(reconcilor
);
497 reconcilor
->StartReconcile();
498 base::RunLoop().RunUntilIdle();
499 ASSERT_FALSE(reconcilor
->is_reconcile_started_
);
501 histogram_tester()->ExpectUniqueSample(
502 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
503 signin_metrics::ACCOUNTS_SAME
,
507 TEST_P(AccountReconcilorTest
, StartReconcileNoopMultiple
) {
508 const std::string account_id
=
509 ConnectProfileToAccount("12345", "user@gmail.com");
510 const std::string account_id2
=
511 PickAccountIdForAccount("67890", "other@gmail.com");
512 cookie_manager_service()->SetListAccountsResponseTwoAccounts(
513 "user@gmail.com", "12345", "other@gmail.com", "67890");
514 token_service()->UpdateCredentials(account_id2
, "refresh_token");
516 AccountReconcilor
* reconcilor
=
517 AccountReconcilorFactory::GetForProfile(profile());
518 ASSERT_TRUE(reconcilor
);
520 reconcilor
->StartReconcile();
521 base::RunLoop().RunUntilIdle();
522 ASSERT_FALSE(reconcilor
->is_reconcile_started_
);
524 histogram_tester()->ExpectTotalCount(
525 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun", 1);
526 histogram_tester()->ExpectUniqueSample(
527 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
528 signin_metrics::ACCOUNTS_SAME
,
532 TEST_P(AccountReconcilorTest
, StartReconcileAddToCookie
) {
533 const std::string account_id
=
534 ConnectProfileToAccount("12345", "user@gmail.com");
535 token_service()->UpdateCredentials(account_id
, "refresh_token");
536 cookie_manager_service()->SetListAccountsResponseOneAccount(
537 "user@gmail.com", "12345");
539 const std::string account_id2
=
540 PickAccountIdForAccount("67890", "other@gmail.com");
541 token_service()->UpdateCredentials(account_id2
, "refresh_token");
543 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id2
));
545 AccountReconcilor
* reconcilor
= GetMockReconcilor();
546 reconcilor
->StartReconcile();
548 base::RunLoop().RunUntilIdle();
549 ASSERT_TRUE(reconcilor
->is_reconcile_started_
);
550 SimulateAddAccountToCookieCompleted(reconcilor
, account_id2
,
551 GoogleServiceAuthError::AuthErrorNone());
552 ASSERT_FALSE(reconcilor
->is_reconcile_started_
);
554 histogram_tester()->ExpectUniqueSample(
555 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
556 signin_metrics::ACCOUNTS_SAME
,
558 histogram_tester()->ExpectUniqueSample(
559 "Signin.Reconciler.AddedToCookieJar.FirstRun", 1, 1);
560 histogram_tester()->ExpectUniqueSample(
561 "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 0, 1);
564 TEST_P(AccountReconcilorTest
, StartReconcileRemoveFromCookie
) {
565 const std::string account_id
=
566 ConnectProfileToAccount("12345", "user@gmail.com");
567 token_service()->UpdateCredentials(account_id
, "refresh_token");
568 cookie_manager_service()->SetListAccountsResponseTwoAccounts(
569 "user@gmail.com", "12345", "other@gmail.com", "67890");
571 EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
572 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id
));
574 AccountReconcilor
* reconcilor
= GetMockReconcilor();
575 reconcilor
->StartReconcile();
576 ASSERT_TRUE(reconcilor
->is_reconcile_started_
);
578 base::RunLoop().RunUntilIdle();
579 SimulateAddAccountToCookieCompleted(reconcilor
, account_id
,
580 GoogleServiceAuthError::AuthErrorNone());
581 ASSERT_FALSE(reconcilor
->is_reconcile_started_
);
583 histogram_tester()->ExpectUniqueSample(
584 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
585 signin_metrics::ACCOUNTS_SAME
,
587 histogram_tester()->ExpectUniqueSample(
588 "Signin.Reconciler.AddedToCookieJar.FirstRun", 0, 1);
589 histogram_tester()->ExpectUniqueSample(
590 "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 1, 1);
593 TEST_P(AccountReconcilorTest
, StartReconcileAddToCookieTwice
) {
594 const std::string account_id
=
595 ConnectProfileToAccount("12345", "user@gmail.com");
596 const std::string account_id2
=
597 PickAccountIdForAccount("67890", "other@gmail.com");
598 const std::string account_id3
=
599 PickAccountIdForAccount("34567", "third@gmail.com");
601 cookie_manager_service()->SetListAccountsResponseOneAccount(
602 "user@gmail.com", "12345");
603 token_service()->UpdateCredentials(account_id2
, "refresh_token");
605 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id2
));
606 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id3
));
608 AccountReconcilor
* reconcilor
= GetMockReconcilor();
609 reconcilor
->StartReconcile();
611 base::RunLoop().RunUntilIdle();
612 ASSERT_TRUE(reconcilor
->is_reconcile_started_
);
613 SimulateAddAccountToCookieCompleted(
614 reconcilor
, account_id2
, GoogleServiceAuthError::AuthErrorNone());
615 ASSERT_FALSE(reconcilor
->is_reconcile_started_
);
617 histogram_tester()->ExpectUniqueSample(
618 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
619 signin_metrics::ACCOUNTS_SAME
,
621 histogram_tester()->ExpectUniqueSample(
622 "Signin.Reconciler.AddedToCookieJar.FirstRun", 1, 1);
623 histogram_tester()->ExpectUniqueSample(
624 "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 0, 1);
626 // Do another pass after I've added a third account to the token service
627 cookie_manager_service()->SetListAccountsResponseTwoAccounts(
628 "user@gmail.com", "12345", "other@gmail.com", "67890");
629 cookie_manager_service()->set_list_accounts_fetched_once_for_testing(false);
631 // This will cause the reconcilor to fire.
632 token_service()->UpdateCredentials(account_id3
, "refresh_token");
633 base::RunLoop().RunUntilIdle();
635 ASSERT_TRUE(reconcilor
->is_reconcile_started_
);
636 SimulateAddAccountToCookieCompleted(
637 reconcilor
, account_id3
, GoogleServiceAuthError::AuthErrorNone());
638 ASSERT_FALSE(reconcilor
->is_reconcile_started_
);
640 histogram_tester()->ExpectUniqueSample(
641 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
642 signin_metrics::ACCOUNTS_SAME
,
644 histogram_tester()->ExpectUniqueSample(
645 "Signin.Reconciler.AddedToCookieJar.FirstRun", 1, 1);
646 histogram_tester()->ExpectUniqueSample(
647 "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 0, 1);
648 histogram_tester()->ExpectUniqueSample(
649 "Signin.Reconciler.DifferentPrimaryAccounts.SubsequentRun",
650 signin_metrics::ACCOUNTS_SAME
,
652 histogram_tester()->ExpectUniqueSample(
653 "Signin.Reconciler.AddedToCookieJar.SubsequentRun", 1, 1);
654 histogram_tester()->ExpectUniqueSample(
655 "Signin.Reconciler.RemovedFromCookieJar.SubsequentRun", 0, 1);
658 TEST_P(AccountReconcilorTest
, StartReconcileBadPrimary
) {
659 const std::string account_id
=
660 ConnectProfileToAccount("12345", "user@gmail.com");
661 const std::string account_id2
=
662 PickAccountIdForAccount("67890", "other@gmail.com");
664 token_service()->UpdateCredentials(account_id2
, "refresh_token");
665 cookie_manager_service()->SetListAccountsResponseTwoAccounts(
666 "other@gmail.com", "67890", "user@gmail.com", "12345");
668 EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
669 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id
));
670 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id2
));
672 AccountReconcilor
* reconcilor
= GetMockReconcilor();
673 reconcilor
->StartReconcile();
675 base::RunLoop().RunUntilIdle();
676 ASSERT_TRUE(reconcilor
->is_reconcile_started_
);
677 SimulateAddAccountToCookieCompleted(reconcilor
, account_id2
,
678 GoogleServiceAuthError::AuthErrorNone());
679 ASSERT_TRUE(reconcilor
->is_reconcile_started_
);
680 SimulateAddAccountToCookieCompleted(reconcilor
, account_id
,
681 GoogleServiceAuthError::AuthErrorNone());
682 ASSERT_FALSE(reconcilor
->is_reconcile_started_
);
684 histogram_tester()->ExpectUniqueSample(
685 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
686 signin_metrics::COOKIE_AND_TOKEN_PRIMARIES_DIFFERENT
,
688 histogram_tester()->ExpectUniqueSample(
689 "Signin.Reconciler.AddedToCookieJar.FirstRun", 0, 1);
690 histogram_tester()->ExpectUniqueSample(
691 "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 0, 1);
694 TEST_P(AccountReconcilorTest
, StartReconcileOnlyOnce
) {
695 const std::string account_id
=
696 ConnectProfileToAccount("12345", "user@gmail.com");
697 cookie_manager_service()->SetListAccountsResponseOneAccount(
698 "user@gmail.com", "12345");
700 AccountReconcilor
* reconcilor
=
701 AccountReconcilorFactory::GetForProfile(profile());
702 ASSERT_TRUE(reconcilor
);
704 ASSERT_FALSE(reconcilor
->is_reconcile_started_
);
705 reconcilor
->StartReconcile();
706 ASSERT_TRUE(reconcilor
->is_reconcile_started_
);
708 base::RunLoop().RunUntilIdle();
709 ASSERT_FALSE(reconcilor
->is_reconcile_started_
);
712 TEST_P(AccountReconcilorTest
, StartReconcileWithSessionInfoExpiredDefault
) {
713 const std::string account_id
=
714 ConnectProfileToAccount("12345", "user@gmail.com");
715 const std::string account_id2
=
716 PickAccountIdForAccount("67890", "other@gmail.com");
717 token_service()->UpdateCredentials(account_id2
, "refresh_token");
718 cookie_manager_service()->SetListAccountsResponseTwoAccountsWithExpiry(
719 "user@gmail.com", "12345", true, "other@gmail.com", "67890", false);
721 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id
));
723 AccountReconcilor
* reconcilor
=
724 AccountReconcilorFactory::GetForProfile(profile());
725 ASSERT_TRUE(reconcilor
);
727 ASSERT_FALSE(reconcilor
->is_reconcile_started_
);
728 reconcilor
->StartReconcile();
729 ASSERT_TRUE(reconcilor
->is_reconcile_started_
);
731 base::RunLoop().RunUntilIdle();
732 SimulateAddAccountToCookieCompleted(reconcilor
, account_id
,
733 GoogleServiceAuthError::AuthErrorNone());
734 ASSERT_FALSE(reconcilor
->is_reconcile_started_
);
737 TEST_F(AccountReconcilorTest
, AddAccountToCookieCompletedWithBogusAccount
) {
738 const std::string account_id
=
739 ConnectProfileToAccount("12345", "user@gmail.com");
740 cookie_manager_service()->SetListAccountsResponseOneAccountWithExpiry(
741 "user@gmail.com", "12345", true);
743 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id
));
745 AccountReconcilor
* reconcilor
=
746 AccountReconcilorFactory::GetForProfile(profile());
747 ASSERT_TRUE(reconcilor
);
749 ASSERT_FALSE(reconcilor
->is_reconcile_started_
);
750 reconcilor
->StartReconcile();
751 ASSERT_TRUE(reconcilor
->is_reconcile_started_
);
753 base::RunLoop().RunUntilIdle();
755 // If an unknown account id is sent, it should not upset the state.
756 SimulateAddAccountToCookieCompleted(reconcilor
, "bogus_account_id",
757 GoogleServiceAuthError::AuthErrorNone());
758 ASSERT_TRUE(reconcilor
->is_reconcile_started_
);
760 SimulateAddAccountToCookieCompleted(reconcilor
, account_id
,
761 GoogleServiceAuthError::AuthErrorNone());
762 ASSERT_FALSE(reconcilor
->is_reconcile_started_
);
765 INSTANTIATE_TEST_CASE_P(AccountReconcilorMaybeEnabled
,
766 AccountReconcilorTest
,