Upstream version 7.36.149.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/memory/scoped_ptr.h"
6 #include "base/run_loop.h"
7 #include "base/time/time.h"
8 #include "chrome/browser/signin/account_reconcilor_factory.h"
9 #include "chrome/browser/signin/chrome_signin_client_factory.h"
10 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
11 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
12 #include "chrome/browser/signin/fake_signin_manager.h"
13 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
14 #include "chrome/browser/signin/signin_manager_factory.h"
15 #include "chrome/test/base/testing_profile.h"
16 #include "components/signin/core/browser/account_reconcilor.h"
17 #include "components/signin/core/browser/profile_oauth2_token_service.h"
18 #include "components/signin/core/browser/signin_manager.h"
19 #include "content/public/test/test_browser_thread_bundle.h"
20 #include "google_apis/gaia/gaia_urls.h"
21 #include "net/url_request/test_url_fetcher_factory.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24
25 namespace {
26
27 const char kTestEmail[] = "user@gmail.com";
28
29 class MockAccountReconcilor : public testing::StrictMock<AccountReconcilor> {
30  public:
31   static KeyedService* Build(content::BrowserContext* context);
32
33   MockAccountReconcilor(ProfileOAuth2TokenService* token_service,
34                         SigninManagerBase* signin_manager,
35                         SigninClient* client);
36   virtual ~MockAccountReconcilor() {}
37
38   MOCK_METHOD1(PerformMergeAction, void(const std::string& account_id));
39   MOCK_METHOD1(StartRemoveAction, void(const std::string& account_id));
40   MOCK_METHOD3(
41       FinishRemoveAction,
42       void(const std::string& account_id,
43            const GoogleServiceAuthError& error,
44            const std::vector<std::pair<std::string, bool> >& accounts));
45   MOCK_METHOD2(PerformAddToChromeAction, void(const std::string& account_id,
46                                               int session_index));
47   MOCK_METHOD0(PerformLogoutAllAccountsAction, void());
48 };
49
50 // static
51 KeyedService* MockAccountReconcilor::Build(content::BrowserContext* context) {
52   Profile* profile = Profile::FromBrowserContext(context);
53   AccountReconcilor* reconcilor = new MockAccountReconcilor(
54       ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
55       SigninManagerFactory::GetForProfile(profile),
56       ChromeSigninClientFactory::GetForProfile(profile));
57   reconcilor->Initialize(false /* start_reconcile_if_tokens_available */);
58   return reconcilor;
59 }
60
61 MockAccountReconcilor::MockAccountReconcilor(
62     ProfileOAuth2TokenService* token_service,
63     SigninManagerBase* signin_manager,
64     SigninClient* client)
65     : testing::StrictMock<AccountReconcilor>(token_service,
66                                              signin_manager,
67                                              client) {}
68
69 }  // namespace
70
71 class AccountReconcilorTest : public testing::Test {
72  public:
73   AccountReconcilorTest();
74   virtual void SetUp() OVERRIDE;
75   virtual void TearDown() OVERRIDE;
76
77   TestingProfile* profile() { return profile_.get(); }
78   FakeSigninManagerForTesting* signin_manager() { return signin_manager_; }
79   FakeProfileOAuth2TokenService* token_service() { return token_service_; }
80
81   void SetFakeResponse(const std::string& url,
82                        const std::string& data,
83                        net::HttpStatusCode code,
84                        net::URLRequestStatus::Status status) {
85     url_fetcher_factory_.SetFakeResponse(GURL(url), data, code, status);
86   }
87
88   MockAccountReconcilor* GetMockReconcilor();
89
90   void SimulateMergeSessionCompleted(
91       MergeSessionHelper::Observer* observer,
92       const std::string& account_id,
93       const GoogleServiceAuthError& error);
94
95   void SimulateRefreshTokenFetched(
96       AccountReconcilor* reconcilor,
97       const std::string& account_id,
98       const std::string& refresh_token);
99
100  private:
101   content::TestBrowserThreadBundle bundle_;
102   scoped_ptr<TestingProfile> profile_;
103   FakeSigninManagerForTesting* signin_manager_;
104   FakeProfileOAuth2TokenService* token_service_;
105   MockAccountReconcilor* mock_reconcilor_;
106   net::FakeURLFetcherFactory url_fetcher_factory_;
107 };
108
109 AccountReconcilorTest::AccountReconcilorTest()
110     : signin_manager_(NULL),
111       token_service_(NULL),
112       mock_reconcilor_(NULL),
113       url_fetcher_factory_(NULL) {}
114
115 void AccountReconcilorTest::SetUp() {
116   TestingProfile::Builder builder;
117   builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
118                             BuildFakeProfileOAuth2TokenService);
119   builder.AddTestingFactory(SigninManagerFactory::GetInstance(),
120                             FakeSigninManagerBase::Build);
121   builder.AddTestingFactory(AccountReconcilorFactory::GetInstance(),
122                             MockAccountReconcilor::Build);
123   profile_ = builder.Build();
124
125   signin_manager_ =
126       static_cast<FakeSigninManagerForTesting*>(
127           SigninManagerFactory::GetForProfile(profile()));
128
129   token_service_ =
130       static_cast<FakeProfileOAuth2TokenService*>(
131           ProfileOAuth2TokenServiceFactory::GetForProfile(profile()));
132 }
133
134 void AccountReconcilorTest::TearDown() {
135   // Destroy the profile before all threads are torn down.
136   profile_.reset();
137 }
138
139 MockAccountReconcilor* AccountReconcilorTest::GetMockReconcilor() {
140   if (!mock_reconcilor_) {
141     mock_reconcilor_ =
142         static_cast<MockAccountReconcilor*>(
143             AccountReconcilorFactory::GetForProfile(profile()));
144   }
145
146   return mock_reconcilor_;
147 }
148
149 void AccountReconcilorTest::SimulateMergeSessionCompleted(
150     MergeSessionHelper::Observer* observer,
151     const std::string& account_id,
152     const GoogleServiceAuthError& error) {
153   observer->MergeSessionCompleted(account_id, error);
154 }
155
156 void AccountReconcilorTest::SimulateRefreshTokenFetched(
157     AccountReconcilor* reconcilor,
158     const std::string& account_id,
159     const std::string& refresh_token) {
160   reconcilor->HandleRefreshTokenFetched(account_id, refresh_token);
161 }
162
163 TEST_F(AccountReconcilorTest, Basic) {
164   AccountReconcilor* reconcilor =
165       AccountReconcilorFactory::GetForProfile(profile());
166   ASSERT_TRUE(reconcilor);
167   ASSERT_EQ(token_service(), reconcilor->token_service());
168 }
169
170 #if !defined(OS_CHROMEOS)
171
172 TEST_F(AccountReconcilorTest, SigninManagerRegistration) {
173   AccountReconcilor* reconcilor =
174       AccountReconcilorFactory::GetForProfile(profile());
175   ASSERT_TRUE(reconcilor);
176   ASSERT_FALSE(reconcilor->IsRegisteredWithTokenService());
177
178   signin_manager()->OnExternalSigninCompleted(kTestEmail);
179   ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
180
181   signin_manager()->SignOut();
182   ASSERT_FALSE(reconcilor->IsRegisteredWithTokenService());
183 }
184
185 TEST_F(AccountReconcilorTest, Reauth) {
186   signin_manager()->SetAuthenticatedUsername(kTestEmail);
187
188   AccountReconcilor* reconcilor =
189       AccountReconcilorFactory::GetForProfile(profile());
190   ASSERT_TRUE(reconcilor);
191   ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
192
193   // Simulate reauth.  The state of the reconcilor should not change.
194   signin_manager()->OnExternalSigninCompleted(kTestEmail);
195   ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
196 }
197
198 #endif  // !defined(OS_CHROMEOS)
199
200 TEST_F(AccountReconcilorTest, ProfileAlreadyConnected) {
201   signin_manager()->SetAuthenticatedUsername(kTestEmail);
202
203   AccountReconcilor* reconcilor =
204       AccountReconcilorFactory::GetForProfile(profile());
205   ASSERT_TRUE(reconcilor);
206   ASSERT_TRUE(reconcilor->IsRegisteredWithTokenService());
207 }
208
209 TEST_F(AccountReconcilorTest, GetAccountsFromCookieSuccess) {
210   signin_manager()->SetAuthenticatedUsername(kTestEmail);
211   token_service()->UpdateCredentials(kTestEmail, "refresh_token");
212   AccountReconcilor* reconcilor =
213       AccountReconcilorFactory::GetForProfile(profile());
214   ASSERT_TRUE(reconcilor);
215
216   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
217       "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 0]]]",
218       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
219
220   reconcilor->StartReconcile();
221   ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
222
223   base::RunLoop().RunUntilIdle();
224   ASSERT_TRUE(reconcilor->AreGaiaAccountsSet());
225   const std::vector<std::pair<std::string, bool> >& accounts =
226       reconcilor->GetGaiaAccountsForTesting();
227   ASSERT_EQ(1u, accounts.size());
228   ASSERT_EQ("user@gmail.com", accounts[0].first);
229 }
230
231 TEST_F(AccountReconcilorTest, GetAccountsFromCookieFailure) {
232   signin_manager()->SetAuthenticatedUsername(kTestEmail);
233   token_service()->UpdateCredentials(kTestEmail, "refresh_token");
234   AccountReconcilor* reconcilor =
235       AccountReconcilorFactory::GetForProfile(profile());
236   ASSERT_TRUE(reconcilor);
237
238   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(), "",
239       net::HTTP_NOT_FOUND, net::URLRequestStatus::SUCCESS);
240
241   reconcilor->StartReconcile();
242   ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
243
244   base::RunLoop().RunUntilIdle();
245   ASSERT_EQ(0u, reconcilor->GetGaiaAccountsForTesting().size());
246 }
247
248 TEST_F(AccountReconcilorTest, ValidateAccountsFromTokens) {
249   signin_manager()->SetAuthenticatedUsername(kTestEmail);
250   token_service()->UpdateCredentials(kTestEmail, "refresh_token");
251
252   AccountReconcilor* reconcilor =
253       AccountReconcilorFactory::GetForProfile(profile());
254   ASSERT_TRUE(reconcilor);
255
256   reconcilor->ValidateAccountsFromTokenService();
257   ASSERT_FALSE(reconcilor->AreAllRefreshTokensChecked());
258
259   SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
260       "{\"id\":\"foo\"}", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
261   token_service()->IssueTokenForAllPendingRequests("access_token",
262       base::Time::Now() + base::TimeDelta::FromHours(1));
263
264   base::RunLoop().RunUntilIdle();
265   ASSERT_TRUE(reconcilor->AreAllRefreshTokensChecked());
266   ASSERT_EQ(1u, reconcilor->GetValidChromeAccountsForTesting().size());
267   ASSERT_EQ(0u, reconcilor->GetInvalidChromeAccountsForTesting().size());
268 }
269
270 TEST_F(AccountReconcilorTest, ValidateAccountsFromTokensFailedUserInfo) {
271   signin_manager()->SetAuthenticatedUsername(kTestEmail);
272   token_service()->UpdateCredentials(kTestEmail, "refresh_token");
273
274   AccountReconcilor* reconcilor =
275       AccountReconcilorFactory::GetForProfile(profile());
276   ASSERT_TRUE(reconcilor);
277
278   reconcilor->ValidateAccountsFromTokenService();
279   ASSERT_FALSE(reconcilor->AreAllRefreshTokensChecked());
280
281   SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
282       "", net::HTTP_NOT_FOUND, net::URLRequestStatus::SUCCESS);
283   token_service()->IssueTokenForAllPendingRequests("access_token",
284       base::Time::Now() + base::TimeDelta::FromHours(1));
285
286   base::RunLoop().RunUntilIdle();
287   ASSERT_TRUE(reconcilor->AreAllRefreshTokensChecked());
288   ASSERT_EQ(0u, reconcilor->GetValidChromeAccountsForTesting().size());
289   ASSERT_EQ(1u, reconcilor->GetInvalidChromeAccountsForTesting().size());
290 }
291
292 TEST_F(AccountReconcilorTest, ValidateAccountsFromTokensFailedTokenRequest) {
293   signin_manager()->SetAuthenticatedUsername(kTestEmail);
294   token_service()->UpdateCredentials(kTestEmail, "refresh_token");
295
296   AccountReconcilor* reconcilor =
297       AccountReconcilorFactory::GetForProfile(profile());
298   ASSERT_TRUE(reconcilor);
299
300   reconcilor->ValidateAccountsFromTokenService();
301   ASSERT_FALSE(reconcilor->AreAllRefreshTokensChecked());
302
303   token_service()->IssueErrorForAllPendingRequests(
304       GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
305
306   base::RunLoop().RunUntilIdle();
307   ASSERT_TRUE(reconcilor->AreAllRefreshTokensChecked());
308   ASSERT_EQ(0u, reconcilor->GetValidChromeAccountsForTesting().size());
309   ASSERT_EQ(1u, reconcilor->GetInvalidChromeAccountsForTesting().size());
310 }
311
312 TEST_F(AccountReconcilorTest, StartReconcileNoop) {
313   signin_manager()->SetAuthenticatedUsername(kTestEmail);
314   token_service()->UpdateCredentials(kTestEmail, "refresh_token");
315
316   AccountReconcilor* reconcilor =
317       AccountReconcilorFactory::GetForProfile(profile());
318   ASSERT_TRUE(reconcilor);
319
320   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
321       "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
322       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
323   SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
324       "{\"id\":\"foo\"}", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
325
326   reconcilor->StartReconcile();
327   ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
328   ASSERT_FALSE(reconcilor->AreAllRefreshTokensChecked());
329
330   base::RunLoop().RunUntilIdle();
331   ASSERT_TRUE(reconcilor->AreGaiaAccountsSet());
332   ASSERT_EQ(1u, reconcilor->GetGaiaAccountsForTesting().size());
333   ASSERT_FALSE(reconcilor->AreAllRefreshTokensChecked());
334
335   token_service()->IssueAllTokensForAccount("user@gmail.com", "access_token",
336       base::Time::Now() + base::TimeDelta::FromHours(1));
337
338   base::RunLoop().RunUntilIdle();
339   ASSERT_TRUE(reconcilor->AreAllRefreshTokensChecked());
340   ASSERT_FALSE(reconcilor->is_reconcile_started_);
341 }
342
343 // This is test is needed until chrome changes to use gaia obfuscated id.
344 // The signin manager and token service use the gaia "email" property, which
345 // preserves dots in usernames and preserves case. gaia::ParseListAccountsData()
346 // however uses gaia "displayEmail" which does not preserve case, and then
347 // passes the string through gaia::CanonicalizeEmail() which removes dots.  This
348 // tests makes sure that an email like "Dot.S@hmail.com", as seen by the
349 // token service, will be considered the same as "dots@gmail.com" as returned
350 // by gaia::ParseListAccountsData().
351 TEST_F(AccountReconcilorTest, StartReconcileNoopWithDots) {
352   signin_manager()->SetAuthenticatedUsername("Dot.S@gmail.com");
353   token_service()->UpdateCredentials("Dot.S@gmail.com", "refresh_token");
354
355   AccountReconcilor* reconcilor =
356       AccountReconcilorFactory::GetForProfile(profile());
357   ASSERT_TRUE(reconcilor);
358
359   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
360       "[\"f\", [[\"b\", 0, \"n\", \"dot.s@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
361       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
362   SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
363       "{\"id\":\"foo\"}", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
364
365   reconcilor->StartReconcile();
366   ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
367   ASSERT_FALSE(reconcilor->AreAllRefreshTokensChecked());
368
369   base::RunLoop().RunUntilIdle();
370   ASSERT_TRUE(reconcilor->AreGaiaAccountsSet());
371   ASSERT_EQ(1u, reconcilor->GetGaiaAccountsForTesting().size());
372   ASSERT_STREQ("dots@gmail.com",
373                reconcilor->GetGaiaAccountsForTesting()[0].first.c_str());
374   ASSERT_FALSE(reconcilor->AreAllRefreshTokensChecked());
375
376   token_service()->IssueAllTokensForAccount("Dot.S@gmail.com", "access_token",
377       base::Time::Now() + base::TimeDelta::FromHours(1));
378
379   base::RunLoop().RunUntilIdle();
380   ASSERT_TRUE(reconcilor->AreAllRefreshTokensChecked());
381   ASSERT_FALSE(reconcilor->is_reconcile_started_);
382 }
383
384 TEST_F(AccountReconcilorTest, StartReconcileNoopMultiple) {
385   signin_manager()->SetAuthenticatedUsername("user@gmail.com");
386   token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
387   token_service()->UpdateCredentials("other@gmail.com", "refresh_token");
388
389   AccountReconcilor* reconcilor =
390       AccountReconcilorFactory::GetForProfile(profile());
391   ASSERT_TRUE(reconcilor);
392
393   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
394       "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1], "
395                "[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
396       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
397   SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
398       "{\"id\":\"foo\"}", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
399
400   reconcilor->StartReconcile();
401   ASSERT_FALSE(reconcilor->AreGaiaAccountsSet());
402   ASSERT_FALSE(reconcilor->AreAllRefreshTokensChecked());
403
404   base::RunLoop().RunUntilIdle();
405   ASSERT_TRUE(reconcilor->AreGaiaAccountsSet());
406   ASSERT_FALSE(reconcilor->AreAllRefreshTokensChecked());
407   ASSERT_EQ(2u, reconcilor->GetGaiaAccountsForTesting().size());
408
409   token_service()->IssueAllTokensForAccount("other@gmail.com", "access_token",
410       base::Time::Now() + base::TimeDelta::FromHours(1));
411
412   base::RunLoop().RunUntilIdle();
413   ASSERT_FALSE(reconcilor->AreAllRefreshTokensChecked());
414
415   token_service()->IssueAllTokensForAccount("user@gmail.com", "access_token",
416       base::Time::Now() + base::TimeDelta::FromHours(1));
417
418   base::RunLoop().RunUntilIdle();
419   ASSERT_TRUE(reconcilor->AreAllRefreshTokensChecked());
420   ASSERT_FALSE(reconcilor->is_reconcile_started_);
421 }
422
423 TEST_F(AccountReconcilorTest, StartReconcileAddToCookie) {
424   signin_manager()->SetAuthenticatedUsername("user@gmail.com");
425   token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
426   token_service()->UpdateCredentials("other@gmail.com", "refresh_token");
427
428   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("other@gmail.com"));
429
430   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
431       "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
432       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
433   SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
434       "{\"id\":\"foo\"}", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
435
436   AccountReconcilor* reconcilor = GetMockReconcilor();
437   reconcilor->StartReconcile();
438   token_service()->IssueAllTokensForAccount("other@gmail.com", "access_token",
439       base::Time::Now() + base::TimeDelta::FromHours(1));
440   token_service()->IssueAllTokensForAccount("user@gmail.com", "access_token",
441       base::Time::Now() + base::TimeDelta::FromHours(1));
442
443   base::RunLoop().RunUntilIdle();
444   ASSERT_TRUE(reconcilor->is_reconcile_started_);
445   SimulateMergeSessionCompleted(reconcilor, "other@gmail.com",
446                                 GoogleServiceAuthError::AuthErrorNone());
447   ASSERT_FALSE(reconcilor->is_reconcile_started_);
448 }
449
450 TEST_F(AccountReconcilorTest, StartReconcileAddToChrome) {
451   signin_manager()->SetAuthenticatedUsername("user@gmail.com");
452   token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
453
454   EXPECT_CALL(*GetMockReconcilor(),
455               PerformAddToChromeAction("other@gmail.com", 1));
456
457   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
458       "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1], "
459                "[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
460       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
461   SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
462       "{\"id\":\"foo\"}", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
463
464   AccountReconcilor* reconcilor = GetMockReconcilor();
465   reconcilor->StartReconcile();
466   token_service()->IssueAllTokensForAccount("user@gmail.com", "access_token",
467       base::Time::Now() + base::TimeDelta::FromHours(1));
468
469   base::RunLoop().RunUntilIdle();
470   ASSERT_TRUE(reconcilor->is_reconcile_started_);
471   SimulateRefreshTokenFetched(reconcilor, "other@gmail.com", "");
472   ASSERT_FALSE(reconcilor->is_reconcile_started_);
473 }
474
475 TEST_F(AccountReconcilorTest, StartReconcileBadPrimary) {
476   signin_manager()->SetAuthenticatedUsername("user@gmail.com");
477   token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
478   token_service()->UpdateCredentials("other@gmail.com", "refresh_token");
479
480   EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
481   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("user@gmail.com"));
482   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("other@gmail.com"));
483
484   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
485       "[\"f\", [[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1], "
486                "[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
487       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
488   SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
489       "{\"id\":\"foo\"}", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
490
491   AccountReconcilor* reconcilor = GetMockReconcilor();
492   reconcilor->StartReconcile();
493   token_service()->IssueAllTokensForAccount("other@gmail.com", "access_token",
494       base::Time::Now() + base::TimeDelta::FromHours(1));
495   token_service()->IssueAllTokensForAccount("user@gmail.com", "access_token",
496       base::Time::Now() + base::TimeDelta::FromHours(1));
497
498   base::RunLoop().RunUntilIdle();
499   ASSERT_TRUE(reconcilor->is_reconcile_started_);
500   SimulateMergeSessionCompleted(reconcilor, "other@gmail.com",
501                                 GoogleServiceAuthError::AuthErrorNone());
502   ASSERT_TRUE(reconcilor->is_reconcile_started_);
503   SimulateMergeSessionCompleted(reconcilor, "user@gmail.com",
504                                 GoogleServiceAuthError::AuthErrorNone());
505   ASSERT_FALSE(reconcilor->is_reconcile_started_);
506 }
507
508 TEST_F(AccountReconcilorTest, StartReconcileOnlyOnce) {
509   signin_manager()->SetAuthenticatedUsername(kTestEmail);
510   token_service()->UpdateCredentials(kTestEmail, "refresh_token");
511
512   AccountReconcilor* reconcilor =
513       AccountReconcilorFactory::GetForProfile(profile());
514   ASSERT_TRUE(reconcilor);
515
516   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
517       "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
518       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
519   SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
520       "{\"id\":\"foo\"}", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
521
522   ASSERT_FALSE(reconcilor->is_reconcile_started_);
523   reconcilor->StartReconcile();
524   ASSERT_TRUE(reconcilor->is_reconcile_started_);
525
526   token_service()->IssueAllTokensForAccount("user@gmail.com", "access_token",
527       base::Time::Now() + base::TimeDelta::FromHours(1));
528
529   base::RunLoop().RunUntilIdle();
530   ASSERT_FALSE(reconcilor->is_reconcile_started_);
531 }
532
533 TEST_F(AccountReconcilorTest, StartReconcileWithSessionInfoExpiredDefault) {
534   signin_manager()->SetAuthenticatedUsername("user@gmail.com");
535   token_service()->UpdateCredentials("user@gmail.com", "refresh_token");
536   token_service()->UpdateCredentials("other@gmail.com", "refresh_token");
537
538   EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction("user@gmail.com"));
539
540   SetFakeResponse(GaiaUrls::GetInstance()->list_accounts_url().spec(),
541       "[\"f\", [[\"b\", 0, \"n\", \"user@gmail.com\", \"p\", 0, 0, 0, 0, 0],"
542                "[\"b\", 0, \"n\", \"other@gmail.com\", \"p\", 0, 0, 0, 0, 1]]]",
543       net::HTTP_OK, net::URLRequestStatus::SUCCESS);
544   SetFakeResponse(GaiaUrls::GetInstance()->people_get_url().spec(),
545       "{\"id\":\"foo\"}", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
546
547   AccountReconcilor* reconcilor =
548       AccountReconcilorFactory::GetForProfile(profile());
549   ASSERT_TRUE(reconcilor);
550
551   ASSERT_FALSE(reconcilor->is_reconcile_started_);
552   reconcilor->StartReconcile();
553   ASSERT_TRUE(reconcilor->is_reconcile_started_);
554
555   token_service()->IssueAllTokensForAccount("user@gmail.com", "access_token",
556       base::Time::Now() + base::TimeDelta::FromHours(1));
557   token_service()->IssueAllTokensForAccount("other@gmail.com", "access_token",
558       base::Time::Now() + base::TimeDelta::FromHours(1));
559
560   base::RunLoop().RunUntilIdle();
561   SimulateMergeSessionCompleted(reconcilor, "user@gmail.com",
562                                 GoogleServiceAuthError::AuthErrorNone());
563   ASSERT_FALSE(reconcilor->is_reconcile_started_);
564 }