1// Copyright (c) 2011 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 "chrome/browser/sync/glue/sync_backend_host.h" 6 7#include <cstddef> 8 9#include "base/message_loop.h" 10#include "base/scoped_ptr.h" 11#include "chrome/browser/sync/engine/model_safe_worker.h" 12#include "chrome/browser/sync/engine/syncapi.h" 13#include "chrome/browser/sync/glue/data_type_controller.h" 14#include "chrome/browser/sync/syncable/model_type.h" 15#include "chrome/test/testing_profile.h" 16#include "content/browser/browser_thread.h" 17#include "googleurl/src/gurl.h" 18#include "testing/gmock/include/gmock/gmock.h" 19#include "testing/gtest/include/gtest/gtest.h" 20 21// TODO(akalin): Remove this once we fix the TODO below. 22#include "chrome/browser/prefs/pref_service.h" 23#include "chrome/common/pref_names.h" 24 25namespace browser_sync { 26 27namespace { 28 29class MockSyncFrontend : public SyncFrontend { 30 public: 31 virtual ~MockSyncFrontend() {} 32 33 MOCK_METHOD0(OnBackendInitialized, void()); 34 MOCK_METHOD0(OnSyncCycleCompleted, void()); 35 MOCK_METHOD0(OnAuthError, void()); 36 MOCK_METHOD0(OnStopSyncingPermanently, void()); 37 MOCK_METHOD0(OnClearServerDataSucceeded, void()); 38 MOCK_METHOD0(OnClearServerDataFailed, void()); 39 MOCK_METHOD1(OnPassphraseRequired, void(bool)); 40 MOCK_METHOD0(OnPassphraseAccepted, void()); 41 MOCK_METHOD1(OnEncryptionComplete, void(const syncable::ModelTypeSet&)); 42 MOCK_METHOD1(OnMigrationNeededForTypes, void(const syncable::ModelTypeSet&)); 43}; 44 45} // namespace 46 47class SyncBackendHostTest : public testing::Test { 48 protected: 49 SyncBackendHostTest() 50 : ui_thread_(BrowserThread::UI, &ui_loop_) {} 51 52 private: 53 MessageLoop ui_loop_; 54 BrowserThread ui_thread_; 55}; 56 57TEST_F(SyncBackendHostTest, InitShutdown) { 58 TestingProfile profile; 59 profile.CreateRequestContext(); 60 61 SyncBackendHost backend(&profile); 62 63 // TODO(akalin): Handle this in SyncBackendHost instead of in 64 // ProfileSyncService, or maybe figure out a way to share the 65 // "register sync prefs" code. 66 PrefService* pref_service = profile.GetPrefs(); 67 pref_service->RegisterStringPref(prefs::kEncryptionBootstrapToken, ""); 68 69 MockSyncFrontend mock_frontend; 70 sync_api::SyncCredentials credentials; 71 credentials.email = "user@example.com"; 72 credentials.sync_token = "sync_token"; 73 backend.Initialize(&mock_frontend, 74 GURL("http://www.example.com"), 75 syncable::ModelTypeSet(), 76 profile.GetRequestContext(), 77 credentials, 78 true); 79 backend.Shutdown(false); 80 // Scoping for io_thread to get destroyed before other locals. 81 { 82 // The request context gets deleted on the I/O thread. To prevent a leak 83 // supply one here. 84 // TODO(sanjeevr): Investigate whether we can do this within 85 // ResetRequestContext 86 BrowserThread io_thread(BrowserThread::IO, MessageLoop::current()); 87 profile.ResetRequestContext(); 88 } 89 MessageLoop::current()->RunAllPending(); 90} 91 92TEST_F(SyncBackendHostTest, MakePendingConfigModeState) { 93 // Empty. 94 { 95 DataTypeController::TypeMap data_type_controllers; 96 syncable::ModelTypeSet types; 97 ModelSafeRoutingInfo routing_info; 98 99 scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState> 100 state(SyncBackendHost::MakePendingConfigModeState( 101 data_type_controllers, types, NULL, &routing_info)); 102 EXPECT_TRUE(routing_info.empty()); 103 EXPECT_FALSE(state->ready_task.get()); 104 EXPECT_EQ(types, state->initial_types); 105 EXPECT_FALSE(state->deleted_type); 106 EXPECT_TRUE(state->added_types.none()); 107 } 108 109 // No enabled types. 110 { 111 DataTypeController::TypeMap data_type_controllers; 112 data_type_controllers[syncable::BOOKMARKS] = NULL; 113 syncable::ModelTypeSet types; 114 ModelSafeRoutingInfo routing_info; 115 116 scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState> 117 state(SyncBackendHost::MakePendingConfigModeState( 118 data_type_controllers, types, NULL, &routing_info)); 119 EXPECT_TRUE(routing_info.empty()); 120 EXPECT_FALSE(state->ready_task.get()); 121 EXPECT_EQ(types, state->initial_types); 122 EXPECT_TRUE(state->deleted_type); 123 EXPECT_TRUE(state->added_types.none()); 124 } 125 126 // Add type. 127 { 128 DataTypeController::TypeMap data_type_controllers; 129 data_type_controllers[syncable::BOOKMARKS] = NULL; 130 syncable::ModelTypeSet types; 131 types.insert(syncable::BOOKMARKS); 132 ModelSafeRoutingInfo routing_info; 133 134 scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState> 135 state(SyncBackendHost::MakePendingConfigModeState( 136 data_type_controllers, types, NULL, &routing_info)); 137 138 ModelSafeRoutingInfo expected_routing_info; 139 expected_routing_info[syncable::BOOKMARKS] = GROUP_PASSIVE; 140 EXPECT_EQ(expected_routing_info, routing_info); 141 EXPECT_FALSE(state->ready_task.get()); 142 EXPECT_EQ(types, state->initial_types); 143 EXPECT_FALSE(state->deleted_type); 144 145 syncable::ModelTypeBitSet expected_added_types; 146 expected_added_types.set(syncable::BOOKMARKS); 147 EXPECT_EQ(expected_added_types, state->added_types); 148 } 149 150 // Add existing type. 151 { 152 DataTypeController::TypeMap data_type_controllers; 153 data_type_controllers[syncable::BOOKMARKS] = NULL; 154 syncable::ModelTypeSet types; 155 types.insert(syncable::BOOKMARKS); 156 ModelSafeRoutingInfo routing_info; 157 routing_info[syncable::BOOKMARKS] = GROUP_PASSIVE; 158 ModelSafeRoutingInfo expected_routing_info = routing_info; 159 160 scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState> 161 state(SyncBackendHost::MakePendingConfigModeState( 162 data_type_controllers, types, NULL, &routing_info)); 163 164 EXPECT_EQ(expected_routing_info, routing_info); 165 EXPECT_FALSE(state->ready_task.get()); 166 EXPECT_EQ(types, state->initial_types); 167 EXPECT_FALSE(state->deleted_type); 168 EXPECT_TRUE(state->added_types.none()); 169 } 170 171 // Delete type. 172 { 173 DataTypeController::TypeMap data_type_controllers; 174 data_type_controllers[syncable::BOOKMARKS] = NULL; 175 syncable::ModelTypeSet types; 176 ModelSafeRoutingInfo routing_info; 177 routing_info[syncable::BOOKMARKS] = GROUP_PASSIVE; 178 179 scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState> 180 state(SyncBackendHost::MakePendingConfigModeState( 181 data_type_controllers, types, NULL, &routing_info)); 182 183 ModelSafeRoutingInfo expected_routing_info; 184 EXPECT_EQ(expected_routing_info, routing_info); 185 EXPECT_FALSE(state->ready_task.get()); 186 EXPECT_EQ(types, state->initial_types); 187 EXPECT_TRUE(state->deleted_type); 188 EXPECT_TRUE(state->added_types.none()); 189 } 190} 191 192// TODO(akalin): Write more SyncBackendHost unit tests. 193 194} // namespace browser_sync 195