Unwind the URL-based experiment IDs.
[chromium-blink-merge.git] / chrome / browser / signin / account_reconcilor_unittest.cc
blob7d6e9c5ae21cf48615471cacc8611124dfd85688
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_profile_oauth2_token_service.h"
17 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
18 #include "chrome/browser/signin/fake_signin_manager.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/profile_oauth2_token_service.h"
29 #include "components/signin/core/browser/signin_manager.h"
30 #include "components/signin/core/browser/signin_metrics.h"
31 #include "components/signin/core/browser/test_signin_client.h"
32 #include "components/signin/core/common/profile_management_switches.h"
33 #include "components/signin/core/common/signin_switches.h"
34 #include "content/public/test/test_browser_thread_bundle.h"
35 #include "google_apis/gaia/gaia_constants.h"
36 #include "google_apis/gaia/gaia_urls.h"
37 #include "net/url_request/test_url_fetcher_factory.h"
38 #include "testing/gmock/include/gmock/gmock.h"
39 #include "testing/gtest/include/gtest/gtest.h"
41 namespace {
43 class MockAccountReconcilor : public testing::StrictMock<AccountReconcilor> {
44 public:
45 static KeyedService* Build(content::BrowserContext* context);
47 MockAccountReconcilor(ProfileOAuth2TokenService* token_service,
48 SigninManagerBase* signin_manager,
49 SigninClient* client,
50 GaiaCookieManagerService* cookie_manager_service);
51 ~MockAccountReconcilor() override {}
53 MOCK_METHOD1(PerformMergeAction, void(const std::string& account_id));
54 MOCK_METHOD0(PerformLogoutAllAccountsAction, void());
57 // static
58 KeyedService* MockAccountReconcilor::Build(content::BrowserContext* context) {
59 Profile* profile = Profile::FromBrowserContext(context);
60 AccountReconcilor* reconcilor = new MockAccountReconcilor(
61 ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
62 SigninManagerFactory::GetForProfile(profile),
63 ChromeSigninClientFactory::GetForProfile(profile),
64 GaiaCookieManagerServiceFactory::GetForProfile(profile));
65 reconcilor->Initialize(false /* start_reconcile_if_tokens_available */);
66 return reconcilor;
69 MockAccountReconcilor::MockAccountReconcilor(
70 ProfileOAuth2TokenService* token_service,
71 SigninManagerBase* signin_manager,
72 SigninClient* client,
73 GaiaCookieManagerService* cookie_manager_service)
74 : testing::StrictMock<AccountReconcilor>(token_service,
75 signin_manager,
76 client,
77 cookie_manager_service) {}
79 } // namespace
81 class AccountReconcilorTest : public ::testing::TestWithParam<bool> {
82 public:
83 AccountReconcilorTest();
84 void SetUp() override;
86 TestingProfile* profile() { return profile_; }
87 FakeSigninManagerForTesting* signin_manager() { return signin_manager_; }
88 FakeProfileOAuth2TokenService* token_service() { return token_service_; }
89 TestSigninClient* test_signin_client() { return test_signin_client_; }
90 AccountTrackerService* account_tracker() { return account_tracker_; }
91 base::HistogramTester* histogram_tester() { return &histogram_tester_; }
93 void SetFakeResponse(const std::string& url,
94 const std::string& data,
95 net::HttpStatusCode code,
96 net::URLRequestStatus::Status status) {
97 url_fetcher_factory_.SetFakeResponse(GURL(url), data, code, status);
100 MockAccountReconcilor* GetMockReconcilor();
102 std::string ConnectProfileToAccount(const std::string& gaia_id,
103 const std::string& username);
105 std::string PickAccountIdForAccount(const std::string& gaia_id,
106 const std::string& username);
108 void SimulateAddAccountToCookieCompleted(
109 GaiaCookieManagerService::Observer* observer,
110 const std::string& account_id,
111 const GoogleServiceAuthError& error);
113 void SimulateCookieContentSettingsChanged(
114 content_settings::Observer* observer,
115 const ContentSettingsPattern& primary_pattern);
117 GURL list_accounts_url() { return list_accounts_url_; }
118 GURL get_check_connection_info_url() {
119 return get_check_connection_info_url_;
122 private:
123 content::TestBrowserThreadBundle bundle_;
124 TestingProfile* profile_;
125 FakeSigninManagerForTesting* signin_manager_;
126 FakeProfileOAuth2TokenService* token_service_;
127 TestSigninClient* test_signin_client_;
128 AccountTrackerService* account_tracker_;
129 MockAccountReconcilor* mock_reconcilor_;
130 net::FakeURLFetcherFactory url_fetcher_factory_;
131 scoped_ptr<TestingProfileManager> testing_profile_manager_;
132 base::HistogramTester histogram_tester_;
133 GURL list_accounts_url_;
134 GURL get_check_connection_info_url_;
136 DISALLOW_COPY_AND_ASSIGN(AccountReconcilorTest);
139 AccountReconcilorTest::AccountReconcilorTest()
140 : signin_manager_(NULL),
141 token_service_(NULL),
142 test_signin_client_(NULL),
143 mock_reconcilor_(NULL),
144 url_fetcher_factory_(NULL) {}
146 void AccountReconcilorTest::SetUp() {
147 // If it's a non-parameterized test, or we have a parameter of true, set flag.
148 if (!::testing::UnitTest::GetInstance()->current_test_info()->value_param() ||
149 GetParam()) {
150 base::CommandLine::ForCurrentProcess()->AppendSwitch(
151 switches::kEnableNewProfileManagement);
154 list_accounts_url_ = GaiaUrls::GetInstance()->ListAccountsURLWithSource(
155 GaiaConstants::kReconcilorSource);
156 get_check_connection_info_url_ =
157 GaiaUrls::GetInstance()->GetCheckConnectionInfoURLWithSource(
158 GaiaConstants::kChromeSource);
160 // Specific tests may set a response that includes specific accounts.
161 SetFakeResponse(list_accounts_url().spec(), "",
162 net::HTTP_NOT_FOUND, net::URLRequestStatus::SUCCESS);
164 testing_profile_manager_.reset(
165 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
166 ASSERT_TRUE(testing_profile_manager_.get()->SetUp());
168 TestingProfile::TestingFactories factories;
169 factories.push_back(std::make_pair(ChromeSigninClientFactory::GetInstance(),
170 signin::BuildTestSigninClient));
171 factories.push_back(std::make_pair(
172 ProfileOAuth2TokenServiceFactory::GetInstance(),
173 BuildFakeProfileOAuth2TokenService));
174 factories.push_back(std::make_pair(SigninManagerFactory::GetInstance(),
175 FakeSigninManagerBase::Build));
176 factories.push_back(std::make_pair(AccountReconcilorFactory::GetInstance(),
177 MockAccountReconcilor::Build));
179 profile_ = testing_profile_manager_.get()->CreateTestingProfile("name",
180 scoped_ptr<PrefServiceSyncable>(),
181 base::UTF8ToUTF16("name"), 0, std::string(),
182 factories);
184 test_signin_client_ =
185 static_cast<TestSigninClient*>(
186 ChromeSigninClientFactory::GetForProfile(profile()));
188 token_service_ =
189 static_cast<FakeProfileOAuth2TokenService*>(
190 ProfileOAuth2TokenServiceFactory::GetForProfile(profile()));
192 account_tracker_ =
193 AccountTrackerServiceFactory::GetForProfile(profile());
195 signin_manager_ =
196 static_cast<FakeSigninManagerForTesting*>(
197 SigninManagerFactory::GetForProfile(profile()));
200 MockAccountReconcilor* AccountReconcilorTest::GetMockReconcilor() {
201 if (!mock_reconcilor_) {
202 mock_reconcilor_ =
203 static_cast<MockAccountReconcilor*>(
204 AccountReconcilorFactory::GetForProfile(profile()));
207 return mock_reconcilor_;
210 std::string AccountReconcilorTest::ConnectProfileToAccount(
211 const std::string& gaia_id,
212 const std::string& username) {
213 const std::string account_id = PickAccountIdForAccount(gaia_id, username);
214 #if !defined(OS_CHROMEOS)
215 signin_manager()->set_password("password");
216 #endif
217 signin_manager()->SetAuthenticatedAccountInfo(gaia_id, username);
218 token_service()->UpdateCredentials(account_id, "refresh_token");
219 return account_id;
222 std::string AccountReconcilorTest::PickAccountIdForAccount(
223 const std::string& gaia_id,
224 const std::string& username) {
225 return account_tracker()->PickAccountIdForAccount(gaia_id, username);
228 void AccountReconcilorTest::SimulateAddAccountToCookieCompleted(
229 GaiaCookieManagerService::Observer* observer,
230 const std::string& account_id,
231 const GoogleServiceAuthError& error) {
232 observer->OnAddAccountToCookieCompleted(account_id, error);
235 void AccountReconcilorTest::SimulateCookieContentSettingsChanged(
236 content_settings::Observer* observer,
237 const ContentSettingsPattern& primary_pattern) {
238 observer->OnContentSettingChanged(
239 primary_pattern,
240 ContentSettingsPattern::Wildcard(),
241 CONTENT_SETTINGS_TYPE_COOKIES,
242 std::string());
245 TEST_F(AccountReconcilorTest, Basic) {
246 AccountReconcilor* reconcilor =
247 AccountReconcilorFactory::GetForProfile(profile());
248 ASSERT_TRUE(reconcilor);
251 #if !defined(OS_CHROMEOS)
253 // This method requires the use of the |TestSigninClient| to be created from the
254 // |ChromeSigninClientFactory| because it overrides the |GoogleSigninSucceeded|
255 // method with an empty implementation. On MacOS, the normal implementation
256 // causes the try_bots to time out.
257 TEST_F(AccountReconcilorTest, SigninManagerRegistration) {
258 AccountReconcilor* reconcilor =
259 AccountReconcilorFactory::GetForProfile(profile());
260 ASSERT_TRUE(reconcilor);
261 ASSERT_FALSE(reconcilor->IsRegisteredWithTokenService());
263 account_tracker()->SeedAccountInfo("12345", "user@gmail.com");
264 signin_manager()->SignIn("12345", "user@gmail.com", "password");
265 ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
267 EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
269 signin_manager()->SignOut(signin_metrics::SIGNOUT_TEST);
270 ASSERT_FALSE(reconcilor->IsRegisteredWithTokenService());
273 // This method requires the use of the |TestSigninClient| to be created from the
274 // |ChromeSigninClientFactory| because it overrides the |GoogleSigninSucceeded|
275 // method with an empty implementation. On MacOS, the normal implementation
276 // causes the try_bots to time out.
277 TEST_F(AccountReconcilorTest, Reauth) {
278 const std::string email = "user@gmail.com";
279 const std::string account_id =
280 ConnectProfileToAccount("12345", email);
282 AccountReconcilor* reconcilor =
283 AccountReconcilorFactory::GetForProfile(profile());
284 ASSERT_TRUE(reconcilor);
285 ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
287 // Simulate reauth. The state of the reconcilor should not change.
288 signin_manager()->OnExternalSigninCompleted(email);
289 ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
292 #endif // !defined(OS_CHROMEOS)
294 TEST_F(AccountReconcilorTest, ProfileAlreadyConnected) {
295 ConnectProfileToAccount("12345", "user@gmail.com");
297 AccountReconcilor* reconcilor =
298 AccountReconcilorFactory::GetForProfile(profile());
299 ASSERT_TRUE(reconcilor);
300 ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
303 TEST_F(AccountReconcilorTest, GetAccountsFromCookieSuccess) {
304 const std::string account_id =
305 ConnectProfileToAccount("12345", "user@gmail.com");
306 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id));
308 AccountReconcilor* reconcilor =
309 AccountReconcilorFactory::GetForProfile(profile());
310 ASSERT_TRUE(reconcilor);
312 SetFakeResponse(list_accounts_url().spec(),
313 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 0]]]",
314 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
316 reconcilor->StartReconcile();
317 ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
319 base::RunLoop().RunUntilIdle();
320 ASSERT_TRUE(reconcilor->AreGaiaAccountsSet());
321 const std::vector<std::pair<std::string, bool> >& accounts =
322 reconcilor->GetGaiaAccountsForTesting();
323 ASSERT_EQ(1u, accounts.size());
324 ASSERT_EQ(account_id, accounts[0].first);
327 TEST_F(AccountReconcilorTest, GetAccountsFromCookieFailure) {
328 ConnectProfileToAccount("12345", "user@gmail.com");
329 AccountReconcilor* reconcilor =
330 AccountReconcilorFactory::GetForProfile(profile());
331 ASSERT_TRUE(reconcilor);
333 SetFakeResponse(list_accounts_url().spec(), "",
334 net::HTTP_NOT_FOUND, net::URLRequestStatus::SUCCESS);
336 reconcilor->StartReconcile();
337 ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
339 base::RunLoop().RunUntilIdle();
340 ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
343 TEST_P(AccountReconcilorTest, StartReconcileNoop) {
344 const std::string account_id =
345 ConnectProfileToAccount("12345", "user@gmail.com");
347 AccountReconcilor* reconcilor =
348 AccountReconcilorFactory::GetForProfile(profile());
349 ASSERT_TRUE(reconcilor);
351 SetFakeResponse(list_accounts_url().spec(),
352 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
353 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
355 reconcilor->StartReconcile();
356 ASSERT_TRUE(reconcilor->is_reconcile_started_);
357 ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
359 base::RunLoop().RunUntilIdle();
360 ASSERT_FALSE(reconcilor->is_reconcile_started_);
362 histogram_tester()->ExpectTotalCount(
363 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun", 1);
364 histogram_tester()->ExpectUniqueSample(
365 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
366 signin_metrics::ACCOUNTS_SAME,
370 TEST_P(AccountReconcilorTest, StartReconcileCookiesDisabled) {
371 const std::string account_id =
372 ConnectProfileToAccount("12345", "user@gmail.com");
373 token_service()->UpdateCredentials(account_id, "refresh_token");
374 test_signin_client()->set_are_signin_cookies_allowed(false);
376 AccountReconcilor* reconcilor =
377 AccountReconcilorFactory::GetForProfile(profile());
378 ASSERT_TRUE(reconcilor);
380 reconcilor->StartReconcile();
381 ASSERT_FALSE(reconcilor->is_reconcile_started_);
382 ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
384 base::RunLoop().RunUntilIdle();
385 ASSERT_FALSE(reconcilor->is_reconcile_started_);
388 TEST_P(AccountReconcilorTest, StartReconcileContentSettings) {
389 const std::string account_id =
390 ConnectProfileToAccount("12345", "user@gmail.com");
391 token_service()->UpdateCredentials(account_id, "refresh_token");
393 AccountReconcilor* reconcilor =
394 AccountReconcilorFactory::GetForProfile(profile());
395 ASSERT_TRUE(reconcilor);
397 test_signin_client()->set_are_signin_cookies_allowed(false);
398 SimulateCookieContentSettingsChanged(reconcilor,
399 ContentSettingsPattern::Wildcard());
400 ASSERT_FALSE(reconcilor->is_reconcile_started_);
402 test_signin_client()->set_are_signin_cookies_allowed(true);
403 SimulateCookieContentSettingsChanged(reconcilor,
404 ContentSettingsPattern::Wildcard());
405 ASSERT_TRUE(reconcilor->is_reconcile_started_);
408 TEST_P(AccountReconcilorTest, StartReconcileContentSettingsGaiaUrl) {
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 SimulateCookieContentSettingsChanged(
418 reconcilor,
419 ContentSettingsPattern::FromURL(GaiaUrls::GetInstance()->gaia_url()));
420 ASSERT_TRUE(reconcilor->is_reconcile_started_);
423 TEST_P(AccountReconcilorTest, StartReconcileContentSettingsNonGaiaUrl) {
424 const std::string account_id =
425 ConnectProfileToAccount("12345", "user@gmail.com");
426 token_service()->UpdateCredentials(account_id, "refresh_token");
428 AccountReconcilor* reconcilor =
429 AccountReconcilorFactory::GetForProfile(profile());
430 ASSERT_TRUE(reconcilor);
432 SimulateCookieContentSettingsChanged(
433 reconcilor,
434 ContentSettingsPattern::FromURL(GURL("http://www.example.com")));
435 ASSERT_FALSE(reconcilor->is_reconcile_started_);
438 TEST_P(AccountReconcilorTest, StartReconcileContentSettingsInvalidPattern) {
439 const std::string account_id =
440 ConnectProfileToAccount("12345", "user@gmail.com");
441 token_service()->UpdateCredentials(account_id, "refresh_token");
443 AccountReconcilor* reconcilor =
444 AccountReconcilorFactory::GetForProfile(profile());
445 ASSERT_TRUE(reconcilor);
447 scoped_ptr<ContentSettingsPattern::BuilderInterface>
448 builder(ContentSettingsPattern::CreateBuilder(false));
449 builder->Invalid();
451 SimulateCookieContentSettingsChanged(reconcilor, builder->Build());
452 ASSERT_TRUE(reconcilor->is_reconcile_started_);
455 // This test is needed until chrome changes to use gaia obfuscated id.
456 // The signin manager and token service use the gaia "email" property, which
457 // preserves dots in usernames and preserves case. gaia::ParseListAccountsData()
458 // however uses gaia "displayEmail" which does not preserve case, and then
459 // passes the string through gaia::CanonicalizeEmail() which removes dots. This
460 // tests makes sure that an email like "Dot.S@hmail.com", as seen by the
461 // token service, will be considered the same as "dots@gmail.com" as returned
462 // by gaia::ParseListAccountsData().
463 TEST_P(AccountReconcilorTest, StartReconcileNoopWithDots) {
464 if (account_tracker()->GetMigrationState() !=
465 AccountTrackerService::MIGRATION_NOT_STARTED) {
466 return;
469 const std::string account_id =
470 ConnectProfileToAccount("12345", "Dot.S@gmail.com");
471 AccountReconcilor* reconcilor =
472 AccountReconcilorFactory::GetForProfile(profile());
473 ASSERT_TRUE(reconcilor);
475 SetFakeResponse(list_accounts_url().spec(),
476 "[\"f\", [[\"b\", 0, \"n\", \"dot.s@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
477 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
479 reconcilor->StartReconcile();
480 ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
482 base::RunLoop().RunUntilIdle();
483 ASSERT_FALSE(reconcilor->is_reconcile_started_);
485 histogram_tester()->ExpectUniqueSample(
486 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
487 signin_metrics::ACCOUNTS_SAME,
491 TEST_P(AccountReconcilorTest, StartReconcileNoopMultiple) {
492 const std::string account_id =
493 ConnectProfileToAccount("12345", "user@gmail.com");
494 const std::string account_id2 =
495 PickAccountIdForAccount("67890", "other@gmail.com");
496 token_service()->UpdateCredentials(account_id2, "refresh_token");
498 AccountReconcilor* reconcilor =
499 AccountReconcilorFactory::GetForProfile(profile());
500 ASSERT_TRUE(reconcilor);
502 SetFakeResponse(list_accounts_url().spec(),
503 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1], "
504 "[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
505 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
507 reconcilor->StartReconcile();
508 ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
509 base::RunLoop().RunUntilIdle();
510 ASSERT_FALSE(reconcilor->is_reconcile_started_);
512 histogram_tester()->ExpectTotalCount(
513 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun", 1);
514 histogram_tester()->ExpectUniqueSample(
515 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
516 signin_metrics::ACCOUNTS_SAME,
520 TEST_P(AccountReconcilorTest, StartReconcileAddToCookie) {
521 const std::string account_id =
522 ConnectProfileToAccount("12345", "user@gmail.com");
523 token_service()->UpdateCredentials(account_id, "refresh_token");
525 const std::string account_id2 =
526 PickAccountIdForAccount("67890", "other@gmail.com");
527 token_service()->UpdateCredentials(account_id2, "refresh_token");
529 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id2));
531 SetFakeResponse(list_accounts_url().spec(),
532 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
533 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
535 AccountReconcilor* reconcilor = GetMockReconcilor();
536 reconcilor->StartReconcile();
538 base::RunLoop().RunUntilIdle();
539 ASSERT_TRUE(reconcilor->is_reconcile_started_);
540 SimulateAddAccountToCookieCompleted(reconcilor, account_id2,
541 GoogleServiceAuthError::AuthErrorNone());
542 ASSERT_FALSE(reconcilor->is_reconcile_started_);
544 histogram_tester()->ExpectUniqueSample(
545 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
546 signin_metrics::ACCOUNTS_SAME,
548 histogram_tester()->ExpectUniqueSample(
549 "Signin.Reconciler.AddedToCookieJar.FirstRun", 1, 1);
550 histogram_tester()->ExpectUniqueSample(
551 "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 0, 1);
554 TEST_P(AccountReconcilorTest, StartReconcileRemoveFromCookie) {
555 const std::string account_id =
556 ConnectProfileToAccount("12345", "user@gmail.com");
557 token_service()->UpdateCredentials(account_id, "refresh_token");
559 EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
560 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id));
562 SetFakeResponse(list_accounts_url().spec(),
563 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1], "
564 "[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
565 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
567 AccountReconcilor* reconcilor = GetMockReconcilor();
568 reconcilor->StartReconcile();
569 ASSERT_TRUE(reconcilor->is_reconcile_started_);
571 base::RunLoop().RunUntilIdle();
572 SimulateAddAccountToCookieCompleted(reconcilor, "user@gmail.com",
573 GoogleServiceAuthError::AuthErrorNone());
574 ASSERT_FALSE(reconcilor->is_reconcile_started_);
576 histogram_tester()->ExpectUniqueSample(
577 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
578 signin_metrics::ACCOUNTS_SAME,
580 histogram_tester()->ExpectUniqueSample(
581 "Signin.Reconciler.AddedToCookieJar.FirstRun", 0, 1);
582 histogram_tester()->ExpectUniqueSample(
583 "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 1, 1);
586 TEST_P(AccountReconcilorTest, StartReconcileAddToCookieTwice) {
587 const std::string account_id =
588 ConnectProfileToAccount("12345", "user@gmail.com");
589 const std::string account_id2 =
590 PickAccountIdForAccount("67890", "other@gmail.com");
591 const std::string account_id3 =
592 PickAccountIdForAccount("34567", "third@gmail.com");
594 token_service()->UpdateCredentials(account_id2, "refresh_token");
596 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id2));
597 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id3));
599 SetFakeResponse(
600 list_accounts_url().spec(),
601 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
602 net::HTTP_OK,
603 net::URLRequestStatus::SUCCESS);
605 AccountReconcilor* reconcilor = GetMockReconcilor();
606 reconcilor->StartReconcile();
608 base::RunLoop().RunUntilIdle();
609 ASSERT_TRUE(reconcilor->is_reconcile_started_);
610 SimulateAddAccountToCookieCompleted(
611 reconcilor, account_id2, GoogleServiceAuthError::AuthErrorNone());
612 ASSERT_FALSE(reconcilor->is_reconcile_started_);
614 histogram_tester()->ExpectUniqueSample(
615 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
616 signin_metrics::ACCOUNTS_SAME,
618 histogram_tester()->ExpectUniqueSample(
619 "Signin.Reconciler.AddedToCookieJar.FirstRun", 1, 1);
620 histogram_tester()->ExpectUniqueSample(
621 "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 0, 1);
623 // Do another pass after I've added a third account to the token service
625 SetFakeResponse(
626 list_accounts_url().spec(),
627 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1], "
628 "[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
629 net::HTTP_OK,
630 net::URLRequestStatus::SUCCESS);
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");
666 EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
667 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id));
668 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id2));
670 SetFakeResponse(list_accounts_url().spec(),
671 "[\"f\", [[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1], "
672 "[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
673 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
675 AccountReconcilor* reconcilor = GetMockReconcilor();
676 reconcilor->StartReconcile();
678 base::RunLoop().RunUntilIdle();
679 ASSERT_TRUE(reconcilor->is_reconcile_started_);
680 SimulateAddAccountToCookieCompleted(reconcilor, account_id2,
681 GoogleServiceAuthError::AuthErrorNone());
682 ASSERT_TRUE(reconcilor->is_reconcile_started_);
683 SimulateAddAccountToCookieCompleted(reconcilor, account_id,
684 GoogleServiceAuthError::AuthErrorNone());
685 ASSERT_FALSE(reconcilor->is_reconcile_started_);
687 histogram_tester()->ExpectUniqueSample(
688 "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
689 signin_metrics::COOKIE_AND_TOKEN_PRIMARIES_DIFFERENT,
691 histogram_tester()->ExpectUniqueSample(
692 "Signin.Reconciler.AddedToCookieJar.FirstRun", 0, 1);
693 histogram_tester()->ExpectUniqueSample(
694 "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 0, 1);
697 TEST_P(AccountReconcilorTest, StartReconcileOnlyOnce) {
698 const std::string account_id =
699 ConnectProfileToAccount("12345", "user@gmail.com");
701 AccountReconcilor* reconcilor =
702 AccountReconcilorFactory::GetForProfile(profile());
703 ASSERT_TRUE(reconcilor);
705 SetFakeResponse(list_accounts_url().spec(),
706 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
707 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
709 ASSERT_FALSE(reconcilor->is_reconcile_started_);
710 reconcilor->StartReconcile();
711 ASSERT_TRUE(reconcilor->is_reconcile_started_);
713 base::RunLoop().RunUntilIdle();
714 ASSERT_FALSE(reconcilor->is_reconcile_started_);
717 TEST_P(AccountReconcilorTest, StartReconcileWithSessionInfoExpiredDefault) {
718 const std::string account_id =
719 ConnectProfileToAccount("12345", "user@gmail.com");
720 const std::string account_id2 =
721 PickAccountIdForAccount("67890", "other@gmail.com");
722 token_service()->UpdateCredentials(account_id2, "refresh_token");
724 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id));
726 SetFakeResponse(list_accounts_url().spec(),
727 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 0],"
728 "[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
729 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
731 AccountReconcilor* reconcilor =
732 AccountReconcilorFactory::GetForProfile(profile());
733 ASSERT_TRUE(reconcilor);
735 ASSERT_FALSE(reconcilor->is_reconcile_started_);
736 reconcilor->StartReconcile();
737 ASSERT_TRUE(reconcilor->is_reconcile_started_);
739 base::RunLoop().RunUntilIdle();
740 SimulateAddAccountToCookieCompleted(reconcilor, account_id,
741 GoogleServiceAuthError::AuthErrorNone());
742 ASSERT_FALSE(reconcilor->is_reconcile_started_);
745 TEST_F(AccountReconcilorTest, AddAccountToCookieCompletedWithBogusAccount) {
746 const std::string account_id =
747 ConnectProfileToAccount("12345", "user@gmail.com");
749 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id));
751 SetFakeResponse(list_accounts_url().spec(),
752 "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 0]]]",
753 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
755 AccountReconcilor* reconcilor =
756 AccountReconcilorFactory::GetForProfile(profile());
757 ASSERT_TRUE(reconcilor);
759 ASSERT_FALSE(reconcilor->is_reconcile_started_);
760 reconcilor->StartReconcile();
761 ASSERT_TRUE(reconcilor->is_reconcile_started_);
763 base::RunLoop().RunUntilIdle();
765 // If an unknown account id is sent, it should not upset the state.
766 SimulateAddAccountToCookieCompleted(reconcilor, "bogus_account_id",
767 GoogleServiceAuthError::AuthErrorNone());
768 ASSERT_TRUE(reconcilor->is_reconcile_started_);
770 SimulateAddAccountToCookieCompleted(reconcilor, account_id,
771 GoogleServiceAuthError::AuthErrorNone());
772 ASSERT_FALSE(reconcilor->is_reconcile_started_);
775 INSTANTIATE_TEST_CASE_P(AccountReconcilorMaybeEnabled,
776 AccountReconcilorTest,
777 testing::Bool());