| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 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/bind.h" | |
| 6 #include "base/callback.h" | |
| 7 #include "base/json/json_reader.h" | |
| 8 #include "base/prefs/testing_pref_store.h" | |
| 9 #include "base/strings/string_util.h" | |
| 10 #include "chrome/browser/managed_mode/managed_user_settings_service.h" | |
| 11 #include "sync/api/fake_sync_change_processor.h" | |
| 12 #include "sync/api/sync_change.h" | |
| 13 #include "sync/api/sync_change_processor_wrapper_for_test.h" | |
| 14 #include "sync/api/sync_error_factory_mock.h" | |
| 15 #include "sync/protocol/sync.pb.h" | |
| 16 #include "testing/gtest/include/gtest/gtest.h" | |
| 17 | |
| 18 namespace { | |
| 19 | |
| 20 class MockSyncErrorFactory : public syncer::SyncErrorFactory { | |
| 21 public: | |
| 22 explicit MockSyncErrorFactory(syncer::ModelType type); | |
| 23 virtual ~MockSyncErrorFactory(); | |
| 24 | |
| 25 // SyncErrorFactory implementation: | |
| 26 virtual syncer::SyncError CreateAndUploadError( | |
| 27 const tracked_objects::Location& location, | |
| 28 const std::string& message) OVERRIDE; | |
| 29 | |
| 30 private: | |
| 31 syncer::ModelType type_; | |
| 32 | |
| 33 DISALLOW_COPY_AND_ASSIGN(MockSyncErrorFactory); | |
| 34 }; | |
| 35 | |
| 36 MockSyncErrorFactory::MockSyncErrorFactory(syncer::ModelType type) | |
| 37 : type_(type) {} | |
| 38 | |
| 39 MockSyncErrorFactory::~MockSyncErrorFactory() {} | |
| 40 | |
| 41 syncer::SyncError MockSyncErrorFactory::CreateAndUploadError( | |
| 42 const tracked_objects::Location& location, | |
| 43 const std::string& message) { | |
| 44 return syncer::SyncError(location, | |
| 45 syncer::SyncError::DATATYPE_ERROR, | |
| 46 message, | |
| 47 type_); | |
| 48 } | |
| 49 | |
| 50 } // namespace | |
| 51 | |
| 52 const char kAtomicItemName[] = "X-Wombat"; | |
| 53 const char kSettingsName[] = "TestingSetting"; | |
| 54 const char kSettingsValue[] = "SettingsValue"; | |
| 55 const char kSplitItemName[] = "X-SuperMoosePowers"; | |
| 56 | |
| 57 class ManagedUserSettingsServiceTest : public ::testing::Test { | |
| 58 protected: | |
| 59 ManagedUserSettingsServiceTest() {} | |
| 60 virtual ~ManagedUserSettingsServiceTest() {} | |
| 61 | |
| 62 scoped_ptr<syncer::SyncChangeProcessor> CreateSyncProcessor() { | |
| 63 sync_processor_.reset(new syncer::FakeSyncChangeProcessor); | |
| 64 return scoped_ptr<syncer::SyncChangeProcessor>( | |
| 65 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get())); | |
| 66 } | |
| 67 | |
| 68 void StartSyncing(const syncer::SyncDataList& initial_sync_data) { | |
| 69 scoped_ptr<syncer::SyncErrorFactory> error_handler( | |
| 70 new MockSyncErrorFactory(syncer::SUPERVISED_USER_SETTINGS)); | |
| 71 syncer::SyncMergeResult result = settings_service_.MergeDataAndStartSyncing( | |
| 72 syncer::SUPERVISED_USER_SETTINGS, | |
| 73 initial_sync_data, | |
| 74 CreateSyncProcessor(), | |
| 75 error_handler.Pass()); | |
| 76 EXPECT_FALSE(result.error().IsSet()); | |
| 77 } | |
| 78 | |
| 79 void UploadSplitItem(const std::string& key, const std::string& value) { | |
| 80 split_items_.SetStringWithoutPathExpansion(key, value); | |
| 81 settings_service_.UploadItem( | |
| 82 ManagedUserSettingsService::MakeSplitSettingKey(kSplitItemName, | |
| 83 key), | |
| 84 scoped_ptr<base::Value>(new base::StringValue(value))); | |
| 85 } | |
| 86 | |
| 87 void UploadAtomicItem(const std::string& value) { | |
| 88 atomic_setting_value_.reset(new base::StringValue(value)); | |
| 89 settings_service_.UploadItem( | |
| 90 kAtomicItemName, | |
| 91 scoped_ptr<base::Value>(new base::StringValue(value))); | |
| 92 } | |
| 93 | |
| 94 void VerifySyncDataItem(syncer::SyncData sync_data) { | |
| 95 const sync_pb::ManagedUserSettingSpecifics& managed_user_setting = | |
| 96 sync_data.GetSpecifics().managed_user_setting(); | |
| 97 base::Value* expected_value = NULL; | |
| 98 if (managed_user_setting.name() == kAtomicItemName) { | |
| 99 expected_value = atomic_setting_value_.get(); | |
| 100 } else { | |
| 101 EXPECT_TRUE(StartsWithASCII(managed_user_setting.name(), | |
| 102 std::string(kSplitItemName) + ':', | |
| 103 true)); | |
| 104 std::string key = | |
| 105 managed_user_setting.name().substr(strlen(kSplitItemName) + 1); | |
| 106 EXPECT_TRUE(split_items_.GetWithoutPathExpansion(key, &expected_value)); | |
| 107 } | |
| 108 | |
| 109 scoped_ptr<base::Value> value( | |
| 110 base::JSONReader::Read(managed_user_setting.value())); | |
| 111 EXPECT_TRUE(expected_value->Equals(value.get())); | |
| 112 } | |
| 113 | |
| 114 void OnNewSettingsAvailable(const base::DictionaryValue* settings) { | |
| 115 if (!settings) | |
| 116 settings_.reset(); | |
| 117 else | |
| 118 settings_.reset(settings->DeepCopy()); | |
| 119 } | |
| 120 | |
| 121 // testing::Test overrides: | |
| 122 virtual void SetUp() OVERRIDE { | |
| 123 TestingPrefStore* pref_store = new TestingPrefStore; | |
| 124 settings_service_.Init(pref_store); | |
| 125 settings_service_.Subscribe( | |
| 126 base::Bind(&ManagedUserSettingsServiceTest::OnNewSettingsAvailable, | |
| 127 base::Unretained(this))); | |
| 128 pref_store->SetInitializationCompleted(); | |
| 129 ASSERT_FALSE(settings_); | |
| 130 settings_service_.SetActive(true); | |
| 131 ASSERT_TRUE(settings_); | |
| 132 } | |
| 133 | |
| 134 virtual void TearDown() OVERRIDE { | |
| 135 settings_service_.Shutdown(); | |
| 136 } | |
| 137 | |
| 138 base::DictionaryValue split_items_; | |
| 139 scoped_ptr<base::Value> atomic_setting_value_; | |
| 140 ManagedUserSettingsService settings_service_; | |
| 141 scoped_ptr<base::DictionaryValue> settings_; | |
| 142 | |
| 143 scoped_ptr<syncer::FakeSyncChangeProcessor> sync_processor_; | |
| 144 }; | |
| 145 | |
| 146 TEST_F(ManagedUserSettingsServiceTest, ProcessAtomicSetting) { | |
| 147 StartSyncing(syncer::SyncDataList()); | |
| 148 ASSERT_TRUE(settings_); | |
| 149 const base::Value* value = NULL; | |
| 150 EXPECT_FALSE(settings_->GetWithoutPathExpansion(kSettingsName, &value)); | |
| 151 | |
| 152 settings_.reset(); | |
| 153 syncer::SyncData data = | |
| 154 ManagedUserSettingsService::CreateSyncDataForSetting( | |
| 155 kSettingsName, base::StringValue(kSettingsValue)); | |
| 156 syncer::SyncChangeList change_list; | |
| 157 change_list.push_back( | |
| 158 syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, data)); | |
| 159 syncer::SyncError error = | |
| 160 settings_service_.ProcessSyncChanges(FROM_HERE, change_list); | |
| 161 EXPECT_FALSE(error.IsSet()) << error.ToString(); | |
| 162 ASSERT_TRUE(settings_); | |
| 163 ASSERT_TRUE(settings_->GetWithoutPathExpansion(kSettingsName, &value)); | |
| 164 std::string string_value; | |
| 165 EXPECT_TRUE(value->GetAsString(&string_value)); | |
| 166 EXPECT_EQ(kSettingsValue, string_value); | |
| 167 } | |
| 168 | |
| 169 TEST_F(ManagedUserSettingsServiceTest, ProcessSplitSetting) { | |
| 170 StartSyncing(syncer::SyncDataList()); | |
| 171 ASSERT_TRUE(settings_); | |
| 172 const base::Value* value = NULL; | |
| 173 EXPECT_FALSE(settings_->GetWithoutPathExpansion(kSettingsName, &value)); | |
| 174 | |
| 175 base::DictionaryValue dict; | |
| 176 dict.SetString("foo", "bar"); | |
| 177 dict.SetBoolean("awesomesauce", true); | |
| 178 dict.SetInteger("eaudecologne", 4711); | |
| 179 | |
| 180 settings_.reset(); | |
| 181 syncer::SyncChangeList change_list; | |
| 182 for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { | |
| 183 syncer::SyncData data = | |
| 184 ManagedUserSettingsService::CreateSyncDataForSetting( | |
| 185 ManagedUserSettingsService::MakeSplitSettingKey(kSettingsName, | |
| 186 it.key()), | |
| 187 it.value()); | |
| 188 change_list.push_back( | |
| 189 syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, data)); | |
| 190 } | |
| 191 syncer::SyncError error = | |
| 192 settings_service_.ProcessSyncChanges(FROM_HERE, change_list); | |
| 193 EXPECT_FALSE(error.IsSet()) << error.ToString(); | |
| 194 ASSERT_TRUE(settings_); | |
| 195 ASSERT_TRUE(settings_->GetWithoutPathExpansion(kSettingsName, &value)); | |
| 196 const base::DictionaryValue* dict_value = NULL; | |
| 197 ASSERT_TRUE(value->GetAsDictionary(&dict_value)); | |
| 198 EXPECT_TRUE(dict_value->Equals(&dict)); | |
| 199 } | |
| 200 | |
| 201 TEST_F(ManagedUserSettingsServiceTest, SetLocalSetting) { | |
| 202 const base::Value* value = NULL; | |
| 203 EXPECT_FALSE(settings_->GetWithoutPathExpansion(kSettingsName, &value)); | |
| 204 | |
| 205 settings_.reset(); | |
| 206 settings_service_.SetLocalSettingForTesting( | |
| 207 kSettingsName, | |
| 208 scoped_ptr<base::Value>(new base::StringValue(kSettingsValue))); | |
| 209 ASSERT_TRUE(settings_); | |
| 210 ASSERT_TRUE(settings_->GetWithoutPathExpansion(kSettingsName, &value)); | |
| 211 std::string string_value; | |
| 212 EXPECT_TRUE(value->GetAsString(&string_value)); | |
| 213 EXPECT_EQ(kSettingsValue, string_value); | |
| 214 } | |
| 215 | |
| 216 TEST_F(ManagedUserSettingsServiceTest, UploadItem) { | |
| 217 UploadSplitItem("foo", "bar"); | |
| 218 UploadSplitItem("blurp", "baz"); | |
| 219 UploadAtomicItem("hurdle"); | |
| 220 | |
| 221 // Uploading should produce changes when we start syncing. | |
| 222 StartSyncing(syncer::SyncDataList()); | |
| 223 ASSERT_EQ(3u, sync_processor_->changes().size()); | |
| 224 for (syncer::SyncChangeList::const_iterator it = | |
| 225 sync_processor_->changes().begin(); | |
| 226 it != sync_processor_->changes().end(); | |
| 227 ++it) { | |
| 228 ASSERT_TRUE(it->IsValid()); | |
| 229 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, it->change_type()); | |
| 230 VerifySyncDataItem(it->sync_data()); | |
| 231 } | |
| 232 | |
| 233 // It should also show up in local Sync data. | |
| 234 syncer::SyncDataList sync_data = | |
| 235 settings_service_.GetAllSyncData(syncer::SUPERVISED_USER_SETTINGS); | |
| 236 EXPECT_EQ(3u, sync_data.size()); | |
| 237 for (syncer::SyncDataList::const_iterator it = sync_data.begin(); | |
| 238 it != sync_data.end(); ++it) { | |
| 239 VerifySyncDataItem(*it); | |
| 240 } | |
| 241 | |
| 242 // Uploading after we have started syncing should work too. | |
| 243 sync_processor_->changes().clear(); | |
| 244 UploadSplitItem("froodle", "narf"); | |
| 245 ASSERT_EQ(1u, sync_processor_->changes().size()); | |
| 246 syncer::SyncChange change = sync_processor_->changes()[0]; | |
| 247 ASSERT_TRUE(change.IsValid()); | |
| 248 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type()); | |
| 249 VerifySyncDataItem(change.sync_data()); | |
| 250 | |
| 251 sync_data = settings_service_.GetAllSyncData( | |
| 252 syncer::SUPERVISED_USER_SETTINGS); | |
| 253 EXPECT_EQ(4u, sync_data.size()); | |
| 254 for (syncer::SyncDataList::const_iterator it = sync_data.begin(); | |
| 255 it != sync_data.end(); ++it) { | |
| 256 VerifySyncDataItem(*it); | |
| 257 } | |
| 258 | |
| 259 // Uploading an item with a previously seen key should create an UPDATE | |
| 260 // action. | |
| 261 sync_processor_->changes().clear(); | |
| 262 UploadSplitItem("blurp", "snarl"); | |
| 263 ASSERT_EQ(1u, sync_processor_->changes().size()); | |
| 264 change = sync_processor_->changes()[0]; | |
| 265 ASSERT_TRUE(change.IsValid()); | |
| 266 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type()); | |
| 267 VerifySyncDataItem(change.sync_data()); | |
| 268 | |
| 269 sync_data = settings_service_.GetAllSyncData( | |
| 270 syncer::SUPERVISED_USER_SETTINGS); | |
| 271 EXPECT_EQ(4u, sync_data.size()); | |
| 272 for (syncer::SyncDataList::const_iterator it = sync_data.begin(); | |
| 273 it != sync_data.end(); ++it) { | |
| 274 VerifySyncDataItem(*it); | |
| 275 } | |
| 276 | |
| 277 sync_processor_->changes().clear(); | |
| 278 UploadAtomicItem("fjord"); | |
| 279 ASSERT_EQ(1u, sync_processor_->changes().size()); | |
| 280 change = sync_processor_->changes()[0]; | |
| 281 ASSERT_TRUE(change.IsValid()); | |
| 282 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type()); | |
| 283 VerifySyncDataItem(change.sync_data()); | |
| 284 | |
| 285 sync_data = settings_service_.GetAllSyncData( | |
| 286 syncer::SUPERVISED_USER_SETTINGS); | |
| 287 EXPECT_EQ(4u, sync_data.size()); | |
| 288 for (syncer::SyncDataList::const_iterator it = sync_data.begin(); | |
| 289 it != sync_data.end(); ++it) { | |
| 290 VerifySyncDataItem(*it); | |
| 291 } | |
| 292 | |
| 293 // The uploaded items should not show up as settings. | |
| 294 const base::Value* value = NULL; | |
| 295 EXPECT_FALSE(settings_->GetWithoutPathExpansion(kAtomicItemName, &value)); | |
| 296 EXPECT_FALSE(settings_->GetWithoutPathExpansion(kSplitItemName, &value)); | |
| 297 | |
| 298 // Restarting sync should not create any new changes. | |
| 299 settings_service_.StopSyncing(syncer::SUPERVISED_USER_SETTINGS); | |
| 300 StartSyncing(sync_data); | |
| 301 ASSERT_EQ(0u, sync_processor_->changes().size()); | |
| 302 } | |
| OLD | NEW |