Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / policy / core / common / configuration_policy_provider_test.cc
bloba9d2ecb4c330bb200215ec804c33d621f0a25575
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.
5 #include "components/policy/core/common/configuration_policy_provider_test.h"
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/values.h"
10 #include "components/policy/core/common/configuration_policy_provider.h"
11 #include "components/policy/core/common/external_data_fetcher.h"
12 #include "components/policy/core/common/mock_configuration_policy_provider.h"
13 #include "components/policy/core/common/policy_bundle.h"
14 #include "components/policy/core/common/policy_map.h"
15 #include "components/policy/core/common/policy_namespace.h"
16 #include "components/policy/core/common/policy_types.h"
17 #include "testing/gmock/include/gmock/gmock.h"
19 using ::testing::Mock;
20 using ::testing::_;
22 namespace policy {
24 const char kTestChromeSchema[] =
25 "{"
26 " \"type\": \"object\","
27 " \"properties\": {"
28 " \"StringPolicy\": { \"type\": \"string\" },"
29 " \"BooleanPolicy\": { \"type\": \"boolean\" },"
30 " \"IntegerPolicy\": { \"type\": \"integer\" },"
31 " \"StringListPolicy\": {"
32 " \"type\": \"array\","
33 " \"items\": { \"type\": \"string\" }"
34 " },"
35 " \"DictionaryPolicy\": {"
36 " \"type\": \"object\","
37 " \"properties\": {"
38 " \"bool\": { \"type\": \"boolean\" },"
39 " \"double\": { \"type\": \"number\" },"
40 " \"int\": { \"type\": \"integer\" },"
41 " \"string\": { \"type\": \"string\" },"
42 " \"array\": {"
43 " \"type\": \"array\","
44 " \"items\": { \"type\": \"string\" }"
45 " },"
46 " \"dictionary\": {"
47 " \"type\": \"object\","
48 " \"properties\": {"
49 " \"sub\": { \"type\": \"string\" },"
50 " \"sublist\": {"
51 " \"type\": \"array\","
52 " \"items\": {"
53 " \"type\": \"object\","
54 " \"properties\": {"
55 " \"aaa\": { \"type\": \"integer\" },"
56 " \"bbb\": { \"type\": \"integer\" },"
57 " \"ccc\": { \"type\": \"string\" },"
58 " \"ddd\": { \"type\": \"string\" }"
59 " }"
60 " }"
61 " }"
62 " }"
63 " },"
64 " \"list\": {"
65 " \"type\": \"array\","
66 " \"items\": {"
67 " \"type\": \"object\","
68 " \"properties\": {"
69 " \"subdictindex\": { \"type\": \"integer\" },"
70 " \"subdict\": {"
71 " \"type\": \"object\","
72 " \"properties\": {"
73 " \"bool\": { \"type\": \"boolean\" },"
74 " \"double\": { \"type\": \"number\" },"
75 " \"int\": { \"type\": \"integer\" },"
76 " \"string\": { \"type\": \"string\" }"
77 " }"
78 " }"
79 " }"
80 " }"
81 " },"
82 " \"dict\": {"
83 " \"type\": \"object\","
84 " \"properties\": {"
85 " \"bool\": { \"type\": \"boolean\" },"
86 " \"double\": { \"type\": \"number\" },"
87 " \"int\": { \"type\": \"integer\" },"
88 " \"string\": { \"type\": \"string\" },"
89 " \"list\": {"
90 " \"type\": \"array\","
91 " \"items\": {"
92 " \"type\": \"object\","
93 " \"properties\": {"
94 " \"subdictindex\": { \"type\": \"integer\" },"
95 " \"subdict\": {"
96 " \"type\": \"object\","
97 " \"properties\": {"
98 " \"bool\": { \"type\": \"boolean\" },"
99 " \"double\": { \"type\": \"number\" },"
100 " \"int\": { \"type\": \"integer\" },"
101 " \"string\": { \"type\": \"string\" }"
102 " }"
103 " }"
104 " }"
105 " }"
106 " }"
107 " }"
108 " }"
109 " }"
110 " }"
111 " }"
112 "}";
114 namespace test_keys {
116 const char kKeyString[] = "StringPolicy";
117 const char kKeyBoolean[] = "BooleanPolicy";
118 const char kKeyInteger[] = "IntegerPolicy";
119 const char kKeyStringList[] = "StringListPolicy";
120 const char kKeyDictionary[] = "DictionaryPolicy";
122 } // namespace test_keys
124 PolicyTestBase::PolicyTestBase() {}
126 PolicyTestBase::~PolicyTestBase() {}
128 void PolicyTestBase::SetUp() {
129 const PolicyNamespace ns(POLICY_DOMAIN_CHROME, "");
130 ASSERT_TRUE(RegisterSchema(ns, kTestChromeSchema));
133 void PolicyTestBase::TearDown() {
134 loop_.RunUntilIdle();
137 bool PolicyTestBase::RegisterSchema(const PolicyNamespace& ns,
138 const std::string& schema_string) {
139 std::string error;
140 Schema schema = Schema::Parse(schema_string, &error);
141 if (schema.valid()) {
142 schema_registry_.RegisterComponent(ns, schema);
143 return true;
145 ADD_FAILURE() << error;
146 return false;
149 PolicyProviderTestHarness::PolicyProviderTestHarness(PolicyLevel level,
150 PolicyScope scope,
151 PolicySource source)
152 : level_(level), scope_(scope), source_(source) {}
154 PolicyProviderTestHarness::~PolicyProviderTestHarness() {}
156 PolicyLevel PolicyProviderTestHarness::policy_level() const {
157 return level_;
160 PolicyScope PolicyProviderTestHarness::policy_scope() const {
161 return scope_;
164 PolicySource PolicyProviderTestHarness::policy_source() const {
165 return source_;
168 void PolicyProviderTestHarness::Install3rdPartyPolicy(
169 const base::DictionaryValue* policies) {
170 FAIL();
173 ConfigurationPolicyProviderTest::ConfigurationPolicyProviderTest() {}
175 ConfigurationPolicyProviderTest::~ConfigurationPolicyProviderTest() {}
177 void ConfigurationPolicyProviderTest::SetUp() {
178 PolicyTestBase::SetUp();
180 test_harness_.reset((*GetParam())());
181 test_harness_->SetUp();
183 const PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, "");
184 Schema chrome_schema = *schema_registry_.schema_map()->GetSchema(chrome_ns);
185 Schema extension_schema =
186 chrome_schema.GetKnownProperty(test_keys::kKeyDictionary);
187 ASSERT_TRUE(extension_schema.valid());
188 schema_registry_.RegisterComponent(
189 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS,
190 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
191 extension_schema);
192 schema_registry_.RegisterComponent(
193 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS,
194 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"),
195 extension_schema);
196 schema_registry_.RegisterComponent(
197 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS,
198 "cccccccccccccccccccccccccccccccc"),
199 extension_schema);
201 provider_.reset(
202 test_harness_->CreateProvider(&schema_registry_, loop_.task_runner()));
203 provider_->Init(&schema_registry_);
204 // Some providers do a reload on init. Make sure any notifications generated
205 // are fired now.
206 loop_.RunUntilIdle();
208 const PolicyBundle kEmptyBundle;
209 EXPECT_TRUE(provider_->policies().Equals(kEmptyBundle));
212 void ConfigurationPolicyProviderTest::TearDown() {
213 // Give providers the chance to clean up after themselves on the file thread.
214 provider_->Shutdown();
215 provider_.reset();
217 PolicyTestBase::TearDown();
220 void ConfigurationPolicyProviderTest::CheckValue(
221 const char* policy_name,
222 const base::Value& expected_value,
223 base::Closure install_value) {
224 // Install the value, reload policy and check the provider for the value.
225 install_value.Run();
226 provider_->RefreshPolicies();
227 loop_.RunUntilIdle();
228 PolicyBundle expected_bundle;
229 expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
230 .Set(policy_name,
231 test_harness_->policy_level(),
232 test_harness_->policy_scope(),
233 test_harness_->policy_source(),
234 expected_value.DeepCopy(),
235 NULL);
236 EXPECT_TRUE(provider_->policies().Equals(expected_bundle));
237 // TODO(joaodasilva): set the policy in the POLICY_DOMAIN_EXTENSIONS too,
238 // and extend the |expected_bundle|, once all providers are ready.
241 TEST_P(ConfigurationPolicyProviderTest, Empty) {
242 provider_->RefreshPolicies();
243 loop_.RunUntilIdle();
244 const PolicyBundle kEmptyBundle;
245 EXPECT_TRUE(provider_->policies().Equals(kEmptyBundle));
248 TEST_P(ConfigurationPolicyProviderTest, StringValue) {
249 const char kTestString[] = "string_value";
250 base::StringValue expected_value(kTestString);
251 CheckValue(test_keys::kKeyString,
252 expected_value,
253 base::Bind(&PolicyProviderTestHarness::InstallStringPolicy,
254 base::Unretained(test_harness_.get()),
255 test_keys::kKeyString,
256 kTestString));
259 TEST_P(ConfigurationPolicyProviderTest, BooleanValue) {
260 base::FundamentalValue expected_value(true);
261 CheckValue(test_keys::kKeyBoolean,
262 expected_value,
263 base::Bind(&PolicyProviderTestHarness::InstallBooleanPolicy,
264 base::Unretained(test_harness_.get()),
265 test_keys::kKeyBoolean,
266 true));
269 TEST_P(ConfigurationPolicyProviderTest, IntegerValue) {
270 base::FundamentalValue expected_value(42);
271 CheckValue(test_keys::kKeyInteger,
272 expected_value,
273 base::Bind(&PolicyProviderTestHarness::InstallIntegerPolicy,
274 base::Unretained(test_harness_.get()),
275 test_keys::kKeyInteger,
276 42));
279 TEST_P(ConfigurationPolicyProviderTest, StringListValue) {
280 base::ListValue expected_value;
281 expected_value.Set(0U, new base::StringValue("first"));
282 expected_value.Set(1U, new base::StringValue("second"));
283 CheckValue(test_keys::kKeyStringList,
284 expected_value,
285 base::Bind(&PolicyProviderTestHarness::InstallStringListPolicy,
286 base::Unretained(test_harness_.get()),
287 test_keys::kKeyStringList,
288 &expected_value));
291 TEST_P(ConfigurationPolicyProviderTest, DictionaryValue) {
292 base::DictionaryValue expected_value;
293 expected_value.SetBoolean("bool", true);
294 expected_value.SetDouble("double", 123.456);
295 expected_value.SetInteger("int", 123);
296 expected_value.SetString("string", "omg");
298 base::ListValue* list = new base::ListValue();
299 list->Set(0U, new base::StringValue("first"));
300 list->Set(1U, new base::StringValue("second"));
301 expected_value.Set("array", list);
303 base::DictionaryValue* dict = new base::DictionaryValue();
304 dict->SetString("sub", "value");
305 list = new base::ListValue();
306 base::DictionaryValue* sub = new base::DictionaryValue();
307 sub->SetInteger("aaa", 111);
308 sub->SetInteger("bbb", 222);
309 list->Append(sub);
310 sub = new base::DictionaryValue();
311 sub->SetString("ccc", "333");
312 sub->SetString("ddd", "444");
313 list->Append(sub);
314 dict->Set("sublist", list);
315 expected_value.Set("dictionary", dict);
317 CheckValue(test_keys::kKeyDictionary,
318 expected_value,
319 base::Bind(&PolicyProviderTestHarness::InstallDictionaryPolicy,
320 base::Unretained(test_harness_.get()),
321 test_keys::kKeyDictionary,
322 &expected_value));
325 TEST_P(ConfigurationPolicyProviderTest, RefreshPolicies) {
326 PolicyBundle bundle;
327 EXPECT_TRUE(provider_->policies().Equals(bundle));
329 // OnUpdatePolicy is called even when there are no changes.
330 MockConfigurationPolicyObserver observer;
331 provider_->AddObserver(&observer);
332 EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1);
333 provider_->RefreshPolicies();
334 loop_.RunUntilIdle();
335 Mock::VerifyAndClearExpectations(&observer);
337 EXPECT_TRUE(provider_->policies().Equals(bundle));
339 // OnUpdatePolicy is called when there are changes.
340 test_harness_->InstallStringPolicy(test_keys::kKeyString, "value");
341 EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1);
342 provider_->RefreshPolicies();
343 loop_.RunUntilIdle();
344 Mock::VerifyAndClearExpectations(&observer);
346 bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
347 .Set(test_keys::kKeyString,
348 test_harness_->policy_level(),
349 test_harness_->policy_scope(),
350 test_harness_->policy_source(),
351 new base::StringValue("value"),
352 NULL);
353 EXPECT_TRUE(provider_->policies().Equals(bundle));
354 provider_->RemoveObserver(&observer);
357 Configuration3rdPartyPolicyProviderTest::
358 Configuration3rdPartyPolicyProviderTest() {}
360 Configuration3rdPartyPolicyProviderTest::
361 ~Configuration3rdPartyPolicyProviderTest() {}
363 TEST_P(Configuration3rdPartyPolicyProviderTest, Load3rdParty) {
364 base::DictionaryValue policy_dict;
365 policy_dict.SetBoolean("bool", true);
366 policy_dict.SetDouble("double", 123.456);
367 policy_dict.SetInteger("int", 789);
368 policy_dict.SetString("string", "string value");
370 base::ListValue* list = new base::ListValue();
371 for (int i = 0; i < 2; ++i) {
372 base::DictionaryValue* dict = new base::DictionaryValue();
373 dict->SetInteger("subdictindex", i);
374 dict->Set("subdict", policy_dict.DeepCopy());
375 list->Append(dict);
377 policy_dict.Set("list", list);
378 policy_dict.Set("dict", policy_dict.DeepCopy());
380 // Install these policies as a Chrome policy.
381 test_harness_->InstallDictionaryPolicy(test_keys::kKeyDictionary,
382 &policy_dict);
383 // Install them as 3rd party policies too.
384 base::DictionaryValue policy_3rdparty;
385 policy_3rdparty.Set("extensions.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
386 policy_dict.DeepCopy());
387 policy_3rdparty.Set("extensions.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
388 policy_dict.DeepCopy());
389 // Install invalid 3rd party policies that shouldn't be loaded. These also
390 // help detecting memory leaks in the code paths that detect invalid input.
391 policy_3rdparty.Set("invalid-domain.component", policy_dict.DeepCopy());
392 policy_3rdparty.Set("extensions.cccccccccccccccccccccccccccccccc",
393 new base::StringValue("invalid-value"));
394 test_harness_->Install3rdPartyPolicy(&policy_3rdparty);
396 provider_->RefreshPolicies();
397 loop_.RunUntilIdle();
399 PolicyMap expected_policy;
400 expected_policy.Set(test_keys::kKeyDictionary,
401 test_harness_->policy_level(),
402 test_harness_->policy_scope(),
403 test_harness_->policy_source(),
404 policy_dict.DeepCopy(),
405 NULL);
406 PolicyBundle expected_bundle;
407 expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
408 .CopyFrom(expected_policy);
409 expected_policy.Clear();
410 expected_policy.LoadFrom(&policy_dict,
411 test_harness_->policy_level(),
412 test_harness_->policy_scope(),
413 test_harness_->policy_source());
414 expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS,
415 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
416 .CopyFrom(expected_policy);
417 expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS,
418 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"))
419 .CopyFrom(expected_policy);
420 EXPECT_TRUE(provider_->policies().Equals(expected_bundle));
423 } // namespace policy