// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/sync/glue/sync_backend_host.h" #include <cstddef> #include "base/message_loop.h" #include "base/scoped_ptr.h" #include "chrome/browser/sync/engine/model_safe_worker.h" #include "chrome/browser/sync/engine/syncapi.h" #include "chrome/browser/sync/glue/data_type_controller.h" #include "chrome/browser/sync/syncable/model_type.h" #include "chrome/test/testing_profile.h" #include "content/browser/browser_thread.h" #include "googleurl/src/gurl.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" // TODO(akalin): Remove this once we fix the TODO below. #include "chrome/browser/prefs/pref_service.h" #include "chrome/common/pref_names.h" namespace browser_sync { namespace { class MockSyncFrontend : public SyncFrontend { public: virtual ~MockSyncFrontend() {} MOCK_METHOD0(OnBackendInitialized, void()); MOCK_METHOD0(OnSyncCycleCompleted, void()); MOCK_METHOD0(OnAuthError, void()); MOCK_METHOD0(OnStopSyncingPermanently, void()); MOCK_METHOD0(OnClearServerDataSucceeded, void()); MOCK_METHOD0(OnClearServerDataFailed, void()); MOCK_METHOD1(OnPassphraseRequired, void(bool)); MOCK_METHOD0(OnPassphraseAccepted, void()); MOCK_METHOD1(OnEncryptionComplete, void(const syncable::ModelTypeSet&)); MOCK_METHOD1(OnMigrationNeededForTypes, void(const syncable::ModelTypeSet&)); }; } // namespace class SyncBackendHostTest : public testing::Test { protected: SyncBackendHostTest() : ui_thread_(BrowserThread::UI, &ui_loop_) {} private: MessageLoop ui_loop_; BrowserThread ui_thread_; }; TEST_F(SyncBackendHostTest, InitShutdown) { TestingProfile profile; profile.CreateRequestContext(); SyncBackendHost backend(&profile); // TODO(akalin): Handle this in SyncBackendHost instead of in // ProfileSyncService, or maybe figure out a way to share the // "register sync prefs" code. PrefService* pref_service = profile.GetPrefs(); pref_service->RegisterStringPref(prefs::kEncryptionBootstrapToken, ""); MockSyncFrontend mock_frontend; sync_api::SyncCredentials credentials; credentials.email = "user@example.com"; credentials.sync_token = "sync_token"; backend.Initialize(&mock_frontend, GURL("http://www.example.com"), syncable::ModelTypeSet(), profile.GetRequestContext(), credentials, true); backend.Shutdown(false); // Scoping for io_thread to get destroyed before other locals. { // The request context gets deleted on the I/O thread. To prevent a leak // supply one here. // TODO(sanjeevr): Investigate whether we can do this within // ResetRequestContext BrowserThread io_thread(BrowserThread::IO, MessageLoop::current()); profile.ResetRequestContext(); } MessageLoop::current()->RunAllPending(); } TEST_F(SyncBackendHostTest, MakePendingConfigModeState) { // Empty. { DataTypeController::TypeMap data_type_controllers; syncable::ModelTypeSet types; ModelSafeRoutingInfo routing_info; scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState> state(SyncBackendHost::MakePendingConfigModeState( data_type_controllers, types, NULL, &routing_info)); EXPECT_TRUE(routing_info.empty()); EXPECT_FALSE(state->ready_task.get()); EXPECT_EQ(types, state->initial_types); EXPECT_FALSE(state->deleted_type); EXPECT_TRUE(state->added_types.none()); } // No enabled types. { DataTypeController::TypeMap data_type_controllers; data_type_controllers[syncable::BOOKMARKS] = NULL; syncable::ModelTypeSet types; ModelSafeRoutingInfo routing_info; scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState> state(SyncBackendHost::MakePendingConfigModeState( data_type_controllers, types, NULL, &routing_info)); EXPECT_TRUE(routing_info.empty()); EXPECT_FALSE(state->ready_task.get()); EXPECT_EQ(types, state->initial_types); EXPECT_TRUE(state->deleted_type); EXPECT_TRUE(state->added_types.none()); } // Add type. { DataTypeController::TypeMap data_type_controllers; data_type_controllers[syncable::BOOKMARKS] = NULL; syncable::ModelTypeSet types; types.insert(syncable::BOOKMARKS); ModelSafeRoutingInfo routing_info; scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState> state(SyncBackendHost::MakePendingConfigModeState( data_type_controllers, types, NULL, &routing_info)); ModelSafeRoutingInfo expected_routing_info; expected_routing_info[syncable::BOOKMARKS] = GROUP_PASSIVE; EXPECT_EQ(expected_routing_info, routing_info); EXPECT_FALSE(state->ready_task.get()); EXPECT_EQ(types, state->initial_types); EXPECT_FALSE(state->deleted_type); syncable::ModelTypeBitSet expected_added_types; expected_added_types.set(syncable::BOOKMARKS); EXPECT_EQ(expected_added_types, state->added_types); } // Add existing type. { DataTypeController::TypeMap data_type_controllers; data_type_controllers[syncable::BOOKMARKS] = NULL; syncable::ModelTypeSet types; types.insert(syncable::BOOKMARKS); ModelSafeRoutingInfo routing_info; routing_info[syncable::BOOKMARKS] = GROUP_PASSIVE; ModelSafeRoutingInfo expected_routing_info = routing_info; scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState> state(SyncBackendHost::MakePendingConfigModeState( data_type_controllers, types, NULL, &routing_info)); EXPECT_EQ(expected_routing_info, routing_info); EXPECT_FALSE(state->ready_task.get()); EXPECT_EQ(types, state->initial_types); EXPECT_FALSE(state->deleted_type); EXPECT_TRUE(state->added_types.none()); } // Delete type. { DataTypeController::TypeMap data_type_controllers; data_type_controllers[syncable::BOOKMARKS] = NULL; syncable::ModelTypeSet types; ModelSafeRoutingInfo routing_info; routing_info[syncable::BOOKMARKS] = GROUP_PASSIVE; scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState> state(SyncBackendHost::MakePendingConfigModeState( data_type_controllers, types, NULL, &routing_info)); ModelSafeRoutingInfo expected_routing_info; EXPECT_EQ(expected_routing_info, routing_info); EXPECT_FALSE(state->ready_task.get()); EXPECT_EQ(types, state->initial_types); EXPECT_TRUE(state->deleted_type); EXPECT_TRUE(state->added_types.none()); } } // TODO(akalin): Write more SyncBackendHost unit tests. } // namespace browser_sync