diff options
Diffstat (limited to 'chrome/browser/policy/policy_loader_mac_unittest.cc')
| -rw-r--r-- | chrome/browser/policy/policy_loader_mac_unittest.cc | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/chrome/browser/policy/policy_loader_mac_unittest.cc b/chrome/browser/policy/policy_loader_mac_unittest.cc new file mode 100644 index 0000000..51a31c8 --- /dev/null +++ b/chrome/browser/policy/policy_loader_mac_unittest.cc @@ -0,0 +1,321 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <CoreFoundation/CoreFoundation.h> + +#include "base/basictypes.h" +#include "base/mac/scoped_cftyperef.h" +#include "base/sys_string_conversions.h" +#include "base/values.h" +#include "chrome/browser/policy/async_policy_provider.h" +#include "chrome/browser/policy/configuration_policy_provider_test.h" +#include "chrome/browser/policy/policy_bundle.h" +#include "chrome/browser/policy/policy_loader_mac.h" +#include "chrome/browser/policy/policy_map.h" +#include "chrome/browser/preferences_mock_mac.h" +#include "policy/policy_constants.h" +#include "testing/gtest/include/gtest/gtest.h" + +using base::mac::ScopedCFTypeRef; + +namespace policy { + +namespace { + +// Converts a base::Value to the equivalent CFPropertyListRef. +// The returned value is owned by the caller. +CFPropertyListRef CreatePropertyFromValue(const base::Value* value) { + switch (value->GetType()) { + case base::Value::TYPE_NULL: + return kCFNull; + + case base::Value::TYPE_BOOLEAN: { + bool bool_value; + if (value->GetAsBoolean(&bool_value)) + return bool_value ? kCFBooleanTrue : kCFBooleanFalse; + break; + } + + case base::Value::TYPE_INTEGER: { + int int_value; + if (value->GetAsInteger(&int_value)) { + return CFNumberCreate( + kCFAllocatorDefault, kCFNumberIntType, &int_value); + } + break; + } + + case base::Value::TYPE_DOUBLE: { + double double_value; + if (value->GetAsDouble(&double_value)) { + return CFNumberCreate( + kCFAllocatorDefault, kCFNumberDoubleType, &double_value); + } + break; + } + + case base::Value::TYPE_STRING: { + std::string string_value; + if (value->GetAsString(&string_value)) + return base::SysUTF8ToCFStringRef(string_value); + break; + } + + case base::Value::TYPE_DICTIONARY: { + const base::DictionaryValue* dict_value; + if (value->GetAsDictionary(&dict_value)) { + // |dict| is owned by the caller. + CFMutableDictionaryRef dict = + CFDictionaryCreateMutable(kCFAllocatorDefault, + dict_value->size(), + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + for (base::DictionaryValue::Iterator iterator(*dict_value); + iterator.HasNext(); iterator.Advance()) { + // CFDictionaryAddValue() retains both |key| and |value|, so make sure + // the references are balanced. + ScopedCFTypeRef<CFStringRef> key( + base::SysUTF8ToCFStringRef(iterator.key())); + ScopedCFTypeRef<CFPropertyListRef> cf_value( + CreatePropertyFromValue(&iterator.value())); + if (cf_value) + CFDictionaryAddValue(dict, key, cf_value); + } + return dict; + } + break; + } + + case base::Value::TYPE_LIST: { + const base::ListValue* list; + if (value->GetAsList(&list)) { + CFMutableArrayRef array = + CFArrayCreateMutable(NULL, list->GetSize(), &kCFTypeArrayCallBacks); + for (base::ListValue::const_iterator it(list->begin()); + it != list->end(); ++it) { + // CFArrayAppendValue() retains |value|, so make sure the reference + // created by CreatePropertyFromValue() is released. + ScopedCFTypeRef<CFPropertyListRef> cf_value( + CreatePropertyFromValue(*it)); + if (cf_value) + CFArrayAppendValue(array, cf_value); + } + return array; + } + break; + } + + case base::Value::TYPE_BINARY: + // This type isn't converted (though it can be represented as CFData) + // because there's no equivalent JSON type, and policy values can only + // take valid JSON values. + break; + } + + return NULL; +} + +class TestHarness : public PolicyProviderTestHarness { + public: + TestHarness(); + virtual ~TestHarness(); + + virtual void SetUp() OVERRIDE; + + virtual ConfigurationPolicyProvider* CreateProvider( + const PolicyDefinitionList* policy_definition_list) OVERRIDE; + + virtual void InstallEmptyPolicy() OVERRIDE; + virtual void InstallStringPolicy(const std::string& policy_name, + const std::string& policy_value) OVERRIDE; + virtual void InstallIntegerPolicy(const std::string& policy_name, + int policy_value) OVERRIDE; + virtual void InstallBooleanPolicy(const std::string& policy_name, + bool policy_value) OVERRIDE; + virtual void InstallStringListPolicy( + const std::string& policy_name, + const base::ListValue* policy_value) OVERRIDE; + virtual void InstallDictionaryPolicy( + const std::string& policy_name, + const base::DictionaryValue* policy_value) OVERRIDE; + + static PolicyProviderTestHarness* Create(); + + private: + MockPreferences* prefs_; + + DISALLOW_COPY_AND_ASSIGN(TestHarness); +}; + +TestHarness::TestHarness() + : PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER) {} + +TestHarness::~TestHarness() {} + +void TestHarness::SetUp() {} + +ConfigurationPolicyProvider* TestHarness::CreateProvider( + const PolicyDefinitionList* policy_definition_list) { + prefs_ = new MockPreferences(); + scoped_ptr<AsyncPolicyLoader> loader( + new PolicyLoaderMac(policy_definition_list, prefs_)); + return new AsyncPolicyProvider(policy_definition_list, loader.Pass()); +} + +void TestHarness::InstallEmptyPolicy() {} + +void TestHarness::InstallStringPolicy(const std::string& policy_name, + const std::string& policy_value) { + ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name)); + ScopedCFTypeRef<CFStringRef> value(base::SysUTF8ToCFStringRef(policy_value)); + prefs_->AddTestItem(name, value, true); +} + +void TestHarness::InstallIntegerPolicy(const std::string& policy_name, + int policy_value) { + ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name)); + ScopedCFTypeRef<CFNumberRef> value( + CFNumberCreate(NULL, kCFNumberIntType, &policy_value)); + prefs_->AddTestItem(name, value, true); +} + +void TestHarness::InstallBooleanPolicy(const std::string& policy_name, + bool policy_value) { + ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name)); + prefs_->AddTestItem(name, + policy_value ? kCFBooleanTrue : kCFBooleanFalse, + true); +} + +void TestHarness::InstallStringListPolicy(const std::string& policy_name, + const base::ListValue* policy_value) { + ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name)); + ScopedCFTypeRef<CFPropertyListRef> array( + CreatePropertyFromValue(policy_value)); + ASSERT_TRUE(array); + prefs_->AddTestItem(name, array, true); +} + +void TestHarness::InstallDictionaryPolicy( + const std::string& policy_name, + const base::DictionaryValue* policy_value) { + ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name)); + ScopedCFTypeRef<CFPropertyListRef> dict( + CreatePropertyFromValue(policy_value)); + ASSERT_TRUE(dict); + prefs_->AddTestItem(name, dict, true); +} + +// static +PolicyProviderTestHarness* TestHarness::Create() { + return new TestHarness(); +} + +} // namespace + +// Instantiate abstract test case for basic policy reading tests. +INSTANTIATE_TEST_CASE_P( + PolicyProviderMacTest, + ConfigurationPolicyProviderTest, + testing::Values(TestHarness::Create)); + +// Special test cases for some mac preferences details. +class PolicyLoaderMacTest : public PolicyTestBase { + protected: + PolicyLoaderMacTest() + : prefs_(new MockPreferences()), + loader_(new PolicyLoaderMac(&test_policy_definitions::kList, prefs_)), + provider_(&test_policy_definitions::kList, + scoped_ptr<AsyncPolicyLoader>(loader_)) {} + virtual ~PolicyLoaderMacTest() {} + + MockPreferences* prefs_; + PolicyLoaderMac* loader_; + AsyncPolicyProvider provider_; +}; + +TEST_F(PolicyLoaderMacTest, Invalid) { + ScopedCFTypeRef<CFStringRef> name( + base::SysUTF8ToCFStringRef(test_policy_definitions::kKeyString)); + const char buffer[] = "binary \xde\xad\xbe\xef data"; + ScopedCFTypeRef<CFDataRef> invalid_data( + CFDataCreate(kCFAllocatorDefault, + reinterpret_cast<const UInt8 *>(buffer), + arraysize(buffer))); + ASSERT_TRUE(invalid_data); + prefs_->AddTestItem(name, invalid_data.get(), true); + prefs_->AddTestItem(name, invalid_data.get(), false); + + // Make the provider read the updated |prefs_|. + provider_.RefreshPolicies(); + loop_.RunAllPending(); + const PolicyBundle kEmptyBundle; + EXPECT_TRUE(provider_.policies().Equals(kEmptyBundle)); +} + +TEST_F(PolicyLoaderMacTest, TestNonForcedValue) { + ScopedCFTypeRef<CFStringRef> name( + base::SysUTF8ToCFStringRef(test_policy_definitions::kKeyString)); + ScopedCFTypeRef<CFPropertyListRef> test_value( + base::SysUTF8ToCFStringRef("string value")); + ASSERT_TRUE(test_value.get()); + prefs_->AddTestItem(name, test_value.get(), false); + + // Make the provider read the updated |prefs_|. + provider_.RefreshPolicies(); + loop_.RunAllPending(); + PolicyBundle expected_bundle; + expected_bundle.Get(POLICY_DOMAIN_CHROME, "") + .Set(test_policy_definitions::kKeyString, POLICY_LEVEL_RECOMMENDED, + POLICY_SCOPE_USER, base::Value::CreateStringValue("string value")); + EXPECT_TRUE(provider_.policies().Equals(expected_bundle)); +} + +TEST_F(PolicyLoaderMacTest, TestConversions) { + base::DictionaryValue root; + + // base::Value::TYPE_NULL + root.Set("null", base::Value::CreateNullValue()); + + // base::Value::TYPE_BOOLEAN + root.SetBoolean("false", false); + root.SetBoolean("true", true); + + // base::Value::TYPE_INTEGER + root.SetInteger("int", 123); + root.SetInteger("zero", 0); + + // base::Value::TYPE_DOUBLE + root.SetDouble("double", 123.456); + root.SetDouble("zerod", 0.0); + + // base::Value::TYPE_STRING + root.SetString("string", "the fox jumps over something"); + root.SetString("empty", ""); + + // base::Value::TYPE_LIST + base::ListValue list; + root.Set("emptyl", list.DeepCopy()); + for (base::DictionaryValue::Iterator it(root); it.HasNext(); it.Advance()) + list.Append(it.value().DeepCopy()); + EXPECT_EQ(root.size(), list.GetSize()); + list.Append(root.DeepCopy()); + root.Set("list", list.DeepCopy()); + + // base::Value::TYPE_DICTIONARY + base::DictionaryValue dict; + root.Set("emptyd", dict.DeepCopy()); + // Very meta. + root.Set("dict", root.DeepCopy()); + + ScopedCFTypeRef<CFPropertyListRef> property(CreatePropertyFromValue(&root)); + ASSERT_TRUE(property); + scoped_ptr<base::Value> value( + PolicyLoaderMac::CreateValueFromProperty(property)); + ASSERT_TRUE(value.get()); + + EXPECT_TRUE(root.Equals(value.get())); +} + +} // namespace policy |
