| OLD | NEW |
| (Empty) |
| 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/callback.h" | |
| 6 #include "base/json/json_reader.h" | |
| 7 #include "base/prefs/testing_pref_store.h" | |
| 8 #include "base/strings/string_util.h" | |
| 9 #include "chrome/browser/policy/configuration_policy_provider_test.h" | |
| 10 #include "chrome/browser/policy/external_data_fetcher.h" | |
| 11 #include "chrome/browser/policy/managed_mode_policy_provider.h" | |
| 12 #include "chrome/browser/policy/policy_bundle.h" | |
| 13 #include "chrome/browser/policy/policy_map.h" | |
| 14 #include "sync/api/sync_change.h" | |
| 15 #include "sync/api/sync_error_factory_mock.h" | |
| 16 #include "sync/protocol/sync.pb.h" | |
| 17 #include "testing/gtest/include/gtest/gtest.h" | |
| 18 | |
| 19 namespace policy { | |
| 20 | |
| 21 namespace { | |
| 22 | |
| 23 class MockChangeProcessor : public syncer::SyncChangeProcessor { | |
| 24 public: | |
| 25 MockChangeProcessor() {} | |
| 26 virtual ~MockChangeProcessor() {} | |
| 27 | |
| 28 // SyncChangeProcessor implementation: | |
| 29 virtual syncer::SyncError ProcessSyncChanges( | |
| 30 const tracked_objects::Location& from_here, | |
| 31 const syncer::SyncChangeList& change_list) OVERRIDE; | |
| 32 | |
| 33 const syncer::SyncChangeList& changes() const { return change_list_; } | |
| 34 | |
| 35 virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const | |
| 36 OVERRIDE { | |
| 37 return syncer::SyncDataList(); | |
| 38 } | |
| 39 | |
| 40 private: | |
| 41 syncer::SyncChangeList change_list_; | |
| 42 | |
| 43 DISALLOW_COPY_AND_ASSIGN(MockChangeProcessor); | |
| 44 }; | |
| 45 | |
| 46 syncer::SyncError MockChangeProcessor::ProcessSyncChanges( | |
| 47 const tracked_objects::Location& from_here, | |
| 48 const syncer::SyncChangeList& change_list) { | |
| 49 change_list_ = change_list; | |
| 50 return syncer::SyncError(); | |
| 51 } | |
| 52 | |
| 53 class MockSyncErrorFactory : public syncer::SyncErrorFactory { | |
| 54 public: | |
| 55 explicit MockSyncErrorFactory(syncer::ModelType type); | |
| 56 virtual ~MockSyncErrorFactory(); | |
| 57 | |
| 58 // SyncErrorFactory implementation: | |
| 59 virtual syncer::SyncError CreateAndUploadError( | |
| 60 const tracked_objects::Location& location, | |
| 61 const std::string& message) OVERRIDE; | |
| 62 | |
| 63 private: | |
| 64 syncer::ModelType type_; | |
| 65 | |
| 66 DISALLOW_COPY_AND_ASSIGN(MockSyncErrorFactory); | |
| 67 }; | |
| 68 | |
| 69 MockSyncErrorFactory::MockSyncErrorFactory(syncer::ModelType type) | |
| 70 : type_(type) {} | |
| 71 | |
| 72 MockSyncErrorFactory::~MockSyncErrorFactory() {} | |
| 73 | |
| 74 syncer::SyncError MockSyncErrorFactory::CreateAndUploadError( | |
| 75 const tracked_objects::Location& location, | |
| 76 const std::string& message) { | |
| 77 return syncer::SyncError(location, | |
| 78 syncer::SyncError::DATATYPE_ERROR, | |
| 79 message, | |
| 80 type_); | |
| 81 } | |
| 82 | |
| 83 class TestHarness : public PolicyProviderTestHarness { | |
| 84 public: | |
| 85 TestHarness(); | |
| 86 virtual ~TestHarness(); | |
| 87 | |
| 88 static PolicyProviderTestHarness* Create(); | |
| 89 | |
| 90 // PolicyProviderTestHarness implementation: | |
| 91 virtual void SetUp() OVERRIDE; | |
| 92 | |
| 93 virtual ConfigurationPolicyProvider* CreateProvider( | |
| 94 scoped_refptr<base::SequencedTaskRunner> task_runner, | |
| 95 const PolicyDefinitionList* policy_definition_list) OVERRIDE; | |
| 96 | |
| 97 virtual void InstallEmptyPolicy() OVERRIDE; | |
| 98 virtual void InstallStringPolicy(const std::string& policy_name, | |
| 99 const std::string& policy_value) OVERRIDE; | |
| 100 virtual void InstallIntegerPolicy(const std::string& policy_name, | |
| 101 int policy_value) OVERRIDE; | |
| 102 virtual void InstallBooleanPolicy(const std::string& policy_name, | |
| 103 bool policy_value) OVERRIDE; | |
| 104 virtual void InstallStringListPolicy( | |
| 105 const std::string& policy_name, | |
| 106 const base::ListValue* policy_value) OVERRIDE; | |
| 107 virtual void InstallDictionaryPolicy( | |
| 108 const std::string& policy_name, | |
| 109 const base::DictionaryValue* policy_value) OVERRIDE; | |
| 110 | |
| 111 private: | |
| 112 void InstallSimplePolicy(const std::string& policy_name, | |
| 113 scoped_ptr<base::Value> policy_value); | |
| 114 | |
| 115 scoped_refptr<TestingPrefStore> pref_store_; | |
| 116 | |
| 117 // Owned by the test fixture. | |
| 118 ManagedModePolicyProvider* provider_; | |
| 119 | |
| 120 DISALLOW_COPY_AND_ASSIGN(TestHarness); | |
| 121 }; | |
| 122 | |
| 123 TestHarness::TestHarness() | |
| 124 : PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER), | |
| 125 pref_store_(new TestingPrefStore) { | |
| 126 pref_store_->SetInitializationCompleted(); | |
| 127 } | |
| 128 | |
| 129 TestHarness::~TestHarness() {} | |
| 130 | |
| 131 // static | |
| 132 PolicyProviderTestHarness* TestHarness::Create() { | |
| 133 return new TestHarness(); | |
| 134 } | |
| 135 | |
| 136 void TestHarness::SetUp() {} | |
| 137 | |
| 138 ConfigurationPolicyProvider* TestHarness::CreateProvider( | |
| 139 scoped_refptr<base::SequencedTaskRunner> task_runner, | |
| 140 const PolicyDefinitionList* policy_definition_list) { | |
| 141 provider_ = new ManagedModePolicyProvider(pref_store_.get()); | |
| 142 syncer::SyncDataList initial_sync_data; | |
| 143 scoped_ptr<syncer::SyncChangeProcessor> sync_processor( | |
| 144 new MockChangeProcessor()); | |
| 145 scoped_ptr<syncer::SyncErrorFactory> error_handler( | |
| 146 new MockSyncErrorFactory(syncer::MANAGED_USER_SETTINGS)); | |
| 147 syncer::SyncMergeResult result = | |
| 148 provider_->MergeDataAndStartSyncing(syncer::MANAGED_USER_SETTINGS, | |
| 149 initial_sync_data, | |
| 150 sync_processor.Pass(), | |
| 151 error_handler.Pass()); | |
| 152 EXPECT_FALSE(result.error().IsSet()); | |
| 153 return provider_; | |
| 154 } | |
| 155 | |
| 156 void TestHarness::InstallSimplePolicy(const std::string& policy_name, | |
| 157 scoped_ptr<base::Value> policy_value) { | |
| 158 syncer::SyncData data = ManagedModePolicyProvider::CreateSyncDataForPolicy( | |
| 159 policy_name, policy_value.get()); | |
| 160 syncer::SyncChangeList change_list; | |
| 161 change_list.push_back( | |
| 162 syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, data)); | |
| 163 syncer::SyncError error = | |
| 164 provider_->ProcessSyncChanges(FROM_HERE, change_list); | |
| 165 EXPECT_FALSE(error.IsSet()) << error.ToString(); | |
| 166 } | |
| 167 | |
| 168 void TestHarness::InstallEmptyPolicy() {} | |
| 169 | |
| 170 void TestHarness::InstallStringPolicy(const std::string& policy_name, | |
| 171 const std::string& policy_value) { | |
| 172 InstallSimplePolicy( | |
| 173 policy_name, | |
| 174 scoped_ptr<base::Value>(base::Value::CreateStringValue(policy_value))); | |
| 175 } | |
| 176 | |
| 177 void TestHarness::InstallIntegerPolicy(const std::string& policy_name, | |
| 178 int policy_value) { | |
| 179 InstallSimplePolicy( | |
| 180 policy_name, | |
| 181 scoped_ptr<base::Value>(new base::FundamentalValue(policy_value))); | |
| 182 } | |
| 183 | |
| 184 void TestHarness::InstallBooleanPolicy(const std::string& policy_name, | |
| 185 bool policy_value) { | |
| 186 InstallSimplePolicy( | |
| 187 policy_name, | |
| 188 scoped_ptr<base::Value>(new base::FundamentalValue(policy_value))); | |
| 189 } | |
| 190 | |
| 191 void TestHarness::InstallStringListPolicy(const std::string& policy_name, | |
| 192 const base::ListValue* policy_value) { | |
| 193 InstallSimplePolicy(policy_name, | |
| 194 scoped_ptr<base::Value>(policy_value->DeepCopy())); | |
| 195 } | |
| 196 | |
| 197 void TestHarness::InstallDictionaryPolicy( | |
| 198 const std::string& policy_name, | |
| 199 const base::DictionaryValue* policy_value) { | |
| 200 syncer::SyncChangeList change_list; | |
| 201 for (base::DictionaryValue::Iterator it(*policy_value); !it.IsAtEnd(); | |
| 202 it.Advance()) { | |
| 203 syncer::SyncData data = ManagedModePolicyProvider::CreateSyncDataForPolicy( | |
| 204 ManagedModePolicyProvider::MakeSplitSettingKey(policy_name, it.key()), | |
| 205 &it.value()); | |
| 206 change_list.push_back( | |
| 207 syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, data)); | |
| 208 } | |
| 209 syncer::SyncError error = | |
| 210 provider_->ProcessSyncChanges(FROM_HERE, change_list); | |
| 211 EXPECT_FALSE(error.IsSet()) << error.ToString(); | |
| 212 } | |
| 213 | |
| 214 } // namespace | |
| 215 | |
| 216 // Instantiate abstract test case for basic policy reading tests. | |
| 217 INSTANTIATE_TEST_CASE_P( | |
| 218 ManagedModePolicyProviderTest, | |
| 219 ConfigurationPolicyProviderTest, | |
| 220 testing::Values(TestHarness::Create)); | |
| 221 | |
| 222 const char kAtomicItemName[] = "X-Wombat"; | |
| 223 const char kSplitItemName[] = "X-SuperMoosePowers"; | |
| 224 | |
| 225 class ManagedModePolicyProviderAPITest : public PolicyTestBase { | |
| 226 protected: | |
| 227 ManagedModePolicyProviderAPITest() | |
| 228 : pref_store_(new TestingPrefStore), provider_(pref_store_.get()) { | |
| 229 pref_store_->SetInitializationCompleted(); | |
| 230 } | |
| 231 virtual ~ManagedModePolicyProviderAPITest() {} | |
| 232 | |
| 233 scoped_ptr<syncer::SyncChangeProcessor> CreateSyncProcessor() { | |
| 234 sync_processor_ = new MockChangeProcessor(); | |
| 235 return scoped_ptr<syncer::SyncChangeProcessor>(sync_processor_); | |
| 236 } | |
| 237 | |
| 238 void StartSyncing(const syncer::SyncDataList& initial_sync_data) { | |
| 239 scoped_ptr<syncer::SyncErrorFactory> error_handler( | |
| 240 new MockSyncErrorFactory(syncer::MANAGED_USER_SETTINGS)); | |
| 241 syncer::SyncMergeResult result = | |
| 242 provider_.MergeDataAndStartSyncing(syncer::MANAGED_USER_SETTINGS, | |
| 243 initial_sync_data, | |
| 244 CreateSyncProcessor(), | |
| 245 error_handler.Pass()); | |
| 246 EXPECT_FALSE(result.error().IsSet()); | |
| 247 } | |
| 248 | |
| 249 void UploadSplitItem(const std::string& key, const std::string& value) { | |
| 250 dict_.SetStringWithoutPathExpansion(key, value); | |
| 251 provider_.UploadItem( | |
| 252 ManagedModePolicyProvider::MakeSplitSettingKey(kSplitItemName, key), | |
| 253 scoped_ptr<base::Value>(base::Value::CreateStringValue(value))); | |
| 254 } | |
| 255 | |
| 256 void UploadAtomicItem(const std::string& value) { | |
| 257 atomic_setting_value_.reset(new base::StringValue(value)); | |
| 258 provider_.UploadItem( | |
| 259 kAtomicItemName, | |
| 260 scoped_ptr<base::Value>(base::Value::CreateStringValue(value))); | |
| 261 } | |
| 262 | |
| 263 void VerifySyncDataItem(syncer::SyncData sync_data) { | |
| 264 const sync_pb::ManagedUserSettingSpecifics& managed_user_setting = | |
| 265 sync_data.GetSpecifics().managed_user_setting(); | |
| 266 base::Value* expected_value = NULL; | |
| 267 if (managed_user_setting.name() == kAtomicItemName) { | |
| 268 expected_value = atomic_setting_value_.get(); | |
| 269 } else { | |
| 270 EXPECT_TRUE(StartsWithASCII(managed_user_setting.name(), | |
| 271 std::string(kSplitItemName) + ':', | |
| 272 true)); | |
| 273 std::string key = | |
| 274 managed_user_setting.name().substr(strlen(kSplitItemName) + 1); | |
| 275 EXPECT_TRUE(dict_.GetWithoutPathExpansion(key, &expected_value)); | |
| 276 } | |
| 277 | |
| 278 scoped_ptr<Value> value( | |
| 279 base::JSONReader::Read(managed_user_setting.value())); | |
| 280 EXPECT_TRUE(expected_value->Equals(value.get())); | |
| 281 } | |
| 282 | |
| 283 // PolicyTestBase overrides: | |
| 284 virtual void TearDown() OVERRIDE { | |
| 285 provider_.Shutdown(); | |
| 286 PolicyTestBase::TearDown(); | |
| 287 } | |
| 288 | |
| 289 base::DictionaryValue dict_; | |
| 290 scoped_ptr<base::Value> atomic_setting_value_; | |
| 291 scoped_refptr<TestingPrefStore> pref_store_; | |
| 292 ManagedModePolicyProvider provider_; | |
| 293 | |
| 294 // Owned by the ManagedModePolicyProvider. | |
| 295 MockChangeProcessor* sync_processor_; | |
| 296 }; | |
| 297 | |
| 298 TEST_F(ManagedModePolicyProviderAPITest, UploadItem) { | |
| 299 UploadSplitItem("foo", "bar"); | |
| 300 UploadSplitItem("blurp", "baz"); | |
| 301 UploadAtomicItem("hurdle"); | |
| 302 | |
| 303 // Uploading should produce changes when we start syncing. | |
| 304 StartSyncing(syncer::SyncDataList()); | |
| 305 const syncer::SyncChangeList& changes = sync_processor_->changes(); | |
| 306 ASSERT_EQ(3u, changes.size()); | |
| 307 for (syncer::SyncChangeList::const_iterator it = changes.begin(); | |
| 308 it != changes.end(); ++it) { | |
| 309 ASSERT_TRUE(it->IsValid()); | |
| 310 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, it->change_type()); | |
| 311 VerifySyncDataItem(it->sync_data()); | |
| 312 } | |
| 313 | |
| 314 // It should also show up in local Sync data. | |
| 315 syncer::SyncDataList sync_data = | |
| 316 provider_.GetAllSyncData(syncer::MANAGED_USER_SETTINGS); | |
| 317 EXPECT_EQ(3u, sync_data.size()); | |
| 318 for (syncer::SyncDataList::const_iterator it = sync_data.begin(); | |
| 319 it != sync_data.end(); ++it) { | |
| 320 VerifySyncDataItem(*it); | |
| 321 } | |
| 322 | |
| 323 // Uploading after we have started syncing should work too. | |
| 324 UploadSplitItem("froodle", "narf"); | |
| 325 ASSERT_EQ(1u, sync_processor_->changes().size()); | |
| 326 syncer::SyncChange change = sync_processor_->changes()[0]; | |
| 327 ASSERT_TRUE(change.IsValid()); | |
| 328 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type()); | |
| 329 VerifySyncDataItem(change.sync_data()); | |
| 330 | |
| 331 sync_data = provider_.GetAllSyncData(syncer::MANAGED_USER_SETTINGS); | |
| 332 EXPECT_EQ(4u, sync_data.size()); | |
| 333 for (syncer::SyncDataList::const_iterator it = sync_data.begin(); | |
| 334 it != sync_data.end(); ++it) { | |
| 335 VerifySyncDataItem(*it); | |
| 336 } | |
| 337 | |
| 338 // Uploading an item with a previously seen key should create an UPDATE | |
| 339 // action. | |
| 340 UploadSplitItem("blurp", "snarl"); | |
| 341 ASSERT_EQ(1u, sync_processor_->changes().size()); | |
| 342 change = sync_processor_->changes()[0]; | |
| 343 ASSERT_TRUE(change.IsValid()); | |
| 344 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type()); | |
| 345 VerifySyncDataItem(change.sync_data()); | |
| 346 | |
| 347 sync_data = provider_.GetAllSyncData(syncer::MANAGED_USER_SETTINGS); | |
| 348 EXPECT_EQ(4u, sync_data.size()); | |
| 349 for (syncer::SyncDataList::const_iterator it = sync_data.begin(); | |
| 350 it != sync_data.end(); ++it) { | |
| 351 VerifySyncDataItem(*it); | |
| 352 } | |
| 353 | |
| 354 UploadAtomicItem("fjord"); | |
| 355 ASSERT_EQ(1u, sync_processor_->changes().size()); | |
| 356 change = sync_processor_->changes()[0]; | |
| 357 ASSERT_TRUE(change.IsValid()); | |
| 358 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type()); | |
| 359 VerifySyncDataItem(change.sync_data()); | |
| 360 | |
| 361 sync_data = provider_.GetAllSyncData(syncer::MANAGED_USER_SETTINGS); | |
| 362 EXPECT_EQ(4u, sync_data.size()); | |
| 363 for (syncer::SyncDataList::const_iterator it = sync_data.begin(); | |
| 364 it != sync_data.end(); ++it) { | |
| 365 VerifySyncDataItem(*it); | |
| 366 } | |
| 367 | |
| 368 // The uploaded items should not show up as policies. | |
| 369 PolicyBundle empty_bundle; | |
| 370 EXPECT_TRUE(provider_.policies().Equals(empty_bundle)); | |
| 371 | |
| 372 // Restarting sync should not create any new changes. | |
| 373 provider_.StopSyncing(syncer::MANAGED_USER_SETTINGS); | |
| 374 StartSyncing(sync_data); | |
| 375 ASSERT_EQ(0u, sync_processor_->changes().size()); | |
| 376 } | |
| 377 | |
| 378 const char kPolicyKey[] = "TestingPolicy"; | |
| 379 | |
| 380 TEST_F(ManagedModePolicyProviderAPITest, SetLocalPolicy) { | |
| 381 PolicyBundle empty_bundle; | |
| 382 EXPECT_TRUE(provider_.policies().Equals(empty_bundle)); | |
| 383 | |
| 384 base::StringValue policy_value("PolicyValue"); | |
| 385 provider_.SetLocalPolicyForTesting( | |
| 386 kPolicyKey, scoped_ptr<base::Value>(policy_value.DeepCopy())); | |
| 387 | |
| 388 PolicyBundle expected_bundle; | |
| 389 PolicyMap* policy_map = &expected_bundle.Get( | |
| 390 PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); | |
| 391 policy_map->Set(kPolicyKey, | |
| 392 POLICY_LEVEL_MANDATORY, | |
| 393 POLICY_SCOPE_USER, | |
| 394 policy_value.DeepCopy(), | |
| 395 NULL); | |
| 396 EXPECT_TRUE(provider_.policies().Equals(expected_bundle)); | |
| 397 } | |
| 398 | |
| 399 } // namespace policy | |
| OLD | NEW |