Upstream version 10.39.225.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_urls.h"
32 #include "net/url_request/test_url_fetcher_factory.h"
33 #include "testing/gmock/include/gmock/gmock.h"
34 #include "testing/gtest/include/gtest/gtest.h"
35
36 namespace {
37
38 const char kTestEmail[] = "user@gmail.com";
39
40 class MockAccountReconcilor : public testing::StrictMock<AccountReconcilor> {
41  public:
42   static KeyedService* Build(content::BrowserContext* context);
43
44   MockAccountReconcilor(ProfileOAuth2TokenService* token_service,
45                         SigninManagerBase* signin_manager,
46                         SigninClient* client);
47   virtual ~MockAccountReconcilor() {}
48
49   virtual void StartFetchingExternalCcResult() OVERRIDE {
50     // Don't do this in tests.
51   }
52
53   MOCK_METHOD1(PerformMergeAction, void(const std::string& account_id));
54   MOCK_METHOD0(PerformLogoutAllAccountsAction, void());
55 };
56
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   reconcilor->Initialize(false /* start_reconcile_if_tokens_available */);
65   return reconcilor;
66 }
67
68 MockAccountReconcilor::MockAccountReconcilor(
69     ProfileOAuth2TokenService* token_service,
70     SigninManagerBase* signin_manager,
71     SigninClient* client)
72     : testing::StrictMock<AccountReconcilor>(token_service,
73                                              signin_manager,
74                                              client) {}
75
76 }  // namespace
77
78 class AccountReconcilorTest : public ::testing::TestWithParam<bool> {
79  public:
80   AccountReconcilorTest();
81   virtual void SetUp() OVERRIDE;
82
83   TestingProfile* profile() { return profile_; }
84   FakeSigninManagerForTesting* signin_manager() { return signin_manager_; }
85   FakeProfileOAuth2TokenService* token_service() { return token_service_; }
86   base::HistogramTester* histogram_tester() { return &histogram_tester_; }
87
88   void SetFakeResponse(const std::string& url,
89                        const std::string& data,
90                        net::HttpStatusCode code,
91                        net::URLRequestStatus::Status status) {
92     url_fetcher_factory_.SetFakeResponse(GURL(url), data, code, status);
93   }
94
95   MockAccountReconcilor* GetMockReconcilor();
96
97   void SimulateMergeSessionCompleted(
98       MergeSessionHelper::Observer* observer,
99       const std::string& account_id,
100       const GoogleServiceAuthError& error);
101
102  private:
103   content::TestBrowserThreadBundle bundle_;
104   TestingProfile* profile_;
105   FakeSigninManagerForTesting* signin_manager_;
106   FakeProfileOAuth2TokenService* token_service_;
107   MockAccountReconcilor* mock_reconcilor_;
108   net::FakeURLFetcherFactory url_fetcher_factory_;
109   scoped_ptr<TestingProfileManager> testing_profile_manager_;
110   base::HistogramTester histogram_tester_;
111
112   DISALLOW_COPY_AND_ASSIGN(AccountReconcilorTest);
113 };
114
115 AccountReconcilorTest::AccountReconcilorTest()
116     : signin_manager_(NULL),
117       token_service_(NULL),
118       mock_reconcilor_(NULL),
119       url_fetcher_factory_(NULL) {}
120
121 void AccountReconcilorTest::SetUp() {
122   // If it's a non-parameterized test, or we have a parameter of true, set flag.
123   if (!::testing::UnitTest::GetInstance()->current_test_info()->value_param() ||
124       GetParam()) {
125     CommandLine::ForCurrentProcess()->AppendSwitch(
126         switches::kEnableNewProfileManagement);
127   }
128
129   testing_profile_manager_.reset(
130       new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
131   ASSERT_TRUE(testing_profile_manager_.get()->SetUp());
132
133   TestingProfile::TestingFactories factories;
134   factories.push_back(std::make_pair(ChromeSigninClientFactory::GetInstance(),
135       signin::BuildTestSigninClient));
136   factories.push_back(std::make_pair(
137       ProfileOAuth2TokenServiceFactory::GetInstance(),
138       BuildFakeProfileOAuth2TokenService));
139   factories.push_back(std::make_pair(SigninManagerFactory::GetInstance(),
140       FakeSigninManagerBase::Build));
141   factories.push_back(std::make_pair(AccountReconcilorFactory::GetInstance(),
142       MockAccountReconcilor::Build));
143
144   profile_ = testing_profile_manager_.get()->CreateTestingProfile("name",
145                               scoped_ptr<PrefServiceSyncable>(),
146                               base::UTF8ToUTF16("name"), 0, std::string(),
147                               factories);
148
149   signin_manager_ =
150       static_cast<FakeSigninManagerForTesting*>(
151           SigninManagerFactory::GetForProfile(profile()));
152
153   token_service_ =
154       static_cast<FakeProfileOAuth2TokenService*>(
155           ProfileOAuth2TokenServiceFactory::GetForProfile(profile()));
156 }
157
158 MockAccountReconcilor* AccountReconcilorTest::GetMockReconcilor() {
159   if (!mock_reconcilor_) {
160     mock_reconcilor_ =
161         static_cast<MockAccountReconcilor*>(
162             AccountReconcilorFactory::GetForProfile(profile()));
163   }
164
165   return mock_reconcilor_;
166 }
167
168 void AccountReconcilorTest::SimulateMergeSessionCompleted(
169     MergeSessionHelper::Observer* observer,
170     const std::string& account_id,
171     const GoogleServiceAuthError& error) {
172   observer->MergeSessionCompleted(account_id, error);
173 }
174
175 TEST_F(AccountReconcilorTest, Basic) {
176   AccountReconcilor* reconcilor =
177       AccountReconcilorFactory::GetForProfile(profile());
178   ASSERT_TRUE(reconcilor);
179   ASSERT_EQ(token_service(), reconcilor->token_service());
180 }
181
182 #if !defined(OS_CHROMEOS)
183
184 // This method requires the use of the |TestSigninClient| to be created from the
185 // |ChromeSigninClientFactory| because it overrides the |GoogleSigninSucceeded|
186 // method with an empty implementation. On MacOS, the normal implementation
187 // causes the try_bots to time out.
188 TEST_F(AccountReconcilorTest, SigninManagerRegistration) {
189   AccountReconcilor* reconcilor =
190       AccountReconcilorFactory::GetForProfile(profile());
191   ASSERT_TRUE(reconcilor);
192   ASSERT_FALSE(reconcilor->IsRegisteredWithTokenService());
193
194   signin_manager()->set_password("password");
195   signin_manager()->OnExternalSigninCompleted(kTestEmail);
196   ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
197
198   EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
199
200   signin_manager()->SignOut(signin_metrics::SIGNOUT_TEST);
201   ASSERT_FALSE(reconcilor->IsRegisteredWithTokenService());
202 }
203
204 // This method requires the use of the |TestSigninClient| to be created from the
205 // |ChromeSigninClientFactory| because it overrides the |GoogleSigninSucceeded|
206 // method with an empty implementation. On MacOS, the normal implementation
207 // causes the try_bots to time out.
208 TEST_F(AccountReconcilorTest, Reauth) {
209   signin_manager()->SetAuthenticatedUsername(kTestEmail);
210   signin_manager()->set_password("password");
211
212   AccountReconcilor* reconcilor =
213       AccountReconcilorFactory::GetForProfile(profile());
214   ASSERT_TRUE(reconcilor);
215   ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
216
217   // Simulate reauth.  The state of the reconcilor should not change.
218   signin_manager()->OnExternalSigninCompleted(kTestEmail);
219   ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
220 }
221
222 #endif  // !defined(OS_CHROMEOS)
223
224 TEST_F(AccountReconcilorTest, ProfileAlreadyConnected) {
225   signin_manager()->SetAuthenticatedUsername(kTestEmail);
226
227   AccountReconcilor* reconcilor =
228       AccountReconcilorFactory::GetForProfile(profile());
229   ASSERT_TRUE(reconcilor);
230   ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
231 }
232
233 TEST_F(AccountReconcilorTest, GetAccountsFromCookieSuccess) {
234   signin_manager()->SetAuthenticatedUsername(kTestEmail);
235   token_service()->UpdateCredentials(kTestEmail, "refresh_token");
236   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(kTestEmail));
237   AccountReconcilor* reconcilor =
238       AccountReconcilorFactory::GetForProfile(profile());
239   ASSERT_TRUE(reconcilor);
240
241   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
242       "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 0]]]",
243       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
244
245   reconcilor->StartReconcile();
246   ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
247
248   base::RunLoop().RunUntilIdle();
249   ASSERT_TRUE(reconcilor->AreGaiaAccountsSet());
250   const std::vector<std::pair<std::string, bool> >& accounts =
251       reconcilor->GetGaiaAccountsForTesting();
252   ASSERT_EQ(1u, accounts.size());
253   ASSERT_EQ("user@gmail.com", accounts[0].first);
254 }
255
256 TEST_F(AccountReconcilorTest, GetAccountsFromCookieFailure) {
257   signin_manager()->SetAuthenticatedUsername(kTestEmail);
258   token_service()->UpdateCredentials(kTestEmail, "refresh_token");
259   AccountReconcilor* reconcilor =
260       AccountReconcilorFactory::GetForProfile(profile());
261   ASSERT_TRUE(reconcilor);
262
263   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(), "",
264       net::HTTP_NOT_FOUND, net::URLRequestStatus::SUCCESS);
265
266   reconcilor->StartReconcile();
267   ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
268
269   base::RunLoop().RunUntilIdle();
270   ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
271 }
272
273 TEST_P(AccountReconcilorTest, StartReconcileNoop) {
274   signin_manager()->SetAuthenticatedUsername(kTestEmail);
275   token_service()->UpdateCredentials(kTestEmail, "refresh_token");
276
277   AccountReconcilor* reconcilor =
278       AccountReconcilorFactory::GetForProfile(profile());
279   ASSERT_TRUE(reconcilor);
280
281   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
282       "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
283       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
284
285   reconcilor->StartReconcile();
286   ASSERT_TRUE(reconcilor->is_reconcile_started_);
287   ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
288
289   base::RunLoop().RunUntilIdle();
290   ASSERT_FALSE(reconcilor->is_reconcile_started_);
291
292   histogram_tester()->ExpectTotalCount(
293       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun", 1);
294   histogram_tester()->ExpectUniqueSample(
295       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
296       signin_metrics::ACCOUNTS_SAME,
297       1);
298 }
299
300 // This is test is needed until chrome changes to use gaia obfuscated id.
301 // The signin manager and token service use the gaia "email" property, which
302 // preserves dots in usernames and preserves case. gaia::ParseListAccountsData()
303 // however uses gaia "displayEmail" which does not preserve case, and then
304 // passes the string through gaia::CanonicalizeEmail() which removes dots.  This
305 // tests makes sure that an email like "Dot.S@hmail.com", as seen by the
306 // token service, will be considered the same as "dots@gmail.com" as returned
307 // by gaia::ParseListAccountsData().
308 TEST_P(AccountReconcilorTest, StartReconcileNoopWithDots) {
309   signin_manager()->SetAuthenticatedUsername("Dot.S@gmail.com");
310   token_service()->UpdateCredentials("Dot.S@gmail.com", "refresh_token");
311
312   AccountReconcilor* reconcilor =
313       AccountReconcilorFactory::GetForProfile(profile());
314   ASSERT_TRUE(reconcilor);
315
316   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
317       "[\"f\", [[\"b\", 0, \"n\", \"dot.s@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
318       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
319
320   reconcilor->StartReconcile();
321   ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
322
323   base::RunLoop().RunUntilIdle();
324   ASSERT_FALSE(reconcilor->is_reconcile_started_);
325
326   histogram_tester()->ExpectUniqueSample(
327       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
328       signin_metrics::ACCOUNTS_SAME,
329       1);
330 }
331
332 TEST_P(AccountReconcilorTest, StartReconcileNoopMultiple) {
333   signin_manager()->SetAuthenticatedUsername("user@gmail.com");
334   token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
335   token_service()->UpdateCredentials("other@gmail.com", "refresh_token");
336
337   AccountReconcilor* reconcilor =
338       AccountReconcilorFactory::GetForProfile(profile());
339   ASSERT_TRUE(reconcilor);
340
341   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
342       "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1], "
343                "[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
344       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
345
346   reconcilor->StartReconcile();
347   ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
348   base::RunLoop().RunUntilIdle();
349   ASSERT_FALSE(reconcilor->is_reconcile_started_);
350
351   histogram_tester()->ExpectTotalCount(
352       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun", 1);
353   histogram_tester()->ExpectUniqueSample(
354       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
355       signin_metrics::ACCOUNTS_SAME,
356       1);
357 }
358
359 TEST_P(AccountReconcilorTest, StartReconcileAddToCookie) {
360   signin_manager()->SetAuthenticatedUsername("user@gmail.com");
361   token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
362   token_service()->UpdateCredentials("other@gmail.com", "refresh_token");
363
364   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("other@gmail.com"));
365
366   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
367       "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
368       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
369
370   AccountReconcilor* reconcilor = GetMockReconcilor();
371   reconcilor->StartReconcile();
372
373   base::RunLoop().RunUntilIdle();
374   ASSERT_TRUE(reconcilor->is_reconcile_started_);
375   SimulateMergeSessionCompleted(reconcilor, "other@gmail.com",
376                                 GoogleServiceAuthError::AuthErrorNone());
377   ASSERT_FALSE(reconcilor->is_reconcile_started_);
378
379   histogram_tester()->ExpectUniqueSample(
380       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
381       signin_metrics::ACCOUNTS_SAME,
382       1);
383   histogram_tester()->ExpectUniqueSample(
384       "Signin.Reconciler.AddedToCookieJar.FirstRun", 1, 1);
385   histogram_tester()->ExpectUniqueSample(
386       "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 0, 1);
387 }
388
389 TEST_P(AccountReconcilorTest, StartReconcileRemoveFromCookie) {
390   signin_manager()->SetAuthenticatedUsername("user@gmail.com");
391   token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
392
393   EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
394   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("user@gmail.com"));
395
396   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
397       "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1], "
398                "[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
399       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
400
401   AccountReconcilor* reconcilor = GetMockReconcilor();
402   reconcilor->StartReconcile();
403   ASSERT_TRUE(reconcilor->is_reconcile_started_);
404
405   base::RunLoop().RunUntilIdle();
406   SimulateMergeSessionCompleted(reconcilor, "user@gmail.com",
407                                 GoogleServiceAuthError::AuthErrorNone());
408   ASSERT_FALSE(reconcilor->is_reconcile_started_);
409
410   histogram_tester()->ExpectUniqueSample(
411       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
412       signin_metrics::ACCOUNTS_SAME,
413       1);
414   histogram_tester()->ExpectUniqueSample(
415       "Signin.Reconciler.AddedToCookieJar.FirstRun", 0, 1);
416   histogram_tester()->ExpectUniqueSample(
417       "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 1, 1);
418 }
419
420 TEST_P(AccountReconcilorTest, StartReconcileAddToCookieTwice) {
421   signin_manager()->SetAuthenticatedUsername("user@gmail.com");
422   token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
423   token_service()->UpdateCredentials("other@gmail.com", "refresh_token");
424
425   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("other@gmail.com"));
426   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("third@gmail.com"));
427
428   SetFakeResponse(
429       GaiaUrls::GetInstance()->list_accounts_url().spec(),
430       "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
431       net::HTTP_OK,
432       net::URLRequestStatus::SUCCESS);
433
434   AccountReconcilor* reconcilor = GetMockReconcilor();
435   reconcilor->StartReconcile();
436
437   base::RunLoop().RunUntilIdle();
438   ASSERT_TRUE(reconcilor->is_reconcile_started_);
439   SimulateMergeSessionCompleted(
440       reconcilor, "other@gmail.com", GoogleServiceAuthError::AuthErrorNone());
441   ASSERT_FALSE(reconcilor->is_reconcile_started_);
442
443   histogram_tester()->ExpectUniqueSample(
444       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
445       signin_metrics::ACCOUNTS_SAME,
446       1);
447   histogram_tester()->ExpectUniqueSample(
448       "Signin.Reconciler.AddedToCookieJar.FirstRun", 1, 1);
449   histogram_tester()->ExpectUniqueSample(
450       "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 0, 1);
451
452   // Do another pass after I've added a third account to the token service
453
454   SetFakeResponse(
455       GaiaUrls::GetInstance()->list_accounts_url().spec(),
456       "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1], "
457       "[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
458       net::HTTP_OK,
459       net::URLRequestStatus::SUCCESS);
460   // This will cause the reconcilor to fire.
461   token_service()->UpdateCredentials("third@gmail.com", "refresh_token");
462
463   base::RunLoop().RunUntilIdle();
464
465   ASSERT_TRUE(reconcilor->is_reconcile_started_);
466   SimulateMergeSessionCompleted(
467       reconcilor, "third@gmail.com", GoogleServiceAuthError::AuthErrorNone());
468   ASSERT_FALSE(reconcilor->is_reconcile_started_);
469
470   histogram_tester()->ExpectUniqueSample(
471       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
472       signin_metrics::ACCOUNTS_SAME,
473       1);
474   histogram_tester()->ExpectUniqueSample(
475       "Signin.Reconciler.AddedToCookieJar.FirstRun", 1, 1);
476   histogram_tester()->ExpectUniqueSample(
477       "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 0, 1);
478   histogram_tester()->ExpectUniqueSample(
479       "Signin.Reconciler.DifferentPrimaryAccounts.SubsequentRun",
480       signin_metrics::ACCOUNTS_SAME,
481       1);
482   histogram_tester()->ExpectUniqueSample(
483       "Signin.Reconciler.AddedToCookieJar.SubsequentRun", 1, 1);
484   histogram_tester()->ExpectUniqueSample(
485       "Signin.Reconciler.RemovedFromCookieJar.SubsequentRun", 0, 1);
486 }
487
488 TEST_P(AccountReconcilorTest, StartReconcileBadPrimary) {
489   signin_manager()->SetAuthenticatedUsername("user@gmail.com");
490   token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
491   token_service()->UpdateCredentials("other@gmail.com", "refresh_token");
492
493   EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
494   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("user@gmail.com"));
495   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("other@gmail.com"));
496
497   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
498       "[\"f\", [[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1], "
499                "[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
500       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
501
502   AccountReconcilor* reconcilor = GetMockReconcilor();
503   reconcilor->StartReconcile();
504
505   base::RunLoop().RunUntilIdle();
506   ASSERT_TRUE(reconcilor->is_reconcile_started_);
507   SimulateMergeSessionCompleted(reconcilor, "other@gmail.com",
508                                 GoogleServiceAuthError::AuthErrorNone());
509   ASSERT_TRUE(reconcilor->is_reconcile_started_);
510   SimulateMergeSessionCompleted(reconcilor, "user@gmail.com",
511                                 GoogleServiceAuthError::AuthErrorNone());
512   ASSERT_FALSE(reconcilor->is_reconcile_started_);
513
514   histogram_tester()->ExpectUniqueSample(
515       "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
516       signin_metrics::COOKIE_AND_TOKEN_PRIMARIES_DIFFERENT,
517       1);
518   histogram_tester()->ExpectUniqueSample(
519       "Signin.Reconciler.AddedToCookieJar.FirstRun", 0, 1);
520   histogram_tester()->ExpectUniqueSample(
521       "Signin.Reconciler.RemovedFromCookieJar.FirstRun", 0, 1);
522 }
523
524 TEST_P(AccountReconcilorTest, StartReconcileOnlyOnce) {
525   signin_manager()->SetAuthenticatedUsername(kTestEmail);
526   token_service()->UpdateCredentials(kTestEmail, "refresh_token");
527
528   AccountReconcilor* reconcilor =
529       AccountReconcilorFactory::GetForProfile(profile());
530   ASSERT_TRUE(reconcilor);
531
532   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
533       "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
534       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
535
536   ASSERT_FALSE(reconcilor->is_reconcile_started_);
537   reconcilor->StartReconcile();
538   ASSERT_TRUE(reconcilor->is_reconcile_started_);
539
540   base::RunLoop().RunUntilIdle();
541   ASSERT_FALSE(reconcilor->is_reconcile_started_);
542 }
543
544 TEST_P(AccountReconcilorTest, StartReconcileWithSessionInfoExpiredDefault) {
545   signin_manager()->SetAuthenticatedUsername("user@gmail.com");
546   token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
547   token_service()->UpdateCredentials("other@gmail.com", "refresh_token");
548
549   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("user@gmail.com"));
550
551   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
552       "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 0],"
553                "[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
554       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
555
556   AccountReconcilor* reconcilor =
557       AccountReconcilorFactory::GetForProfile(profile());
558   ASSERT_TRUE(reconcilor);
559
560   ASSERT_FALSE(reconcilor->is_reconcile_started_);
561   reconcilor->StartReconcile();
562   ASSERT_TRUE(reconcilor->is_reconcile_started_);
563
564   base::RunLoop().RunUntilIdle();
565   SimulateMergeSessionCompleted(reconcilor, "user@gmail.com",
566                                 GoogleServiceAuthError::AuthErrorNone());
567   ASSERT_FALSE(reconcilor->is_reconcile_started_);
568 }
569
570 TEST_F(AccountReconcilorTest, MergeSessionCompletedWithBogusAccount) {
571   signin_manager()->SetAuthenticatedUsername("user@gmail.com");
572   token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
573
574   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("user@gmail.com"));
575
576   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
577       "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 0]]]",
578       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
579
580   AccountReconcilor* reconcilor =
581       AccountReconcilorFactory::GetForProfile(profile());
582   ASSERT_TRUE(reconcilor);
583
584   ASSERT_FALSE(reconcilor->is_reconcile_started_);
585   reconcilor->StartReconcile();
586   ASSERT_TRUE(reconcilor->is_reconcile_started_);
587
588   base::RunLoop().RunUntilIdle();
589
590   // If an unknown account id is sent, it should not upset the state.
591   SimulateMergeSessionCompleted(reconcilor, "bogus@gmail.com",
592                                 GoogleServiceAuthError::AuthErrorNone());
593   ASSERT_TRUE(reconcilor->is_reconcile_started_);
594
595   SimulateMergeSessionCompleted(reconcilor, "user@gmail.com",
596                                 GoogleServiceAuthError::AuthErrorNone());
597   ASSERT_FALSE(reconcilor->is_reconcile_started_);
598 }
599
600 INSTANTIATE_TEST_CASE_P(AccountReconcilorMaybeEnabled,
601                         AccountReconcilorTest,
602                         testing::Bool());
603