• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "base/basictypes.h"
6 #include "base/command_line.h"
7 #include "base/compiler_specific.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/run_loop.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "chrome/browser/invalidation/fake_invalidation_service.h"
14 #include "chrome/browser/invalidation/profile_invalidation_provider_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/profile_oauth2_token_service_factory.h"
18 #include "chrome/browser/signin/signin_manager_factory.h"
19 #include "chrome/browser/sync/glue/sync_backend_host_mock.h"
20 #include "chrome/browser/sync/profile_sync_components_factory_mock.h"
21 #include "chrome/browser/sync/supervised_user_signin_manager_wrapper.h"
22 #include "chrome/common/chrome_switches.h"
23 #include "chrome/common/pref_names.h"
24 #include "chrome/grit/generated_resources.h"
25 #include "chrome/test/base/testing_browser_process.h"
26 #include "chrome/test/base/testing_pref_service_syncable.h"
27 #include "chrome/test/base/testing_profile.h"
28 #include "chrome/test/base/testing_profile_manager.h"
29 #include "components/invalidation/invalidation_service.h"
30 #include "components/invalidation/profile_invalidation_provider.h"
31 #include "components/signin/core/browser/signin_manager.h"
32 #include "components/sync_driver/data_type_manager.h"
33 #include "components/sync_driver/pref_names.h"
34 #include "components/sync_driver/sync_prefs.h"
35 #include "content/public/test/test_browser_thread_bundle.h"
36 #include "google_apis/gaia/gaia_constants.h"
37 #include "testing/gmock/include/gmock/gmock.h"
38 #include "testing/gtest/include/gtest/gtest.h"
39 #include "ui/base/l10n/l10n_util.h"
40 
41 namespace content {
42 class BrowserContext;
43 }
44 
45 namespace browser_sync {
46 
47 namespace {
48 
49 class FakeDataTypeManager : public sync_driver::DataTypeManager {
50  public:
FakeDataTypeManager(sync_driver::DataTypeManagerObserver * observer)51   explicit FakeDataTypeManager(sync_driver::DataTypeManagerObserver* observer)
52      : observer_(observer) {}
~FakeDataTypeManager()53   virtual ~FakeDataTypeManager() {};
54 
Configure(syncer::ModelTypeSet desired_types,syncer::ConfigureReason reason)55   virtual void Configure(syncer::ModelTypeSet desired_types,
56                          syncer::ConfigureReason reason) OVERRIDE {
57     sync_driver::DataTypeManager::ConfigureResult result;
58     result.status = sync_driver::DataTypeManager::OK;
59     observer_->OnConfigureDone(result);
60   }
61 
ReenableType(syncer::ModelType type)62   virtual void ReenableType(syncer::ModelType type) OVERRIDE {}
ResetDataTypeErrors()63   virtual void ResetDataTypeErrors() OVERRIDE {}
PurgeForMigration(syncer::ModelTypeSet undesired_types,syncer::ConfigureReason reason)64   virtual void PurgeForMigration(syncer::ModelTypeSet undesired_types,
65                                  syncer::ConfigureReason reason) OVERRIDE {}
Stop()66   virtual void Stop() OVERRIDE {};
state() const67   virtual State state() const OVERRIDE {
68     return sync_driver::DataTypeManager::CONFIGURED;
69   };
70 
71  private:
72   sync_driver::DataTypeManagerObserver* observer_;
73 };
74 
ACTION(ReturnNewDataTypeManager)75 ACTION(ReturnNewDataTypeManager) {
76   return new FakeDataTypeManager(arg4);
77 }
78 
79 using testing::Return;
80 using testing::StrictMock;
81 using testing::_;
82 
83 class TestProfileSyncServiceObserver : public ProfileSyncServiceObserver {
84  public:
TestProfileSyncServiceObserver(ProfileSyncService * service)85   explicit TestProfileSyncServiceObserver(ProfileSyncService* service)
86       : service_(service), first_setup_in_progress_(false) {}
OnStateChanged()87   virtual void OnStateChanged() OVERRIDE {
88     first_setup_in_progress_ = service_->FirstSetupInProgress();
89   }
first_setup_in_progress() const90   bool first_setup_in_progress() const { return first_setup_in_progress_; }
91  private:
92   ProfileSyncService* service_;
93   bool first_setup_in_progress_;
94 };
95 
96 // A variant of the SyncBackendHostMock that won't automatically
97 // call back when asked to initialized.  Allows us to test things
98 // that could happen while backend init is in progress.
99 class SyncBackendHostNoReturn : public SyncBackendHostMock {
Initialize(sync_driver::SyncFrontend * frontend,scoped_ptr<base::Thread> sync_thread,const syncer::WeakHandle<syncer::JsEventHandler> & event_handler,const GURL & service_url,const syncer::SyncCredentials & credentials,bool delete_sync_data_folder,scoped_ptr<syncer::SyncManagerFactory> sync_manager_factory,scoped_ptr<syncer::UnrecoverableErrorHandler> unrecoverable_error_handler,syncer::ReportUnrecoverableErrorFunction report_unrecoverable_error_function,syncer::NetworkResources * network_resources)100   virtual void Initialize(
101       sync_driver::SyncFrontend* frontend,
102       scoped_ptr<base::Thread> sync_thread,
103       const syncer::WeakHandle<syncer::JsEventHandler>& event_handler,
104       const GURL& service_url,
105       const syncer::SyncCredentials& credentials,
106       bool delete_sync_data_folder,
107       scoped_ptr<syncer::SyncManagerFactory> sync_manager_factory,
108       scoped_ptr<syncer::UnrecoverableErrorHandler> unrecoverable_error_handler,
109       syncer::ReportUnrecoverableErrorFunction
110           report_unrecoverable_error_function,
111       syncer::NetworkResources* network_resources) OVERRIDE {}
112 };
113 
114 class SyncBackendHostMockCollectDeleteDirParam : public SyncBackendHostMock {
115  public:
SyncBackendHostMockCollectDeleteDirParam(std::vector<bool> * delete_dir_param)116   explicit SyncBackendHostMockCollectDeleteDirParam(
117       std::vector<bool>* delete_dir_param)
118      : delete_dir_param_(delete_dir_param) {}
119 
Initialize(sync_driver::SyncFrontend * frontend,scoped_ptr<base::Thread> sync_thread,const syncer::WeakHandle<syncer::JsEventHandler> & event_handler,const GURL & service_url,const syncer::SyncCredentials & credentials,bool delete_sync_data_folder,scoped_ptr<syncer::SyncManagerFactory> sync_manager_factory,scoped_ptr<syncer::UnrecoverableErrorHandler> unrecoverable_error_handler,syncer::ReportUnrecoverableErrorFunction report_unrecoverable_error_function,syncer::NetworkResources * network_resources)120   virtual void Initialize(
121       sync_driver::SyncFrontend* frontend,
122       scoped_ptr<base::Thread> sync_thread,
123       const syncer::WeakHandle<syncer::JsEventHandler>& event_handler,
124       const GURL& service_url,
125       const syncer::SyncCredentials& credentials,
126       bool delete_sync_data_folder,
127       scoped_ptr<syncer::SyncManagerFactory> sync_manager_factory,
128       scoped_ptr<syncer::UnrecoverableErrorHandler> unrecoverable_error_handler,
129       syncer::ReportUnrecoverableErrorFunction
130           report_unrecoverable_error_function,
131       syncer::NetworkResources* network_resources) OVERRIDE {
132     delete_dir_param_->push_back(delete_sync_data_folder);
133     SyncBackendHostMock::Initialize(frontend, sync_thread.Pass(),
134                                     event_handler, service_url, credentials,
135                                     delete_sync_data_folder,
136                                     sync_manager_factory.Pass(),
137                                     unrecoverable_error_handler.Pass(),
138                                     report_unrecoverable_error_function,
139                                     network_resources);
140   }
141 
142  private:
143   std::vector<bool>* delete_dir_param_;
144 };
145 
ACTION(ReturnNewSyncBackendHostMock)146 ACTION(ReturnNewSyncBackendHostMock) {
147   return new browser_sync::SyncBackendHostMock();
148 }
149 
ACTION(ReturnNewSyncBackendHostNoReturn)150 ACTION(ReturnNewSyncBackendHostNoReturn) {
151   return new browser_sync::SyncBackendHostNoReturn();
152 }
153 
ACTION_P(ReturnNewMockHostCollectDeleteDirParam,delete_dir_param)154 ACTION_P(ReturnNewMockHostCollectDeleteDirParam, delete_dir_param) {
155   return new browser_sync::SyncBackendHostMockCollectDeleteDirParam(
156       delete_dir_param);
157 }
158 
BuildFakeProfileInvalidationProvider(content::BrowserContext * context)159 KeyedService* BuildFakeProfileInvalidationProvider(
160     content::BrowserContext* context) {
161   return new invalidation::ProfileInvalidationProvider(
162       scoped_ptr<invalidation::InvalidationService>(
163           new invalidation::FakeInvalidationService));
164 }
165 
166 // A test harness that uses a real ProfileSyncService and in most cases a
167 // MockSyncBackendHost.
168 //
169 // This is useful if we want to test the ProfileSyncService and don't care about
170 // testing the SyncBackendHost.
171 class ProfileSyncServiceTest : public ::testing::Test {
172  protected:
ProfileSyncServiceTest()173   ProfileSyncServiceTest()
174       : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
175         profile_manager_(TestingBrowserProcess::GetGlobal()) {}
~ProfileSyncServiceTest()176   virtual ~ProfileSyncServiceTest() {}
177 
SetUp()178   virtual void SetUp() OVERRIDE {
179     CommandLine::ForCurrentProcess()->AppendSwitchASCII(
180         switches::kSyncDeferredStartupTimeoutSeconds, "0");
181 
182     CHECK(profile_manager_.SetUp());
183 
184     TestingProfile::TestingFactories testing_facotries;
185     testing_facotries.push_back(
186             std::make_pair(ProfileOAuth2TokenServiceFactory::GetInstance(),
187                            BuildAutoIssuingFakeProfileOAuth2TokenService));
188     testing_facotries.push_back(
189             std::make_pair(
190                 invalidation::ProfileInvalidationProviderFactory::GetInstance(),
191                 BuildFakeProfileInvalidationProvider));
192 
193     profile_ = profile_manager_.CreateTestingProfile(
194         "sync-service-test", scoped_ptr<PrefServiceSyncable>(),
195         base::UTF8ToUTF16("sync-service-test"), 0, std::string(),
196         testing_facotries);
197   }
198 
TearDown()199   virtual void TearDown() OVERRIDE {
200     // Kill the service before the profile.
201     if (service_)
202       service_->Shutdown();
203 
204     service_.reset();
205   }
206 
IssueTestTokens()207   void IssueTestTokens() {
208     ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)
209         ->UpdateCredentials("test", "oauth2_login_token");
210   }
211 
CreateService(ProfileSyncServiceStartBehavior behavior)212   void CreateService(ProfileSyncServiceStartBehavior behavior) {
213     SigninManagerBase* signin =
214         SigninManagerFactory::GetForProfile(profile_);
215     signin->SetAuthenticatedUsername("test");
216     ProfileOAuth2TokenService* oauth2_token_service =
217         ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
218     components_factory_ = new ProfileSyncComponentsFactoryMock();
219     service_.reset(new ProfileSyncService(
220         scoped_ptr<ProfileSyncComponentsFactory>(components_factory_),
221         profile_,
222         make_scoped_ptr(new SupervisedUserSigninManagerWrapper(profile_,
223                                                                signin)),
224         oauth2_token_service,
225         behavior));
226     service_->SetClearingBrowseringDataForTesting(
227         base::Bind(&ProfileSyncServiceTest::ClearBrowsingDataCallback,
228                    base::Unretained(this)));
229   }
230 
231 #if defined(OS_WIN) || defined(OS_MACOSX) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
CreateServiceWithoutSignIn()232   void CreateServiceWithoutSignIn() {
233     CreateService(browser_sync::AUTO_START);
234     SigninManagerFactory::GetForProfile(profile())->SignOut(
235         signin_metrics::SIGNOUT_TEST);
236   }
237 #endif
238 
ShutdownAndDeleteService()239   void ShutdownAndDeleteService() {
240     if (service_)
241       service_->Shutdown();
242     service_.reset();
243   }
244 
InitializeForNthSync()245   void InitializeForNthSync() {
246     // Set first sync time before initialize to disable backup.
247     sync_driver::SyncPrefs sync_prefs(service()->profile()->GetPrefs());
248     sync_prefs.SetFirstSyncTime(base::Time::Now());
249     service_->Initialize();
250   }
251 
InitializeForFirstSync()252   void InitializeForFirstSync() {
253     service_->Initialize();
254   }
255 
ExpectDataTypeManagerCreation(int times)256   void ExpectDataTypeManagerCreation(int times) {
257     EXPECT_CALL(*components_factory_, CreateDataTypeManager(_, _, _, _, _))
258         .Times(times)
259         .WillRepeatedly(ReturnNewDataTypeManager());
260   }
261 
ExpectSyncBackendHostCreation(int times)262   void ExpectSyncBackendHostCreation(int times) {
263     EXPECT_CALL(*components_factory_, CreateSyncBackendHost(_, _, _, _, _))
264         .Times(times)
265         .WillRepeatedly(ReturnNewSyncBackendHostMock());
266   }
267 
ExpectSyncBackendHostCreationCollectDeleteDir(int times,std::vector<bool> * delete_dir_param)268   void ExpectSyncBackendHostCreationCollectDeleteDir(
269       int times, std::vector<bool> *delete_dir_param) {
270     EXPECT_CALL(*components_factory_, CreateSyncBackendHost(_, _, _, _, _))
271         .Times(times)
272         .WillRepeatedly(ReturnNewMockHostCollectDeleteDirParam(
273             delete_dir_param));
274   }
275 
PrepareDelayedInitSyncBackendHost()276   void PrepareDelayedInitSyncBackendHost() {
277     EXPECT_CALL(*components_factory_, CreateSyncBackendHost(_, _, _, _, _)).
278         WillOnce(ReturnNewSyncBackendHostNoReturn());
279   }
280 
profile()281   TestingProfile* profile() {
282     return profile_;
283   }
284 
service()285   ProfileSyncService* service() {
286     return service_.get();
287   }
288 
components_factory()289   ProfileSyncComponentsFactoryMock* components_factory() {
290     return components_factory_;
291   }
292 
ClearBrowsingDataCallback(BrowsingDataRemover::Observer * observer,Profile * profile,base::Time start,base::Time end)293   void ClearBrowsingDataCallback(BrowsingDataRemover::Observer* observer,
294                                  Profile* profile,
295                                  base::Time start,
296                                  base::Time end) {
297     EXPECT_EQ(profile_, profile);
298     clear_browsing_date_start_ = start;
299   }
300 
301  protected:
PumpLoop()302   void PumpLoop() {
303     base::RunLoop run_loop;
304     base::MessageLoop::current()->PostTask(
305         FROM_HERE, run_loop.QuitClosure());
306     run_loop.Run();
307   }
308 
309   // The requested start time when ClearBrowsingDataCallback is called.
310   base::Time clear_browsing_date_start_;
311 
312  private:
313   content::TestBrowserThreadBundle thread_bundle_;
314   TestingProfileManager profile_manager_;
315   TestingProfile* profile_;
316   scoped_ptr<ProfileSyncService> service_;
317 
318   // Pointer to the components factory.  Not owned.  May be null.
319   ProfileSyncComponentsFactoryMock* components_factory_;
320 };
321 
322 // Verify that the server URLs are sane.
TEST_F(ProfileSyncServiceTest,InitialState)323 TEST_F(ProfileSyncServiceTest, InitialState) {
324   CreateService(browser_sync::AUTO_START);
325   InitializeForNthSync();
326   const std::string& url = service()->sync_service_url().spec();
327   EXPECT_TRUE(url == ProfileSyncService::kSyncServerUrl ||
328               url == ProfileSyncService::kDevServerUrl);
329 }
330 
331 // Verify a successful initialization.
TEST_F(ProfileSyncServiceTest,SuccessfulInitialization)332 TEST_F(ProfileSyncServiceTest, SuccessfulInitialization) {
333   profile()->GetTestingPrefService()->SetManagedPref(
334       sync_driver::prefs::kSyncManaged, new base::FundamentalValue(false));
335   IssueTestTokens();
336   CreateService(browser_sync::AUTO_START);
337   ExpectDataTypeManagerCreation(1);
338   ExpectSyncBackendHostCreation(1);
339   InitializeForNthSync();
340   EXPECT_FALSE(service()->IsManaged());
341   EXPECT_TRUE(service()->sync_initialized());
342   EXPECT_EQ(ProfileSyncService::SYNC, service()->backend_mode());
343 }
344 
345 
346 // Verify that the SetSetupInProgress function call updates state
347 // and notifies observers.
TEST_F(ProfileSyncServiceTest,SetupInProgress)348 TEST_F(ProfileSyncServiceTest, SetupInProgress) {
349   CreateService(browser_sync::AUTO_START);
350   InitializeForNthSync();
351 
352   TestProfileSyncServiceObserver observer(service());
353   service()->AddObserver(&observer);
354 
355   service()->SetSetupInProgress(true);
356   EXPECT_TRUE(observer.first_setup_in_progress());
357   service()->SetSetupInProgress(false);
358   EXPECT_FALSE(observer.first_setup_in_progress());
359 
360   service()->RemoveObserver(&observer);
361 }
362 
363 // Verify that disable by enterprise policy works.
TEST_F(ProfileSyncServiceTest,DisabledByPolicyBeforeInit)364 TEST_F(ProfileSyncServiceTest, DisabledByPolicyBeforeInit) {
365   profile()->GetTestingPrefService()->SetManagedPref(
366       sync_driver::prefs::kSyncManaged, new base::FundamentalValue(true));
367   IssueTestTokens();
368   CreateService(browser_sync::AUTO_START);
369   InitializeForNthSync();
370   EXPECT_TRUE(service()->IsManaged());
371   EXPECT_FALSE(service()->sync_initialized());
372 }
373 
374 // Verify that disable by enterprise policy works even after the backend has
375 // been initialized.
TEST_F(ProfileSyncServiceTest,DisabledByPolicyAfterInit)376 TEST_F(ProfileSyncServiceTest, DisabledByPolicyAfterInit) {
377   IssueTestTokens();
378   CreateService(browser_sync::AUTO_START);
379   ExpectDataTypeManagerCreation(1);
380   ExpectSyncBackendHostCreation(1);
381   InitializeForNthSync();
382 
383   EXPECT_FALSE(service()->IsManaged());
384   EXPECT_TRUE(service()->sync_initialized());
385 
386   profile()->GetTestingPrefService()->SetManagedPref(
387       sync_driver::prefs::kSyncManaged, new base::FundamentalValue(true));
388 
389   EXPECT_TRUE(service()->IsManaged());
390   EXPECT_FALSE(service()->sync_initialized());
391 }
392 
393 // Exercies the ProfileSyncService's code paths related to getting shut down
394 // before the backend initialize call returns.
TEST_F(ProfileSyncServiceTest,AbortedByShutdown)395 TEST_F(ProfileSyncServiceTest, AbortedByShutdown) {
396   CreateService(browser_sync::AUTO_START);
397   PrepareDelayedInitSyncBackendHost();
398 
399   IssueTestTokens();
400   InitializeForNthSync();
401   EXPECT_FALSE(service()->sync_initialized());
402 
403   ShutdownAndDeleteService();
404 }
405 
406 // Test StopAndSuppress() before we've initialized the backend.
TEST_F(ProfileSyncServiceTest,EarlyStopAndSuppress)407 TEST_F(ProfileSyncServiceTest, EarlyStopAndSuppress) {
408   CreateService(browser_sync::AUTO_START);
409   IssueTestTokens();
410 
411   service()->StopAndSuppress();
412   EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(
413       sync_driver::prefs::kSyncSuppressStart));
414 
415   // Because of supression, this should fail.
416   InitializeForNthSync();
417   EXPECT_FALSE(service()->sync_initialized());
418 
419   // Remove suppression.  This should be enough to allow init to happen.
420   ExpectDataTypeManagerCreation(1);
421   ExpectSyncBackendHostCreation(1);
422   service()->UnsuppressAndStart();
423   EXPECT_TRUE(service()->sync_initialized());
424   EXPECT_FALSE(profile()->GetPrefs()->GetBoolean(
425       sync_driver::prefs::kSyncSuppressStart));
426 }
427 
428 // Test StopAndSuppress() after we've initialized the backend.
TEST_F(ProfileSyncServiceTest,DisableAndEnableSyncTemporarily)429 TEST_F(ProfileSyncServiceTest, DisableAndEnableSyncTemporarily) {
430   CreateService(browser_sync::AUTO_START);
431   IssueTestTokens();
432   ExpectDataTypeManagerCreation(1);
433   ExpectSyncBackendHostCreation(1);
434   InitializeForNthSync();
435 
436   EXPECT_TRUE(service()->sync_initialized());
437   EXPECT_FALSE(profile()->GetPrefs()->GetBoolean(
438       sync_driver::prefs::kSyncSuppressStart));
439 
440   testing::Mock::VerifyAndClearExpectations(components_factory());
441 
442   service()->StopAndSuppress();
443   EXPECT_FALSE(service()->sync_initialized());
444   EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(
445       sync_driver::prefs::kSyncSuppressStart));
446 
447   ExpectDataTypeManagerCreation(1);
448   ExpectSyncBackendHostCreation(1);
449 
450   service()->UnsuppressAndStart();
451   EXPECT_TRUE(service()->sync_initialized());
452   EXPECT_FALSE(profile()->GetPrefs()->GetBoolean(
453       sync_driver::prefs::kSyncSuppressStart));
454 }
455 
456 // Certain ProfileSyncService tests don't apply to Chrome OS, for example
457 // things that deal with concepts like "signing out" and policy.
458 #if !defined (OS_CHROMEOS)
TEST_F(ProfileSyncServiceTest,EnableSyncAndSignOut)459 TEST_F(ProfileSyncServiceTest, EnableSyncAndSignOut) {
460   CreateService(browser_sync::AUTO_START);
461   ExpectDataTypeManagerCreation(1);
462   ExpectSyncBackendHostCreation(1);
463   IssueTestTokens();
464   InitializeForNthSync();
465 
466   EXPECT_TRUE(service()->sync_initialized());
467   EXPECT_FALSE(profile()->GetPrefs()->GetBoolean(
468       sync_driver::prefs::kSyncSuppressStart));
469 
470   SigninManagerFactory::GetForProfile(profile())->SignOut(
471       signin_metrics::SIGNOUT_TEST);
472   EXPECT_FALSE(service()->sync_initialized());
473 }
474 #endif  // !defined(OS_CHROMEOS)
475 
TEST_F(ProfileSyncServiceTest,GetSyncTokenStatus)476 TEST_F(ProfileSyncServiceTest, GetSyncTokenStatus) {
477   CreateService(browser_sync::AUTO_START);
478   IssueTestTokens();
479   ExpectDataTypeManagerCreation(1);
480   ExpectSyncBackendHostCreation(1);
481   InitializeForNthSync();
482 
483   // Initial status.
484   ProfileSyncService::SyncTokenStatus token_status =
485       service()->GetSyncTokenStatus();
486   EXPECT_EQ(syncer::CONNECTION_NOT_ATTEMPTED, token_status.connection_status);
487   EXPECT_TRUE(token_status.connection_status_update_time.is_null());
488   EXPECT_TRUE(token_status.token_request_time.is_null());
489   EXPECT_TRUE(token_status.token_receive_time.is_null());
490 
491   // Simulate an auth error.
492   service()->OnConnectionStatusChange(syncer::CONNECTION_AUTH_ERROR);
493 
494   // The token request will take the form of a posted task.  Run it.
495   base::RunLoop loop;
496   loop.RunUntilIdle();
497 
498   token_status = service()->GetSyncTokenStatus();
499   EXPECT_EQ(syncer::CONNECTION_AUTH_ERROR, token_status.connection_status);
500   EXPECT_FALSE(token_status.connection_status_update_time.is_null());
501   EXPECT_FALSE(token_status.token_request_time.is_null());
502   EXPECT_FALSE(token_status.token_receive_time.is_null());
503   EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
504             token_status.last_get_token_error);
505   EXPECT_TRUE(token_status.next_token_request_time.is_null());
506 
507   // Simulate successful connection.
508   service()->OnConnectionStatusChange(syncer::CONNECTION_OK);
509   token_status = service()->GetSyncTokenStatus();
510   EXPECT_EQ(syncer::CONNECTION_OK, token_status.connection_status);
511 }
512 
513 #if defined(ENABLE_PRE_SYNC_BACKUP)
TEST_F(ProfileSyncServiceTest,DontStartBackupOnBrowserStart)514 TEST_F(ProfileSyncServiceTest, DontStartBackupOnBrowserStart) {
515   CreateServiceWithoutSignIn();
516   InitializeForFirstSync();
517   PumpLoop();
518   EXPECT_EQ(ProfileSyncService::IDLE, service()->backend_mode());
519 }
520 
TEST_F(ProfileSyncServiceTest,BackupBeforeFirstSync)521 TEST_F(ProfileSyncServiceTest, BackupBeforeFirstSync) {
522   CreateServiceWithoutSignIn();
523   ExpectDataTypeManagerCreation(2);
524   std::vector<bool> delete_dir_param;
525   ExpectSyncBackendHostCreationCollectDeleteDir(2, &delete_dir_param);
526   InitializeForFirstSync();
527 
528   SigninManagerFactory::GetForProfile(profile())
529       ->SetAuthenticatedUsername("test");
530   IssueTestTokens();
531   PumpLoop();
532 
533   // At this time, backup is finished. Task is posted to start sync again.
534   EXPECT_EQ(ProfileSyncService::BACKUP, service()->backend_mode());
535   EXPECT_TRUE(service()->ShouldPushChanges());
536   EXPECT_EQ(1u, delete_dir_param.size());
537   EXPECT_TRUE(delete_dir_param[0]);
538 
539   // Pump loop to start sync.
540   PumpLoop();
541   EXPECT_EQ(ProfileSyncService::SYNC, service()->backend_mode());
542   EXPECT_EQ(2u, delete_dir_param.size());
543   EXPECT_TRUE(delete_dir_param[0]);
544 }
545 
546 // Test backup is done again on browser start if user signed in last session
547 // but backup didn't finish when last session was closed.
TEST_F(ProfileSyncServiceTest,ResumeBackupIfAborted)548 TEST_F(ProfileSyncServiceTest, ResumeBackupIfAborted) {
549   IssueTestTokens();
550   CreateService(AUTO_START);
551   ExpectDataTypeManagerCreation(2);
552   std::vector<bool> delete_dir_param;
553   ExpectSyncBackendHostCreationCollectDeleteDir(2, &delete_dir_param);
554   InitializeForFirstSync();
555   PumpLoop();
556 
557   // At this time, backup is finished. Task is posted to start sync again.
558   EXPECT_EQ(ProfileSyncService::BACKUP, service()->backend_mode());
559   EXPECT_TRUE(service()->ShouldPushChanges());
560   EXPECT_EQ(1u, delete_dir_param.size());
561   EXPECT_TRUE(delete_dir_param[0]);
562 
563   // Pump loop to start sync.
564   PumpLoop();
565   EXPECT_EQ(ProfileSyncService::SYNC, service()->backend_mode());
566   EXPECT_EQ(2u, delete_dir_param.size());
567   EXPECT_TRUE(delete_dir_param[0]);
568 }
569 
TEST_F(ProfileSyncServiceTest,Rollback)570 TEST_F(ProfileSyncServiceTest, Rollback) {
571   CreateService(browser_sync::MANUAL_START);
572   service()->SetSyncSetupCompleted();
573   ExpectDataTypeManagerCreation(2);
574   std::vector<bool> delete_dir_param;
575   ExpectSyncBackendHostCreationCollectDeleteDir(2, &delete_dir_param);
576   IssueTestTokens();
577   InitializeForNthSync();
578   EXPECT_TRUE(service()->sync_initialized());
579   EXPECT_EQ(ProfileSyncService::SYNC, service()->backend_mode());
580 
581   // First sync time should be recorded.
582   sync_driver::SyncPrefs sync_prefs(service()->profile()->GetPrefs());
583   base::Time first_sync_time = sync_prefs.GetFirstSyncTime();
584   EXPECT_FALSE(first_sync_time.is_null());
585 
586   syncer::SyncProtocolError client_cmd;
587   client_cmd.action = syncer::DISABLE_SYNC_AND_ROLLBACK;
588   service()->OnActionableError(client_cmd);
589   EXPECT_EQ(ProfileSyncService::IDLE, service()->backend_mode());
590 
591   // Pump loop to run rollback.
592   PumpLoop();
593   EXPECT_EQ(ProfileSyncService::ROLLBACK, service()->backend_mode());
594 
595   // Browser data should be cleared during rollback.
596   EXPECT_EQ(first_sync_time, clear_browsing_date_start_);
597 
598   client_cmd.action = syncer::ROLLBACK_DONE;
599   service()->OnActionableError(client_cmd);
600   EXPECT_EQ(ProfileSyncService::IDLE, service()->backend_mode());
601 
602   // First sync time is erased after rollback is done.
603   EXPECT_TRUE(sync_prefs.GetFirstSyncTime().is_null());
604 
605   EXPECT_EQ(2u, delete_dir_param.size());
606   EXPECT_FALSE(delete_dir_param[0]);
607   EXPECT_FALSE(delete_dir_param[1]);
608 }
609 
610 #endif
611 
TEST_F(ProfileSyncServiceTest,GetSyncServiceURL)612 TEST_F(ProfileSyncServiceTest, GetSyncServiceURL) {
613   // See that we can override the URL with a flag.
614   CommandLine command_line(
615       base::FilePath(base::FilePath(FILE_PATH_LITERAL("chrome.exe"))));
616   command_line.AppendSwitchASCII(switches::kSyncServiceURL, "https://foo/bar");
617   EXPECT_EQ("https://foo/bar",
618             ProfileSyncService::GetSyncServiceURL(command_line).spec());
619 }
620 
621 // Verify that LastSyncedTime is cleared when the user signs out.
TEST_F(ProfileSyncServiceTest,ClearLastSyncedTimeOnSignOut)622 TEST_F(ProfileSyncServiceTest, ClearLastSyncedTimeOnSignOut) {
623   IssueTestTokens();
624   CreateService(AUTO_START);
625   ExpectDataTypeManagerCreation(1);
626   ExpectSyncBackendHostCreation(1);
627   InitializeForNthSync();
628   EXPECT_TRUE(service()->sync_initialized());
629   EXPECT_EQ(l10n_util::GetStringUTF16(IDS_SYNC_TIME_JUST_NOW),
630             service()->GetLastSyncedTimeString());
631 
632   // Sign out.
633   service()->DisableForUser();
634   PumpLoop();
635 
636   EXPECT_EQ(l10n_util::GetStringUTF16(IDS_SYNC_TIME_NEVER),
637             service()->GetLastSyncedTimeString());
638 }
639 
640 }  // namespace
641 }  // namespace browser_sync
642