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