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/chrome_signin_client_factory.h"
15 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
16 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
17 #include "chrome/browser/signin/fake_signin_manager.h"
18 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
19 #include "chrome/browser/signin/signin_manager_factory.h"
20 #include "chrome/browser/signin/test_signin_client_builder.h"
21 #include "chrome/test/base/testing_browser_process.h"
22 #include "chrome/test/base/testing_profile.h"
23 #include "chrome/test/base/testing_profile_manager.h"
24 #include "components/signin/core/browser/account_reconcilor.h"
25 #include "components/signin/core/browser/profile_oauth2_token_service.h"
26 #include "components/signin/core/browser/signin_manager.h"
27 #include "components/signin/core/browser/signin_metrics.h"
28 #include "components/signin/core/common/profile_management_switches.h"
29 #include "components/signin/core/common/signin_switches.h"
30 #include "content/public/test/test_browser_thread_bundle.h"
31 #include "google_apis/gaia/gaia_constants.h"
32 #include "google_apis/gaia/gaia_urls.h"
33 #include "net/url_request/test_url_fetcher_factory.h"
34 #include "testing/gmock/include/gmock/gmock.h"
35 #include "testing/gtest/include/gtest/gtest.h"
39 const char kTestEmail[] = "user@gmail.com";
41 class MockAccountReconcilor : public testing::StrictMock<AccountReconcilor> {
43 static KeyedService* Build(content::BrowserContext* context);
45 MockAccountReconcilor(ProfileOAuth2TokenService* token_service,
46 SigninManagerBase* signin_manager,
47 SigninClient* client);
48 virtual ~MockAccountReconcilor() {}
50 virtual void StartFetchingExternalCcResult() override {
51 // Don't do this in tests.
54 MOCK_METHOD1(PerformMergeAction, void(const std::string& account_id));
55 MOCK_METHOD0(PerformLogoutAllAccountsAction, void());
59 KeyedService* MockAccountReconcilor::Build(content::BrowserContext* context) {
60 Profile* profile = Profile::FromBrowserContext(context);
61 AccountReconcilor* reconcilor = new MockAccountReconcilor(
62 ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
63 SigninManagerFactory::GetForProfile(profile),
64 ChromeSigninClientFactory::GetForProfile(profile));
65 reconcilor->Initialize(false /* start_reconcile_if_tokens_available */);
69 MockAccountReconcilor::MockAccountReconcilor(
70 ProfileOAuth2TokenService* token_service,
71 SigninManagerBase* signin_manager,
73 : testing::StrictMock<AccountReconcilor>(token_service,
79 class AccountReconcilorTest : public ::testing::TestWithParam<bool> {
81 AccountReconcilorTest();
82 void SetUp() override;
84 TestingProfile* profile() { return profile_; }
85 FakeSigninManagerForTesting* signin_manager() { return signin_manager_; }
86 FakeProfileOAuth2TokenService* token_service() { return token_service_; }
87 base::HistogramTester* histogram_tester() { return &histogram_tester_; }
89 void SetFakeResponse(const std::string& url,
90 const std::string& data,
91 net::HttpStatusCode code,
92 net::URLRequestStatus::Status status) {
93 url_fetcher_factory_.SetFakeResponse(GURL(url), data, code, status);
96 MockAccountReconcilor* GetMockReconcilor();
98 void SimulateMergeSessionCompleted(
99 MergeSessionHelper::Observer* observer,
100 const std::string& account_id,
101 const GoogleServiceAuthError& error);
103 GURL list_accounts_url() { return list_accounts_url_; }
104 GURL get_check_connection_info_url() {
105 return get_check_connection_info_url_;
109 content::TestBrowserThreadBundle bundle_;
110 TestingProfile* profile_;
111 FakeSigninManagerForTesting* signin_manager_;
112 FakeProfileOAuth2TokenService* token_service_;
113 MockAccountReconcilor* mock_reconcilor_;
114 net::FakeURLFetcherFactory url_fetcher_factory_;
115 scoped_ptr<TestingProfileManager> testing_profile_manager_;
116 base::HistogramTester histogram_tester_;
117 GURL list_accounts_url_;
118 GURL get_check_connection_info_url_;
120 DISALLOW_COPY_AND_ASSIGN(AccountReconcilorTest);
123 AccountReconcilorTest::AccountReconcilorTest()
124 : signin_manager_(NULL),
125 token_service_(NULL),
126 mock_reconcilor_(NULL),
127 url_fetcher_factory_(NULL) {}
129 void AccountReconcilorTest::SetUp() {
130 // If it's a non-parameterized test, or we have a parameter of true, set flag.
131 if (!::testing::UnitTest::GetInstance()->current_test_info()->value_param() ||
133 CommandLine::ForCurrentProcess()->AppendSwitch(
134 switches::kEnableNewProfileManagement);
137 list_accounts_url_ = GaiaUrls::GetInstance()->ListAccountsURLWithSource(
138 GaiaConstants::kReconcilorSource);
139 get_check_connection_info_url_ =
140 GaiaUrls::GetInstance()->GetCheckConnectionInfoURLWithSource(
141 GaiaConstants::kReconcilorSource);
143 SetFakeResponse(get_check_connection_info_url().spec(), "[]",
144 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
146 testing_profile_manager_.reset(
147 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
148 ASSERT_TRUE(testing_profile_manager_.get()->SetUp());
150 TestingProfile::TestingFactories factories;
151 factories.push_back(std::make_pair(ChromeSigninClientFactory::GetInstance(),
152 signin::BuildTestSigninClient));
153 factories.push_back(std::make_pair(
154 ProfileOAuth2TokenServiceFactory::GetInstance(),
155 BuildFakeProfileOAuth2TokenService));
156 factories.push_back(std::make_pair(SigninManagerFactory::GetInstance(),
157 FakeSigninManagerBase::Build));
158 factories.push_back(std::make_pair(AccountReconcilorFactory::GetInstance(),
159 MockAccountReconcilor::Build));
161 profile_ = testing_profile_manager_.get()->CreateTestingProfile("name",
162 scoped_ptr<PrefServiceSyncable>(),
163 base::UTF8ToUTF16("name"), 0, std::string(),
167 static_cast<FakeSigninManagerForTesting*>(
168 SigninManagerFactory::GetForProfile(profile()));
171 static_cast<FakeProfileOAuth2TokenService*>(
172 ProfileOAuth2TokenServiceFactory::GetForProfile(profile()));
175 MockAccountReconcilor* AccountReconcilorTest::GetMockReconcilor() {
176 if (!mock_reconcilor_) {
178 static_cast<MockAccountReconcilor*>(
179 AccountReconcilorFactory::GetForProfile(profile()));
182 return mock_reconcilor_;
185 void AccountReconcilorTest::SimulateMergeSessionCompleted(
186 MergeSessionHelper::Observer* observer,
187 const std::string& account_id,
188 const GoogleServiceAuthError& error) {
189 observer->MergeSessionCompleted(account_id, error);
192 TEST_F(AccountReconcilorTest, Basic) {
193 AccountReconcilor* reconcilor =
194 AccountReconcilorFactory::GetForProfile(profile());
195 ASSERT_TRUE(reconcilor);
196 ASSERT_EQ(token_service(), reconcilor->token_service());
199 #if !defined(OS_CHROMEOS)
201 // This method requires the use of the |TestSigninClient| to be created from the
202 // |ChromeSigninClientFactory| because it overrides the |GoogleSigninSucceeded|
203 // method with an empty implementation. On MacOS, the normal implementation
204 // causes the try_bots to time out.
205 TEST_F(AccountReconcilorTest, SigninManagerRegistration) {
206 AccountReconcilor* reconcilor =
207 AccountReconcilorFactory::GetForProfile(profile());
208 ASSERT_TRUE(reconcilor);
209 ASSERT_FALSE(reconcilor->IsRegisteredWithTokenService());
211 signin_manager()->set_password("password");
212 signin_manager()->OnExternalSigninCompleted(kTestEmail);
213 ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
215 EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
217 signin_manager()->SignOut(signin_metrics::SIGNOUT_TEST);
218 ASSERT_FALSE(reconcilor->IsRegisteredWithTokenService());
221 // This method requires the use of the |TestSigninClient| to be created from the
222 // |ChromeSigninClientFactory| because it overrides the |GoogleSigninSucceeded|
223 // method with an empty implementation. On MacOS, the normal implementation
224 // causes the try_bots to time out.
225 TEST_F(AccountReconcilorTest, Reauth) {
226 signin_manager()->SetAuthenticatedUsername(kTestEmail);
227 signin_manager()->set_password("password");
229 AccountReconcilor* reconcilor =
230 AccountReconcilorFactory::GetForProfile(profile());
231 ASSERT_TRUE(reconcilor);
232 ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
234 // Simulate reauth. The state of the reconcilor should not change.
235 signin_manager()->OnExternalSigninCompleted(kTestEmail);
236 ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
239 #endif // !defined(OS_CHROMEOS)
241 TEST_F(AccountReconcilorTest, ProfileAlreadyConnected) {
242 signin_manager()->SetAuthenticatedUsername(kTestEmail);
244 AccountReconcilor* reconcilor =
245 AccountReconcilorFactory::GetForProfile(profile());
246 ASSERT_TRUE(reconcilor);
247 ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
250 TEST_F(AccountReconcilorTest, GetAccountsFromCookieSuccess) {
251 signin_manager()->SetAuthenticatedUsername(kTestEmail);
252 token_service()->UpdateCredentials(kTestEmail, "refresh_token");
253 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(kTestEmail));
254 AccountReconcilor* reconcilor =
255 AccountReconcilorFactory::GetForProfile(profile());
256 ASSERT_TRUE(reconcilor);
258 SetFakeResponse(list_accounts_url().spec(),
259 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 0]]]",
260 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
262 reconcilor->StartReconcile();
263 ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
265 base::RunLoop().RunUntilIdle();
266 ASSERT_TRUE(reconcilor->AreGaiaAccountsSet());
267 const std::vector<std::pair<std::string, bool> >& accounts =
268 reconcilor->GetGaiaAccountsForTesting();
269 ASSERT_EQ(1u, accounts.size());
270 ASSERT_EQ("user@gmail.com", accounts[0].first);
273 TEST_F(AccountReconcilorTest, GetAccountsFromCookieFailure) {
274 signin_manager()->SetAuthenticatedUsername(kTestEmail);
275 token_service()->UpdateCredentials(kTestEmail, "refresh_token");
276 AccountReconcilor* reconcilor =
277 AccountReconcilorFactory::GetForProfile(profile());
278 ASSERT_TRUE(reconcilor);
280 SetFakeResponse(list_accounts_url().spec(), "",
281 net::HTTP_NOT_FOUND, net::URLRequestStatus::SUCCESS);
283 reconcilor->StartReconcile();
284 ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
286 base::RunLoop().RunUntilIdle();
287 ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
290 TEST_P(AccountReconcilorTest, StartReconcileNoop) {
291 signin_manager()->SetAuthenticatedUsername(kTestEmail);
292 token_service()->UpdateCredentials(kTestEmail, "refresh_token");
294 AccountReconcilor* reconcilor =
295 AccountReconcilorFactory::GetForProfile(profile());
296 ASSERT_TRUE(reconcilor);
298 SetFakeResponse(list_accounts_url().spec(),
299 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
300 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
302 reconcilor->StartReconcile();
303 ASSERT_TRUE(reconcilor->is_reconcile_started_);
304 ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
306 base::RunLoop().RunUntilIdle();
307 ASSERT_FALSE(reconcilor->is_reconcile_started_);
309 histogram_tester()->ExpectTotalCount(
310 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun", 1);
311 histogram_tester()->ExpectUniqueSample(
312 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
313 signin_metrics::ACCOUNTS_SAME,
317 // This is test is needed until chrome changes to use gaia obfuscated id.
318 // The signin manager and token service use the gaia "email" property, which
319 // preserves dots in usernames and preserves case. gaia::ParseListAccountsData()
320 // however uses gaia "displayEmail" which does not preserve case, and then
321 // passes the string through gaia::CanonicalizeEmail() which removes dots. This
322 // tests makes sure that an email like "Dot.S@hmail.com", as seen by the
323 // token service, will be considered the same as "dots@gmail.com" as returned
324 // by gaia::ParseListAccountsData().
325 TEST_P(AccountReconcilorTest, StartReconcileNoopWithDots) {
326 signin_manager()->SetAuthenticatedUsername("Dot.S@gmail.com");
327 token_service()->UpdateCredentials("Dot.S@gmail.com", "refresh_token");
329 AccountReconcilor* reconcilor =
330 AccountReconcilorFactory::GetForProfile(profile());
331 ASSERT_TRUE(reconcilor);
333 SetFakeResponse(list_accounts_url().spec(),
334 "[\"f\", [[\"b\", 0, \"n\", \"dot.s@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
335 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
337 reconcilor->StartReconcile();
338 ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
340 base::RunLoop().RunUntilIdle();
341 ASSERT_FALSE(reconcilor->is_reconcile_started_);
343 histogram_tester()->ExpectUniqueSample(
344 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
345 signin_metrics::ACCOUNTS_SAME,
349 TEST_P(AccountReconcilorTest, StartReconcileNoopMultiple) {
350 signin_manager()->SetAuthenticatedUsername("user@gmail.com");
351 token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
352 token_service()->UpdateCredentials("other@gmail.com", "refresh_token");
354 AccountReconcilor* reconcilor =
355 AccountReconcilorFactory::GetForProfile(profile());
356 ASSERT_TRUE(reconcilor);
358 SetFakeResponse(list_accounts_url().spec(),
359 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1], "
360 "[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
361 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
363 reconcilor->StartReconcile();
364 ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
365 base::RunLoop().RunUntilIdle();
366 ASSERT_FALSE(reconcilor->is_reconcile_started_);
368 histogram_tester()->ExpectTotalCount(
369 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun", 1);
370 histogram_tester()->ExpectUniqueSample(
371 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
372 signin_metrics::ACCOUNTS_SAME,
376 TEST_P(AccountReconcilorTest, StartReconcileAddToCookie) {
377 signin_manager()->SetAuthenticatedUsername("user@gmail.com");
378 token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
379 token_service()->UpdateCredentials("other@gmail.com", "refresh_token");
381 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("other@gmail.com"));
383 SetFakeResponse(list_accounts_url().spec(),
384 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
385 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
387 AccountReconcilor* reconcilor = GetMockReconcilor();
388 reconcilor->StartReconcile();
390 base::RunLoop().RunUntilIdle();
391 ASSERT_TRUE(reconcilor->is_reconcile_started_);
392 SimulateMergeSessionCompleted(reconcilor, "other@gmail.com",
393 GoogleServiceAuthError::AuthErrorNone());
394 ASSERT_FALSE(reconcilor->is_reconcile_started_);
396 histogram_tester()->ExpectUniqueSample(
397 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
398 signin_metrics::ACCOUNTS_SAME,
400 histogram_tester()->ExpectUniqueSample(
401 "Signin.Reconciler.AddedToCookieJar.FirstRun", 1, 1);
402 histogram_tester()->ExpectUniqueSample(
403 "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 0, 1);
406 TEST_P(AccountReconcilorTest, StartReconcileRemoveFromCookie) {
407 signin_manager()->SetAuthenticatedUsername("user@gmail.com");
408 token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
410 EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
411 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("user@gmail.com"));
413 SetFakeResponse(list_accounts_url().spec(),
414 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1], "
415 "[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
416 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
418 AccountReconcilor* reconcilor = GetMockReconcilor();
419 reconcilor->StartReconcile();
420 ASSERT_TRUE(reconcilor->is_reconcile_started_);
422 base::RunLoop().RunUntilIdle();
423 SimulateMergeSessionCompleted(reconcilor, "user@gmail.com",
424 GoogleServiceAuthError::AuthErrorNone());
425 ASSERT_FALSE(reconcilor->is_reconcile_started_);
427 histogram_tester()->ExpectUniqueSample(
428 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
429 signin_metrics::ACCOUNTS_SAME,
431 histogram_tester()->ExpectUniqueSample(
432 "Signin.Reconciler.AddedToCookieJar.FirstRun", 0, 1);
433 histogram_tester()->ExpectUniqueSample(
434 "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 1, 1);
437 TEST_P(AccountReconcilorTest, StartReconcileAddToCookieTwice) {
438 signin_manager()->SetAuthenticatedUsername("user@gmail.com");
439 token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
440 token_service()->UpdateCredentials("other@gmail.com", "refresh_token");
442 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("other@gmail.com"));
443 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("third@gmail.com"));
446 list_accounts_url().spec(),
447 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
449 net::URLRequestStatus::SUCCESS);
451 AccountReconcilor* reconcilor = GetMockReconcilor();
452 reconcilor->StartReconcile();
454 base::RunLoop().RunUntilIdle();
455 ASSERT_TRUE(reconcilor->is_reconcile_started_);
456 SimulateMergeSessionCompleted(
457 reconcilor, "other@gmail.com", GoogleServiceAuthError::AuthErrorNone());
458 ASSERT_FALSE(reconcilor->is_reconcile_started_);
460 histogram_tester()->ExpectUniqueSample(
461 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
462 signin_metrics::ACCOUNTS_SAME,
464 histogram_tester()->ExpectUniqueSample(
465 "Signin.Reconciler.AddedToCookieJar.FirstRun", 1, 1);
466 histogram_tester()->ExpectUniqueSample(
467 "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 0, 1);
469 // Do another pass after I've added a third account to the token service
472 list_accounts_url().spec(),
473 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1], "
474 "[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
476 net::URLRequestStatus::SUCCESS);
477 // This will cause the reconcilor to fire.
478 token_service()->UpdateCredentials("third@gmail.com", "refresh_token");
480 base::RunLoop().RunUntilIdle();
482 ASSERT_TRUE(reconcilor->is_reconcile_started_);
483 SimulateMergeSessionCompleted(
484 reconcilor, "third@gmail.com", GoogleServiceAuthError::AuthErrorNone());
485 ASSERT_FALSE(reconcilor->is_reconcile_started_);
487 histogram_tester()->ExpectUniqueSample(
488 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
489 signin_metrics::ACCOUNTS_SAME,
491 histogram_tester()->ExpectUniqueSample(
492 "Signin.Reconciler.AddedToCookieJar.FirstRun", 1, 1);
493 histogram_tester()->ExpectUniqueSample(
494 "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 0, 1);
495 histogram_tester()->ExpectUniqueSample(
496 "Signin.Reconciler.DifferentPrimaryAccounts.SubsequentRun",
497 signin_metrics::ACCOUNTS_SAME,
499 histogram_tester()->ExpectUniqueSample(
500 "Signin.Reconciler.AddedToCookieJar.SubsequentRun", 1, 1);
501 histogram_tester()->ExpectUniqueSample(
502 "Signin.Reconciler.RemovedFromCookieJar.SubsequentRun", 0, 1);
505 TEST_P(AccountReconcilorTest, StartReconcileBadPrimary) {
506 signin_manager()->SetAuthenticatedUsername("user@gmail.com");
507 token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
508 token_service()->UpdateCredentials("other@gmail.com", "refresh_token");
510 EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
511 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("user@gmail.com"));
512 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("other@gmail.com"));
514 SetFakeResponse(list_accounts_url().spec(),
515 "[\"f\", [[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1], "
516 "[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
517 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
519 AccountReconcilor* reconcilor = GetMockReconcilor();
520 reconcilor->StartReconcile();
522 base::RunLoop().RunUntilIdle();
523 ASSERT_TRUE(reconcilor->is_reconcile_started_);
524 SimulateMergeSessionCompleted(reconcilor, "other@gmail.com",
525 GoogleServiceAuthError::AuthErrorNone());
526 ASSERT_TRUE(reconcilor->is_reconcile_started_);
527 SimulateMergeSessionCompleted(reconcilor, "user@gmail.com",
528 GoogleServiceAuthError::AuthErrorNone());
529 ASSERT_FALSE(reconcilor->is_reconcile_started_);
531 histogram_tester()->ExpectUniqueSample(
532 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
533 signin_metrics::COOKIE_AND_TOKEN_PRIMARIES_DIFFERENT,
535 histogram_tester()->ExpectUniqueSample(
536 "Signin.Reconciler.AddedToCookieJar.FirstRun", 0, 1);
537 histogram_tester()->ExpectUniqueSample(
538 "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 0, 1);
541 TEST_P(AccountReconcilorTest, StartReconcileOnlyOnce) {
542 signin_manager()->SetAuthenticatedUsername(kTestEmail);
543 token_service()->UpdateCredentials(kTestEmail, "refresh_token");
545 AccountReconcilor* reconcilor =
546 AccountReconcilorFactory::GetForProfile(profile());
547 ASSERT_TRUE(reconcilor);
549 SetFakeResponse(list_accounts_url().spec(),
550 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
551 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
553 ASSERT_FALSE(reconcilor->is_reconcile_started_);
554 reconcilor->StartReconcile();
555 ASSERT_TRUE(reconcilor->is_reconcile_started_);
557 base::RunLoop().RunUntilIdle();
558 ASSERT_FALSE(reconcilor->is_reconcile_started_);
561 TEST_P(AccountReconcilorTest, StartReconcileWithSessionInfoExpiredDefault) {
562 signin_manager()->SetAuthenticatedUsername("user@gmail.com");
563 token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
564 token_service()->UpdateCredentials("other@gmail.com", "refresh_token");
566 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("user@gmail.com"));
568 SetFakeResponse(list_accounts_url().spec(),
569 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 0],"
570 "[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
571 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
573 AccountReconcilor* reconcilor =
574 AccountReconcilorFactory::GetForProfile(profile());
575 ASSERT_TRUE(reconcilor);
577 ASSERT_FALSE(reconcilor->is_reconcile_started_);
578 reconcilor->StartReconcile();
579 ASSERT_TRUE(reconcilor->is_reconcile_started_);
581 base::RunLoop().RunUntilIdle();
582 SimulateMergeSessionCompleted(reconcilor, "user@gmail.com",
583 GoogleServiceAuthError::AuthErrorNone());
584 ASSERT_FALSE(reconcilor->is_reconcile_started_);
587 TEST_F(AccountReconcilorTest, MergeSessionCompletedWithBogusAccount) {
588 signin_manager()->SetAuthenticatedUsername("user@gmail.com");
589 token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
591 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("user@gmail.com"));
593 SetFakeResponse(list_accounts_url().spec(),
594 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 0]]]",
595 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
597 AccountReconcilor* reconcilor =
598 AccountReconcilorFactory::GetForProfile(profile());
599 ASSERT_TRUE(reconcilor);
601 ASSERT_FALSE(reconcilor->is_reconcile_started_);
602 reconcilor->StartReconcile();
603 ASSERT_TRUE(reconcilor->is_reconcile_started_);
605 base::RunLoop().RunUntilIdle();
607 // If an unknown account id is sent, it should not upset the state.
608 SimulateMergeSessionCompleted(reconcilor, "bogus@gmail.com",
609 GoogleServiceAuthError::AuthErrorNone());
610 ASSERT_TRUE(reconcilor->is_reconcile_started_);
612 SimulateMergeSessionCompleted(reconcilor, "user@gmail.com",
613 GoogleServiceAuthError::AuthErrorNone());
614 ASSERT_FALSE(reconcilor->is_reconcile_started_);
617 INSTANTIATE_TEST_CASE_P(AccountReconcilorMaybeEnabled,
618 AccountReconcilorTest,