Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / signin / account_reconcilor_unittest.cc
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.
4
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"
36
37 namespace {
38
39 const char kTestEmail[] = "user@gmail.com";
40
41 class MockAccountReconcilor : public testing::StrictMock<AccountReconcilor> {
42  public:
43   static KeyedService* Build(content::BrowserContext* context);
44
45   MockAccountReconcilor(ProfileOAuth2TokenService* token_service,
46                         SigninManagerBase* signin_manager,
47                         SigninClient* client);
48   virtual ~MockAccountReconcilor() {}
49
50   virtual void StartFetchingExternalCcResult() override {
51     // Don't do this in tests.
52   }
53
54   MOCK_METHOD1(PerformMergeAction, void(const std::string& account_id));
55   MOCK_METHOD0(PerformLogoutAllAccountsAction, void());
56 };
57
58 // static
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 */);
66   return reconcilor;
67 }
68
69 MockAccountReconcilor::MockAccountReconcilor(
70     ProfileOAuth2TokenService* token_service,
71     SigninManagerBase* signin_manager,
72     SigninClient* client)
73     : testing::StrictMock<AccountReconcilor>(token_service,
74                                              signin_manager,
75                                              client) {}
76
77 }  // namespace
78
79 class AccountReconcilorTest : public ::testing::TestWithParam<bool> {
80  public:
81   AccountReconcilorTest();
82   void SetUp() override;
83
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_; }
88
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);
94   }
95
96   MockAccountReconcilor* GetMockReconcilor();
97
98   void SimulateMergeSessionCompleted(
99       MergeSessionHelper::Observer* observer,
100       const std::string& account_id,
101       const GoogleServiceAuthError& error);
102
103   GURL list_accounts_url() { return list_accounts_url_; }
104   GURL get_check_connection_info_url() {
105     return get_check_connection_info_url_;
106   }
107
108  private:
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_;
119
120   DISALLOW_COPY_AND_ASSIGN(AccountReconcilorTest);
121 };
122
123 AccountReconcilorTest::AccountReconcilorTest()
124     : signin_manager_(NULL),
125       token_service_(NULL),
126       mock_reconcilor_(NULL),
127       url_fetcher_factory_(NULL) {}
128
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() ||
132       GetParam()) {
133     CommandLine::ForCurrentProcess()->AppendSwitch(
134         switches::kEnableNewProfileManagement);
135   }
136
137   list_accounts_url_ = GaiaUrls::GetInstance()->ListAccountsURLWithSource(
138       GaiaConstants::kReconcilorSource);
139   get_check_connection_info_url_ =
140       GaiaUrls::GetInstance()->GetCheckConnectionInfoURLWithSource(
141           GaiaConstants::kReconcilorSource);
142
143   SetFakeResponse(get_check_connection_info_url().spec(), "[]",
144       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
145
146   testing_profile_manager_.reset(
147       new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
148   ASSERT_TRUE(testing_profile_manager_.get()->SetUp());
149
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));
160
161   profile_ = testing_profile_manager_.get()->CreateTestingProfile("name",
162                               scoped_ptr<PrefServiceSyncable>(),
163                               base::UTF8ToUTF16("name"), 0, std::string(),
164                               factories);
165
166   signin_manager_ =
167       static_cast<FakeSigninManagerForTesting*>(
168           SigninManagerFactory::GetForProfile(profile()));
169
170   token_service_ =
171       static_cast<FakeProfileOAuth2TokenService*>(
172           ProfileOAuth2TokenServiceFactory::GetForProfile(profile()));
173 }
174
175 MockAccountReconcilor* AccountReconcilorTest::GetMockReconcilor() {
176   if (!mock_reconcilor_) {
177     mock_reconcilor_ =
178         static_cast<MockAccountReconcilor*>(
179             AccountReconcilorFactory::GetForProfile(profile()));
180   }
181
182   return mock_reconcilor_;
183 }
184
185 void AccountReconcilorTest::SimulateMergeSessionCompleted(
186     MergeSessionHelper::Observer* observer,
187     const std::string& account_id,
188     const GoogleServiceAuthError& error) {
189   observer->MergeSessionCompleted(account_id, error);
190 }
191
192 TEST_F(AccountReconcilorTest, Basic) {
193   AccountReconcilor* reconcilor =
194       AccountReconcilorFactory::GetForProfile(profile());
195   ASSERT_TRUE(reconcilor);
196   ASSERT_EQ(token_service(), reconcilor->token_service());
197 }
198
199 #if !defined(OS_CHROMEOS)
200
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());
210
211   signin_manager()->set_password("password");
212   signin_manager()->OnExternalSigninCompleted(kTestEmail);
213   ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
214
215   EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
216
217   signin_manager()->SignOut(signin_metrics::SIGNOUT_TEST);
218   ASSERT_FALSE(reconcilor->IsRegisteredWithTokenService());
219 }
220
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");
228
229   AccountReconcilor* reconcilor =
230       AccountReconcilorFactory::GetForProfile(profile());
231   ASSERT_TRUE(reconcilor);
232   ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
233
234   // Simulate reauth.  The state of the reconcilor should not change.
235   signin_manager()->OnExternalSigninCompleted(kTestEmail);
236   ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
237 }
238
239 #endif  // !defined(OS_CHROMEOS)
240
241 TEST_F(AccountReconcilorTest, ProfileAlreadyConnected) {
242   signin_manager()->SetAuthenticatedUsername(kTestEmail);
243
244   AccountReconcilor* reconcilor =
245       AccountReconcilorFactory::GetForProfile(profile());
246   ASSERT_TRUE(reconcilor);
247   ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
248 }
249
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);
257
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);
261
262   reconcilor->StartReconcile();
263   ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
264
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);
271 }
272
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);
279
280   SetFakeResponse(list_accounts_url().spec(), "",
281       net::HTTP_NOT_FOUND, net::URLRequestStatus::SUCCESS);
282
283   reconcilor->StartReconcile();
284   ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
285
286   base::RunLoop().RunUntilIdle();
287   ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
288 }
289
290 TEST_P(AccountReconcilorTest, StartReconcileNoop) {
291   signin_manager()->SetAuthenticatedUsername(kTestEmail);
292   token_service()->UpdateCredentials(kTestEmail, "refresh_token");
293
294   AccountReconcilor* reconcilor =
295       AccountReconcilorFactory::GetForProfile(profile());
296   ASSERT_TRUE(reconcilor);
297
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);
301
302   reconcilor->StartReconcile();
303   ASSERT_TRUE(reconcilor->is_reconcile_started_);
304   ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
305
306   base::RunLoop().RunUntilIdle();
307   ASSERT_FALSE(reconcilor->is_reconcile_started_);
308
309   histogram_tester()->ExpectTotalCount(
310       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun", 1);
311   histogram_tester()->ExpectUniqueSample(
312       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
313       signin_metrics::ACCOUNTS_SAME,
314       1);
315 }
316
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");
328
329   AccountReconcilor* reconcilor =
330       AccountReconcilorFactory::GetForProfile(profile());
331   ASSERT_TRUE(reconcilor);
332
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);
336
337   reconcilor->StartReconcile();
338   ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
339
340   base::RunLoop().RunUntilIdle();
341   ASSERT_FALSE(reconcilor->is_reconcile_started_);
342
343   histogram_tester()->ExpectUniqueSample(
344       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
345       signin_metrics::ACCOUNTS_SAME,
346       1);
347 }
348
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");
353
354   AccountReconcilor* reconcilor =
355       AccountReconcilorFactory::GetForProfile(profile());
356   ASSERT_TRUE(reconcilor);
357
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);
362
363   reconcilor->StartReconcile();
364   ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
365   base::RunLoop().RunUntilIdle();
366   ASSERT_FALSE(reconcilor->is_reconcile_started_);
367
368   histogram_tester()->ExpectTotalCount(
369       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun", 1);
370   histogram_tester()->ExpectUniqueSample(
371       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
372       signin_metrics::ACCOUNTS_SAME,
373       1);
374 }
375
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");
380
381   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("other@gmail.com"));
382
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);
386
387   AccountReconcilor* reconcilor = GetMockReconcilor();
388   reconcilor->StartReconcile();
389
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_);
395
396   histogram_tester()->ExpectUniqueSample(
397       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
398       signin_metrics::ACCOUNTS_SAME,
399       1);
400   histogram_tester()->ExpectUniqueSample(
401       "Signin.Reconciler.AddedToCookieJar.FirstRun", 1, 1);
402   histogram_tester()->ExpectUniqueSample(
403       "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 0, 1);
404 }
405
406 TEST_P(AccountReconcilorTest, StartReconcileRemoveFromCookie) {
407   signin_manager()->SetAuthenticatedUsername("user@gmail.com");
408   token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
409
410   EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
411   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("user@gmail.com"));
412
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);
417
418   AccountReconcilor* reconcilor = GetMockReconcilor();
419   reconcilor->StartReconcile();
420   ASSERT_TRUE(reconcilor->is_reconcile_started_);
421
422   base::RunLoop().RunUntilIdle();
423   SimulateMergeSessionCompleted(reconcilor, "user@gmail.com",
424                                 GoogleServiceAuthError::AuthErrorNone());
425   ASSERT_FALSE(reconcilor->is_reconcile_started_);
426
427   histogram_tester()->ExpectUniqueSample(
428       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
429       signin_metrics::ACCOUNTS_SAME,
430       1);
431   histogram_tester()->ExpectUniqueSample(
432       "Signin.Reconciler.AddedToCookieJar.FirstRun", 0, 1);
433   histogram_tester()->ExpectUniqueSample(
434       "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 1, 1);
435 }
436
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");
441
442   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("other@gmail.com"));
443   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("third@gmail.com"));
444
445   SetFakeResponse(
446       list_accounts_url().spec(),
447       "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
448       net::HTTP_OK,
449       net::URLRequestStatus::SUCCESS);
450
451   AccountReconcilor* reconcilor = GetMockReconcilor();
452   reconcilor->StartReconcile();
453
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_);
459
460   histogram_tester()->ExpectUniqueSample(
461       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
462       signin_metrics::ACCOUNTS_SAME,
463       1);
464   histogram_tester()->ExpectUniqueSample(
465       "Signin.Reconciler.AddedToCookieJar.FirstRun", 1, 1);
466   histogram_tester()->ExpectUniqueSample(
467       "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 0, 1);
468
469   // Do another pass after I've added a third account to the token service
470
471   SetFakeResponse(
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]]]",
475       net::HTTP_OK,
476       net::URLRequestStatus::SUCCESS);
477   // This will cause the reconcilor to fire.
478   token_service()->UpdateCredentials("third@gmail.com", "refresh_token");
479
480   base::RunLoop().RunUntilIdle();
481
482   ASSERT_TRUE(reconcilor->is_reconcile_started_);
483   SimulateMergeSessionCompleted(
484       reconcilor, "third@gmail.com", GoogleServiceAuthError::AuthErrorNone());
485   ASSERT_FALSE(reconcilor->is_reconcile_started_);
486
487   histogram_tester()->ExpectUniqueSample(
488       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
489       signin_metrics::ACCOUNTS_SAME,
490       1);
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,
498       1);
499   histogram_tester()->ExpectUniqueSample(
500       "Signin.Reconciler.AddedToCookieJar.SubsequentRun", 1, 1);
501   histogram_tester()->ExpectUniqueSample(
502       "Signin.Reconciler.RemovedFromCookieJar.SubsequentRun", 0, 1);
503 }
504
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");
509
510   EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
511   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("user@gmail.com"));
512   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("other@gmail.com"));
513
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);
518
519   AccountReconcilor* reconcilor = GetMockReconcilor();
520   reconcilor->StartReconcile();
521
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_);
530
531   histogram_tester()->ExpectUniqueSample(
532       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
533       signin_metrics::COOKIE_AND_TOKEN_PRIMARIES_DIFFERENT,
534       1);
535   histogram_tester()->ExpectUniqueSample(
536       "Signin.Reconciler.AddedToCookieJar.FirstRun", 0, 1);
537   histogram_tester()->ExpectUniqueSample(
538       "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 0, 1);
539 }
540
541 TEST_P(AccountReconcilorTest, StartReconcileOnlyOnce) {
542   signin_manager()->SetAuthenticatedUsername(kTestEmail);
543   token_service()->UpdateCredentials(kTestEmail, "refresh_token");
544
545   AccountReconcilor* reconcilor =
546       AccountReconcilorFactory::GetForProfile(profile());
547   ASSERT_TRUE(reconcilor);
548
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);
552
553   ASSERT_FALSE(reconcilor->is_reconcile_started_);
554   reconcilor->StartReconcile();
555   ASSERT_TRUE(reconcilor->is_reconcile_started_);
556
557   base::RunLoop().RunUntilIdle();
558   ASSERT_FALSE(reconcilor->is_reconcile_started_);
559 }
560
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");
565
566   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("user@gmail.com"));
567
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);
572
573   AccountReconcilor* reconcilor =
574       AccountReconcilorFactory::GetForProfile(profile());
575   ASSERT_TRUE(reconcilor);
576
577   ASSERT_FALSE(reconcilor->is_reconcile_started_);
578   reconcilor->StartReconcile();
579   ASSERT_TRUE(reconcilor->is_reconcile_started_);
580
581   base::RunLoop().RunUntilIdle();
582   SimulateMergeSessionCompleted(reconcilor, "user@gmail.com",
583                                 GoogleServiceAuthError::AuthErrorNone());
584   ASSERT_FALSE(reconcilor->is_reconcile_started_);
585 }
586
587 TEST_F(AccountReconcilorTest, MergeSessionCompletedWithBogusAccount) {
588   signin_manager()->SetAuthenticatedUsername("user@gmail.com");
589   token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
590
591   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("user@gmail.com"));
592
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);
596
597   AccountReconcilor* reconcilor =
598       AccountReconcilorFactory::GetForProfile(profile());
599   ASSERT_TRUE(reconcilor);
600
601   ASSERT_FALSE(reconcilor->is_reconcile_started_);
602   reconcilor->StartReconcile();
603   ASSERT_TRUE(reconcilor->is_reconcile_started_);
604
605   base::RunLoop().RunUntilIdle();
606
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_);
611
612   SimulateMergeSessionCompleted(reconcilor, "user@gmail.com",
613                                 GoogleServiceAuthError::AuthErrorNone());
614   ASSERT_FALSE(reconcilor->is_reconcile_started_);
615 }
616
617 INSTANTIATE_TEST_CASE_P(AccountReconcilorMaybeEnabled,
618                         AccountReconcilorTest,
619                         testing::Bool());