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 |