1// Copyright (c) 2012 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 "testing/gtest/include/gtest/gtest.h"
6
7#include "base/memory/scoped_ptr.h"
8#include "base/message_loop/message_loop.h"
9#include "base/prefs/pref_service.h"
10#include "base/run_loop.h"
11#include "chrome/browser/chrome_notification_types.h"
12#include "chrome/browser/signin/fake_signin_manager.h"
13#include "chrome/browser/signin/oauth2_token_service.h"
14#include "chrome/browser/signin/profile_oauth2_token_service.h"
15#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
16#include "chrome/browser/signin/signin_manager.h"
17#include "chrome/browser/signin/signin_manager_factory.h"
18#include "chrome/browser/signin/token_service.h"
19#include "chrome/browser/signin/token_service_factory.h"
20#include "chrome/browser/sync/glue/data_type_manager.h"
21#include "chrome/browser/sync/glue/data_type_manager_mock.h"
22#include "chrome/browser/sync/profile_sync_components_factory_mock.h"
23#include "chrome/browser/sync/profile_sync_service_factory.h"
24#include "chrome/browser/sync/profile_sync_test_util.h"
25#include "chrome/browser/sync/sync_prefs.h"
26#include "chrome/browser/sync/test_profile_sync_service.h"
27#include "chrome/common/pref_names.h"
28#include "chrome/test/base/testing_profile.h"
29#include "content/public/browser/notification_service.h"
30#include "content/public/browser/notification_source.h"
31#include "content/public/test/test_browser_thread_bundle.h"
32#include "content/public/test/test_utils.h"
33#include "google_apis/gaia/gaia_auth_consumer.h"
34#include "google_apis/gaia/gaia_constants.h"
35#include "testing/gmock/include/gmock/gmock.h"
36
37using browser_sync::DataTypeManager;
38using browser_sync::DataTypeManagerMock;
39using content::BrowserThread;
40using testing::_;
41using testing::AnyNumber;
42using testing::DoAll;
43using testing::InvokeArgument;
44using testing::Mock;
45using testing::Return;
46
47ACTION_P(InvokeOnConfigureStart, pss) {
48  TestProfileSyncService* service = static_cast<TestProfileSyncService*>(pss);
49  service->OnConfigureStart();
50}
51
52ACTION_P2(InvokeOnConfigureDone, pss, result) {
53  TestProfileSyncService* service = static_cast<TestProfileSyncService*>(pss);
54  DataTypeManager::ConfigureResult configure_result =
55      static_cast<DataTypeManager::ConfigureResult>(result);
56  service->OnConfigureDone(configure_result);
57}
58
59class FakeTokenService : public TokenService {
60 public:
61  FakeTokenService() {}
62  virtual ~FakeTokenService() {}
63
64  virtual void LoadTokensFromDB() OVERRIDE {
65    set_tokens_loaded(true);
66    content::NotificationService::current()->Notify(
67        chrome::NOTIFICATION_TOKEN_LOADING_FINISHED,
68        content::Source<TokenService>(this),
69        content::NotificationService::NoDetails());
70  }
71};
72
73class ProfileSyncServiceStartupTest : public testing::Test {
74 public:
75  ProfileSyncServiceStartupTest()
76      : thread_bundle_(content::TestBrowserThreadBundle::REAL_DB_THREAD |
77                       content::TestBrowserThreadBundle::REAL_FILE_THREAD |
78                       content::TestBrowserThreadBundle::REAL_IO_THREAD),
79        profile_(new TestingProfile),
80        sync_(NULL) {}
81
82  virtual ~ProfileSyncServiceStartupTest() {
83  }
84
85  virtual void SetUp() {
86#if defined(OS_CHROMEOS)
87    SigninManagerFactory::GetInstance()->SetTestingFactory(
88        profile_.get(), FakeSigninManagerBase::Build);
89#else
90    SigninManagerFactory::GetInstance()->SetTestingFactory(
91        profile_.get(), FakeSigninManager::Build);
92#endif
93  }
94
95  virtual void TearDown() {
96    sync_->RemoveObserver(&observer_);
97    ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(
98        profile_.get(), NULL);
99    ProfileOAuth2TokenServiceFactory::GetInstance()->SetTestingFactory(
100        profile_.get(), NULL);
101    profile_.reset();
102
103    // Pump messages posted by the sync core thread (which may end up
104    // posting on the IO thread).
105    base::RunLoop().RunUntilIdle();
106    content::RunAllPendingInMessageLoop(content::BrowserThread::IO);
107    base::RunLoop().RunUntilIdle();
108  }
109
110  static BrowserContextKeyedService* BuildService(
111      content::BrowserContext* profile) {
112    return new TestProfileSyncService(
113        new ProfileSyncComponentsFactoryMock(),
114        static_cast<Profile*>(profile),
115        SigninManagerFactory::GetForProfile(static_cast<Profile*>(profile)),
116        ProfileSyncService::MANUAL_START,
117        true);
118  }
119
120  void CreateSyncService() {
121    ProfileOAuth2TokenServiceFactory::GetInstance()->SetTestingFactory(
122        profile_.get(), FakeOAuth2TokenService::BuildTokenService);
123    sync_ = static_cast<TestProfileSyncService*>(
124        ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
125            profile_.get(), BuildService));
126    sync_->AddObserver(&observer_);
127    sync_->set_synchronous_sync_configuration();
128  }
129
130 protected:
131  DataTypeManagerMock* SetUpDataTypeManager() {
132    DataTypeManagerMock* data_type_manager = new DataTypeManagerMock();
133    EXPECT_CALL(*sync_->components_factory_mock(),
134                CreateDataTypeManager(_, _, _, _, _, _)).
135        WillOnce(Return(data_type_manager));
136    return data_type_manager;
137  }
138
139  content::TestBrowserThreadBundle thread_bundle_;
140  scoped_ptr<TestingProfile> profile_;
141  TestProfileSyncService* sync_;
142  ProfileSyncServiceObserverMock observer_;
143};
144
145class ProfileSyncServiceStartupCrosTest : public ProfileSyncServiceStartupTest {
146 public:
147  virtual void SetUp() {
148    ProfileSyncServiceStartupTest::SetUp();
149    ProfileOAuth2TokenServiceFactory::GetInstance()->SetTestingFactory(
150        profile_.get(), FakeOAuth2TokenService::BuildTokenService);
151    sync_ = static_cast<TestProfileSyncService*>(
152        ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
153            profile_.get(), BuildCrosService));
154    sync_->AddObserver(&observer_);
155    sync_->set_synchronous_sync_configuration();
156  }
157
158  static BrowserContextKeyedService* BuildCrosService(
159      content::BrowserContext* context) {
160    Profile* profile = static_cast<Profile*>(context);
161    SigninManagerBase* signin =
162        SigninManagerFactory::GetForProfile(profile);
163    profile->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
164                                   "test_user@gmail.com");
165    signin->Initialize(profile, NULL);
166    EXPECT_FALSE(signin->GetAuthenticatedUsername().empty());
167    return new TestProfileSyncService(
168        new ProfileSyncComponentsFactoryMock(),
169        profile,
170        signin,
171        ProfileSyncService::AUTO_START,
172        true);
173  }
174};
175
176BrowserContextKeyedService* BuildFakeTokenService(
177    content::BrowserContext* profile) {
178  return new FakeTokenService();
179}
180
181TEST_F(ProfileSyncServiceStartupTest, StartFirstTime) {
182  // We've never completed startup.
183  profile_->GetPrefs()->ClearPref(prefs::kSyncHasSetupCompleted);
184  SigninManagerFactory::GetForProfile(
185      profile_.get())->Initialize(profile_.get(), NULL);
186  CreateSyncService();
187  DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
188  EXPECT_CALL(*data_type_manager, Configure(_, _)).Times(0);
189
190  // Should not actually start, rather just clean things up and wait
191  // to be enabled.
192  EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
193  sync_->Initialize();
194
195  // Preferences should be back to defaults.
196  EXPECT_EQ(0, profile_->GetPrefs()->GetInt64(prefs::kSyncLastSyncedTime));
197  EXPECT_FALSE(profile_->GetPrefs()->GetBoolean(prefs::kSyncHasSetupCompleted));
198  Mock::VerifyAndClearExpectations(data_type_manager);
199
200  // Then start things up.
201  EXPECT_CALL(*data_type_manager, Configure(_, _)).Times(1);
202  EXPECT_CALL(*data_type_manager, state()).
203      WillOnce(Return(DataTypeManager::CONFIGURED)).
204      WillOnce(Return(DataTypeManager::CONFIGURED));
205  EXPECT_CALL(*data_type_manager, Stop()).Times(1);
206  EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
207
208  sync_->SetSetupInProgress(true);
209
210  // Simulate successful signin as test_user.
211  profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
212                                  "test_user@gmail.com");
213  sync_->signin()->SetAuthenticatedUsername("test_user@gmail.com");
214  GoogleServiceSigninSuccessDetails details("test_user@gmail.com", "");
215  content::NotificationService::current()->Notify(
216      chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL,
217      content::Source<Profile>(profile_.get()),
218      content::Details<const GoogleServiceSigninSuccessDetails>(&details));
219
220  // Create some tokens in the token service.
221  TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
222      GaiaConstants::kGaiaOAuth2LoginRefreshToken, "oauth2_login_token");
223  TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
224      GaiaConstants::kSyncService, "token");
225
226  // Simulate the UI telling sync it has finished setting up.
227  sync_->SetSetupInProgress(false);
228  EXPECT_TRUE(sync_->ShouldPushChanges());
229}
230
231// TODO(pavely): Reenable test once android is switched to oauth2.
232TEST_F(ProfileSyncServiceStartupTest, DISABLED_StartNoCredentials) {
233  // We've never completed startup.
234  profile_->GetPrefs()->ClearPref(prefs::kSyncHasSetupCompleted);
235  SigninManagerFactory::GetForProfile(
236      profile_.get())->Initialize(profile_.get(), NULL);
237  TokenService* token_service = static_cast<TokenService*>(
238      TokenServiceFactory::GetInstance()->SetTestingFactoryAndUse(
239          profile_.get(), BuildFakeTokenService));
240  CreateSyncService();
241
242  // Should not actually start, rather just clean things up and wait
243  // to be enabled.
244  EXPECT_CALL(*sync_->components_factory_mock(),
245              CreateDataTypeManager(_, _, _, _, _, _)).Times(0);
246  EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
247  sync_->Initialize();
248  EXPECT_FALSE(sync_->GetBackendForTest());
249
250  // Preferences should be back to defaults.
251  EXPECT_EQ(0, profile_->GetPrefs()->GetInt64(prefs::kSyncLastSyncedTime));
252  EXPECT_FALSE(profile_->GetPrefs()->GetBoolean(prefs::kSyncHasSetupCompleted));
253
254  // Then start things up.
255  sync_->SetSetupInProgress(true);
256
257  // Simulate successful signin as test_user.
258  profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
259                                  "test_user@gmail.com");
260  sync_->signin()->SetAuthenticatedUsername("test_user@gmail.com");
261  GoogleServiceSigninSuccessDetails details("test_user@gmail.com", "");
262  content::NotificationService::current()->Notify(
263      chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL,
264      content::Source<Profile>(profile_.get()),
265      content::Details<const GoogleServiceSigninSuccessDetails>(&details));
266  // NOTE: Unlike StartFirstTime, this test does not issue any auth tokens.
267  token_service->LoadTokensFromDB();
268
269  sync_->SetSetupInProgress(false);
270  // ProfileSyncService should try to start by requesting access token.
271  // This request should fail as login token was not issued to TokenService.
272  EXPECT_FALSE(sync_->ShouldPushChanges());
273  EXPECT_EQ(GoogleServiceAuthError::USER_NOT_SIGNED_UP,
274      sync_->GetAuthError().state());
275}
276
277// TODO(pavely): Reenable test once android is switched to oauth2.
278TEST_F(ProfileSyncServiceStartupTest, DISABLED_StartInvalidCredentials) {
279  profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
280                                  "test_user@gmail.com");
281  SigninManagerFactory::GetForProfile(
282      profile_.get())->Initialize(profile_.get(), NULL);
283  CreateSyncService();
284  DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
285  EXPECT_CALL(*data_type_manager, Configure(_, _)).Times(0);
286  // Issue login token so that ProfileSyncServer tries to initialize backend.
287  TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
288      GaiaConstants::kGaiaOAuth2LoginRefreshToken, "oauth2_login_token");
289
290  // Tell the backend to stall while downloading control types (simulating an
291  // auth error).
292  sync_->fail_initial_download();
293
294  EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
295  sync_->Initialize();
296  EXPECT_TRUE(sync_->GetBackendForTest());
297  EXPECT_FALSE(sync_->sync_initialized());
298  Mock::VerifyAndClearExpectations(data_type_manager);
299
300  // Update the credentials, unstalling the backend.
301  EXPECT_CALL(*data_type_manager, Configure(_, _));
302  EXPECT_CALL(*data_type_manager, state()).
303      WillRepeatedly(Return(DataTypeManager::CONFIGURED));
304  EXPECT_CALL(*data_type_manager, Stop()).Times(1);
305  EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
306  sync_->SetSetupInProgress(true);
307
308  // Simulate successful signin.
309  GoogleServiceSigninSuccessDetails details("test_user@gmail.com",
310                                            std::string());
311  content::NotificationService::current()->Notify(
312        chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL,
313        content::Source<Profile>(profile_.get()),
314        content::Details<const GoogleServiceSigninSuccessDetails>(&details));
315
316  TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
317      GaiaConstants::kGaiaOAuth2LoginRefreshToken, "oauth2_login_token");
318  sync_->SetSetupInProgress(false);
319
320  // Verify we successfully finish startup and configuration.
321  EXPECT_TRUE(sync_->ShouldPushChanges());
322}
323
324TEST_F(ProfileSyncServiceStartupCrosTest, StartCrosNoCredentials) {
325  EXPECT_CALL(*sync_->components_factory_mock(),
326              CreateDataTypeManager(_, _, _, _, _, _)).Times(0);
327  profile_->GetPrefs()->ClearPref(prefs::kSyncHasSetupCompleted);
328  EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
329  TokenService* token_service = static_cast<TokenService*>(
330      TokenServiceFactory::GetInstance()->SetTestingFactoryAndUse(
331          profile_.get(), BuildFakeTokenService));
332
333  sync_->Initialize();
334  // Sync should not start because there are no tokens yet.
335  EXPECT_FALSE(sync_->ShouldPushChanges());
336  EXPECT_FALSE(sync_->GetBackendForTest());
337  token_service->LoadTokensFromDB();
338  sync_->SetSetupInProgress(false);
339
340  // Sync should not start because there are still no tokens.
341  EXPECT_FALSE(sync_->ShouldPushChanges());
342  EXPECT_FALSE(sync_->GetBackendForTest());
343}
344
345TEST_F(ProfileSyncServiceStartupCrosTest, StartFirstTime) {
346  DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
347  profile_->GetPrefs()->ClearPref(prefs::kSyncHasSetupCompleted);
348  EXPECT_CALL(*data_type_manager, Configure(_, _));
349  EXPECT_CALL(*data_type_manager, state()).
350      WillRepeatedly(Return(DataTypeManager::CONFIGURED));
351  EXPECT_CALL(*data_type_manager, Stop()).Times(1);
352  EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
353
354  TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
355      GaiaConstants::kGaiaOAuth2LoginRefreshToken, "oauth2_login_token");
356  TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
357      GaiaConstants::kSyncService, "sync_token");
358  sync_->Initialize();
359  EXPECT_TRUE(sync_->ShouldPushChanges());
360}
361
362TEST_F(ProfileSyncServiceStartupTest, StartNormal) {
363  // Pre load the tokens
364  profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
365                                  "test_user@gmail.com");
366  SigninManagerFactory::GetForProfile(profile_.get())->Initialize(
367      profile_.get(), NULL);
368  CreateSyncService();
369  DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
370  EXPECT_CALL(*data_type_manager, Configure(_, _));
371  EXPECT_CALL(*data_type_manager, state()).
372      WillRepeatedly(Return(DataTypeManager::CONFIGURED));
373  EXPECT_CALL(*data_type_manager, Stop()).Times(1);
374  EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
375
376  TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
377      GaiaConstants::kGaiaOAuth2LoginRefreshToken, "oauth2_login_token");
378  TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
379      GaiaConstants::kSyncService, "sync_token");
380
381  sync_->Initialize();
382}
383
384// Test that we can recover from a case where a bug in the code resulted in
385// OnUserChoseDatatypes not being properly called and datatype preferences
386// therefore being left unset.
387TEST_F(ProfileSyncServiceStartupTest, StartRecoverDatatypePrefs) {
388  // Clear the datatype preference fields (simulating bug 154940).
389  profile_->GetPrefs()->ClearPref(prefs::kSyncKeepEverythingSynced);
390  syncer::ModelTypeSet user_types = syncer::UserTypes();
391  for (syncer::ModelTypeSet::Iterator iter = user_types.First();
392       iter.Good(); iter.Inc()) {
393    profile_->GetPrefs()->ClearPref(
394        browser_sync::SyncPrefs::GetPrefNameForDataType(iter.Get()));
395  }
396
397  // Pre load the tokens
398  profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
399                                  "test_user@gmail.com");
400  SigninManagerFactory::GetForProfile(profile_.get())->Initialize(
401      profile_.get(), NULL);
402  CreateSyncService();
403  DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
404  EXPECT_CALL(*data_type_manager, Configure(_, _));
405  EXPECT_CALL(*data_type_manager, state()).
406      WillRepeatedly(Return(DataTypeManager::CONFIGURED));
407  EXPECT_CALL(*data_type_manager, Stop()).Times(1);
408  EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
409
410  TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
411      GaiaConstants::kGaiaOAuth2LoginRefreshToken, "oauth2_login_token");
412  TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
413      GaiaConstants::kSyncService, "sync_token");
414  sync_->Initialize();
415
416  EXPECT_TRUE(profile_->GetPrefs()->GetBoolean(
417      prefs::kSyncKeepEverythingSynced));
418}
419
420// Verify that the recovery of datatype preferences doesn't overwrite a valid
421// case where only bookmarks are enabled.
422TEST_F(ProfileSyncServiceStartupTest, StartDontRecoverDatatypePrefs) {
423  // Explicitly set Keep Everything Synced to false and have only bookmarks
424  // enabled.
425  profile_->GetPrefs()->SetBoolean(prefs::kSyncKeepEverythingSynced, false);
426
427  // Pre load the tokens
428  profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
429                                  "test_user@gmail.com");
430  SigninManagerFactory::GetForProfile(profile_.get())->Initialize(
431      profile_.get(), NULL);
432  CreateSyncService();
433  DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
434  EXPECT_CALL(*data_type_manager, Configure(_, _));
435  EXPECT_CALL(*data_type_manager, state()).
436      WillRepeatedly(Return(DataTypeManager::CONFIGURED));
437  EXPECT_CALL(*data_type_manager, Stop()).Times(1);
438  EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
439  TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
440      GaiaConstants::kGaiaOAuth2LoginRefreshToken, "oauth2_login_token");
441  TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
442      GaiaConstants::kSyncService, "sync_token");
443  sync_->Initialize();
444
445  EXPECT_FALSE(profile_->GetPrefs()->GetBoolean(
446      prefs::kSyncKeepEverythingSynced));
447}
448
449TEST_F(ProfileSyncServiceStartupTest, ManagedStartup) {
450  // Service should not be started by Initialize() since it's managed.
451  profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
452                                  "test_user@gmail.com");
453  SigninManagerFactory::GetForProfile(profile_.get())->Initialize(
454      profile_.get(), NULL);
455  CreateSyncService();
456
457  // Disable sync through policy.
458  profile_->GetPrefs()->SetBoolean(prefs::kSyncManaged, true);
459  EXPECT_CALL(*sync_->components_factory_mock(),
460              CreateDataTypeManager(_, _, _, _, _, _)).Times(0);
461  EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
462
463  TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
464      GaiaConstants::kGaiaOAuth2LoginRefreshToken, "oauth2_login_token");
465  sync_->Initialize();
466}
467
468TEST_F(ProfileSyncServiceStartupTest, SwitchManaged) {
469  profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
470                                  "test_user@gmail.com");
471  SigninManagerFactory::GetForProfile(profile_.get())->Initialize(
472      profile_.get(), NULL);
473  CreateSyncService();
474  DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
475  EXPECT_CALL(*data_type_manager, Configure(_, _));
476  EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
477  TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
478      GaiaConstants::kGaiaOAuth2LoginRefreshToken, "oauth2_login_token");
479  TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
480      GaiaConstants::kSyncService, "token");
481  sync_->Initialize();
482
483  // The service should stop when switching to managed mode.
484  Mock::VerifyAndClearExpectations(data_type_manager);
485  EXPECT_CALL(*data_type_manager, state()).
486      WillOnce(Return(DataTypeManager::CONFIGURED));
487  EXPECT_CALL(*data_type_manager, Stop()).Times(1);
488  EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
489  profile_->GetPrefs()->SetBoolean(prefs::kSyncManaged, true);
490
491  // When switching back to unmanaged, the state should change, but the service
492  // should not start up automatically (kSyncSetupCompleted will be false).
493  Mock::VerifyAndClearExpectations(data_type_manager);
494  EXPECT_CALL(*sync_->components_factory_mock(),
495              CreateDataTypeManager(_, _, _, _, _, _)).Times(0);
496  EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
497  profile_->GetPrefs()->ClearPref(prefs::kSyncManaged);
498}
499
500TEST_F(ProfileSyncServiceStartupTest, StartFailure) {
501  profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
502                                  "test_user@gmail.com");
503  SigninManagerFactory::GetForProfile(profile_.get())->Initialize(
504      profile_.get(), NULL);
505  CreateSyncService();
506  DataTypeManagerMock* data_type_manager = SetUpDataTypeManager();
507  DataTypeManager::ConfigureStatus status = DataTypeManager::ABORTED;
508  syncer::SyncError error(
509      FROM_HERE,
510      syncer::SyncError::DATATYPE_ERROR,
511      "Association failed.",
512      syncer::BOOKMARKS);
513  std::map<syncer::ModelType, syncer::SyncError> errors;
514  errors[syncer::BOOKMARKS] = error;
515  DataTypeManager::ConfigureResult result(
516      status,
517      syncer::ModelTypeSet(),
518      errors,
519      syncer::ModelTypeSet(),
520      syncer::ModelTypeSet());
521  EXPECT_CALL(*data_type_manager, Configure(_, _)).
522      WillRepeatedly(
523          DoAll(InvokeOnConfigureStart(sync_),
524                InvokeOnConfigureDone(sync_, result)));
525  EXPECT_CALL(*data_type_manager, state()).
526      WillOnce(Return(DataTypeManager::STOPPED));
527  EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
528  TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
529      GaiaConstants::kGaiaOAuth2LoginRefreshToken, "oauth2_login_token");
530  TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
531      GaiaConstants::kSyncService, "token");
532  sync_->Initialize();
533  EXPECT_TRUE(sync_->HasUnrecoverableError());
534}
535
536TEST_F(ProfileSyncServiceStartupTest, StartDownloadFailed) {
537  // Pre load the tokens
538  profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
539                                  "test_user@gmail.com");
540  SigninManagerFactory::GetForProfile(profile_.get())->Initialize(
541      profile_.get(), NULL);
542  CreateSyncService();
543
544  profile_->GetPrefs()->ClearPref(prefs::kSyncHasSetupCompleted);
545
546  EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber());
547  TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
548      GaiaConstants::kGaiaOAuth2LoginRefreshToken, "oauth2_login_token");
549  TokenServiceFactory::GetForProfile(profile_.get())->IssueAuthTokenForTest(
550      GaiaConstants::kSyncService, "token");
551  sync_->fail_initial_download();
552
553  sync_->SetSetupInProgress(true);
554  sync_->Initialize();
555  sync_->SetSetupInProgress(false);
556  EXPECT_FALSE(sync_->sync_initialized());
557  EXPECT_TRUE(sync_->GetBackendForTest());
558}
559