Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / signin / account_reconcilor_unittest.cc
blob692821de701976b8167d654a017e0c6622c6d7cb
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"
42 namespace {
44 class MockAccountReconcilor : public testing::StrictMock<AccountReconcilor> {
45 public:
46 static scoped_ptr<KeyedService> Build(content::BrowserContext* context);
48 MockAccountReconcilor(ProfileOAuth2TokenService* token_service,
49 SigninManagerBase* signin_manager,
50 SigninClient* client,
51 GaiaCookieManagerService* cookie_manager_service);
52 ~MockAccountReconcilor() override {}
54 MOCK_METHOD1(PerformMergeAction, void(const std::string& account_id));
55 MOCK_METHOD0(PerformLogoutAllAccountsAction, void());
58 // static
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,
74 SigninClient* client,
75 GaiaCookieManagerService* cookie_manager_service)
76 : testing::StrictMock<AccountReconcilor>(token_service,
77 signin_manager,
78 client,
79 cookie_manager_service) {}
81 } // namespace
83 class AccountReconcilorTest : public ::testing::TestWithParam<bool> {
84 public:
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_;
126 private:
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() ||
154 GetParam()) {
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(),
184 factories);
186 test_signin_client_ =
187 static_cast<TestSigninClient*>(
188 ChromeSigninClientFactory::GetForProfile(profile()));
190 token_service_ =
191 static_cast<FakeProfileOAuth2TokenService*>(
192 ProfileOAuth2TokenServiceFactory::GetForProfile(profile()));
194 account_tracker_ =
195 AccountTrackerServiceFactory::GetForProfile(profile());
197 signin_manager_ =
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_) {
215 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");
229 #endif
230 signin_manager()->SetAuthenticatedAccountInfo(gaia_id, username);
231 token_service()->UpdateCredentials(account_id, "refresh_token");
232 return account_id;
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(
252 primary_pattern,
253 ContentSettingsPattern::Wildcard(),
254 CONTENT_SETTINGS_TYPE_COOKIES,
255 std::string());
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(
438 reconcilor,
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(
453 reconcilor,
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));
469 builder->Invalid();
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) {
486 return;
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,
767 testing::Bool());