// Copyright (c) 2011 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 <algorithm> #include "base/file_util.h" #include "base/memory/scoped_temp_dir.h" #include "base/path_service.h" #include "base/string_number_conversions.h" #include "chrome/browser/policy/config_dir_policy_provider.h" #include "chrome/browser/policy/configuration_policy_pref_store.h" #include "chrome/browser/policy/mock_configuration_policy_store.h" #include "content/browser/browser_thread.h" #include "content/common/json_value_serializer.h" #include "policy/policy_constants.h" #include "testing/gtest/include/gtest/gtest.h" namespace policy { template<typename BASE> class ConfigDirPolicyProviderTestBase : public BASE { protected: ConfigDirPolicyProviderTestBase() {} virtual void SetUp() { ASSERT_TRUE(test_dir_.CreateUniqueTempDir()); } // JSON-encode a dictionary and write it to a file. void WriteConfigFile(const DictionaryValue& dict, const std::string& file_name) { std::string data; JSONStringValueSerializer serializer(&data); serializer.Serialize(dict); const FilePath file_path(test_dir().AppendASCII(file_name)); ASSERT_TRUE(file_util::WriteFile(file_path, data.c_str(), data.size())); } const FilePath& test_dir() { return test_dir_.path(); } private: ScopedTempDir test_dir_; }; class ConfigDirPolicyLoaderTest : public ConfigDirPolicyProviderTestBase<testing::Test> { }; // The preferences dictionary is expected to be empty when there are no files to // load. TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsEmpty) { ConfigDirPolicyProviderDelegate loader(test_dir()); scoped_ptr<DictionaryValue> policy(loader.Load()); EXPECT_TRUE(policy.get()); EXPECT_TRUE(policy->empty()); } // Reading from a non-existent directory should result in an empty preferences // dictionary. TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsNonExistentDirectory) { FilePath non_existent_dir(test_dir().Append(FILE_PATH_LITERAL("not_there"))); ConfigDirPolicyProviderDelegate loader(non_existent_dir); scoped_ptr<DictionaryValue> policy(loader.Load()); EXPECT_TRUE(policy.get()); EXPECT_TRUE(policy->empty()); } // Test reading back a single preference value. TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsSinglePref) { DictionaryValue test_dict; test_dict.SetString("HomepageLocation", "http://www.google.com"); WriteConfigFile(test_dict, "config_file"); ConfigDirPolicyProviderDelegate loader(test_dir()); scoped_ptr<DictionaryValue> policy(loader.Load()); EXPECT_TRUE(policy.get()); EXPECT_TRUE(policy->Equals(&test_dict)); } // Test merging values from different files. TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsMergePrefs) { // Write a bunch of data files in order to increase the chance to detect the // provider not respecting lexicographic ordering when reading them. Since the // filesystem may return files in arbitrary order, there is no way to be sure, // but this is better than nothing. DictionaryValue test_dict_bar; test_dict_bar.SetString("HomepageLocation", "http://bar.com"); for (unsigned int i = 1; i <= 4; ++i) WriteConfigFile(test_dict_bar, base::IntToString(i)); DictionaryValue test_dict_foo; test_dict_foo.SetString("HomepageLocation", "http://foo.com"); WriteConfigFile(test_dict_foo, "9"); for (unsigned int i = 5; i <= 8; ++i) WriteConfigFile(test_dict_bar, base::IntToString(i)); ConfigDirPolicyProviderDelegate loader(test_dir()); scoped_ptr<DictionaryValue> policy(loader.Load()); EXPECT_TRUE(policy.get()); EXPECT_TRUE(policy->Equals(&test_dict_foo)); } // Holds policy type, corresponding policy key string and a valid value for use // in parametrized value tests. class ValueTestParams { public: // Assumes ownership of |test_value|. ValueTestParams(ConfigurationPolicyType type, const char* policy_key, Value* test_value) : type_(type), policy_key_(policy_key), test_value_(test_value) {} // testing::TestWithParam does copying, so provide copy constructor and // assignment operator. ValueTestParams(const ValueTestParams& other) : type_(other.type_), policy_key_(other.policy_key_), test_value_(other.test_value_->DeepCopy()) {} const ValueTestParams& operator=(ValueTestParams other) { swap(other); return *this; } void swap(ValueTestParams& other) { std::swap(type_, other.type_); std::swap(policy_key_, other.policy_key_); test_value_.swap(other.test_value_); } ConfigurationPolicyType type() const { return type_; } const char* policy_key() const { return policy_key_; } const Value* test_value() const { return test_value_.get(); } // Factory methods that create parameter objects for different value types. static ValueTestParams ForStringPolicy( ConfigurationPolicyType type, const char* policy_key) { return ValueTestParams(type, policy_key, Value::CreateStringValue("test")); } static ValueTestParams ForBooleanPolicy( ConfigurationPolicyType type, const char* policy_key) { return ValueTestParams(type, policy_key, Value::CreateBooleanValue(true)); } static ValueTestParams ForIntegerPolicy( ConfigurationPolicyType type, const char* policy_key) { return ValueTestParams(type, policy_key, Value::CreateIntegerValue(42)); } static ValueTestParams ForListPolicy( ConfigurationPolicyType type, const char* policy_key) { ListValue* value = new ListValue(); value->Set(0U, Value::CreateStringValue("first")); value->Set(1U, Value::CreateStringValue("second")); return ValueTestParams(type, policy_key, value); } private: ConfigurationPolicyType type_; const char* policy_key_; scoped_ptr<Value> test_value_; }; // Tests whether the provider correctly reads a value from the file and forwards // it to the store. class ConfigDirPolicyProviderValueTest : public ConfigDirPolicyProviderTestBase< testing::TestWithParam<ValueTestParams> > { protected: ConfigDirPolicyProviderValueTest() : ui_thread_(BrowserThread::UI, &loop_), file_thread_(BrowserThread::FILE, &loop_) {} virtual void TearDown() { loop_.RunAllPending(); } MockConfigurationPolicyStore policy_store_; private: MessageLoop loop_; BrowserThread ui_thread_; BrowserThread file_thread_; }; TEST_P(ConfigDirPolicyProviderValueTest, Default) { ConfigDirPolicyProvider provider( ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(), test_dir()); EXPECT_TRUE(provider.Provide(&policy_store_)); EXPECT_TRUE(policy_store_.policy_map().empty()); } TEST_P(ConfigDirPolicyProviderValueTest, NullValue) { DictionaryValue dict; dict.Set(GetParam().policy_key(), Value::CreateNullValue()); WriteConfigFile(dict, "empty"); ConfigDirPolicyProvider provider( ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(), test_dir()); EXPECT_TRUE(provider.Provide(&policy_store_)); EXPECT_TRUE(policy_store_.policy_map().empty()); } TEST_P(ConfigDirPolicyProviderValueTest, TestValue) { DictionaryValue dict; dict.Set(GetParam().policy_key(), GetParam().test_value()->DeepCopy()); WriteConfigFile(dict, "policy"); ConfigDirPolicyProvider provider( ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(), test_dir()); EXPECT_TRUE(provider.Provide(&policy_store_)); EXPECT_EQ(1U, policy_store_.policy_map().size()); const Value* value = policy_store_.Get(GetParam().type()); ASSERT_TRUE(value); EXPECT_TRUE(GetParam().test_value()->Equals(value)); } // Test parameters for all supported policies. INSTANTIATE_TEST_CASE_P( ConfigDirPolicyProviderValueTestInstance, ConfigDirPolicyProviderValueTest, testing::Values( ValueTestParams::ForStringPolicy( kPolicyHomepageLocation, key::kHomepageLocation), ValueTestParams::ForBooleanPolicy( kPolicyHomepageIsNewTabPage, key::kHomepageIsNewTabPage), ValueTestParams::ForIntegerPolicy( kPolicyRestoreOnStartup, key::kRestoreOnStartup), ValueTestParams::ForListPolicy( kPolicyRestoreOnStartupURLs, key::kRestoreOnStartupURLs), ValueTestParams::ForBooleanPolicy( kPolicyDefaultSearchProviderEnabled, key::kDefaultSearchProviderEnabled), ValueTestParams::ForStringPolicy( kPolicyDefaultSearchProviderName, key::kDefaultSearchProviderName), ValueTestParams::ForStringPolicy( kPolicyDefaultSearchProviderKeyword, key::kDefaultSearchProviderKeyword), ValueTestParams::ForStringPolicy( kPolicyDefaultSearchProviderSearchURL, key::kDefaultSearchProviderSearchURL), ValueTestParams::ForStringPolicy( kPolicyDefaultSearchProviderSuggestURL, key::kDefaultSearchProviderSuggestURL), ValueTestParams::ForStringPolicy( kPolicyDefaultSearchProviderInstantURL, key::kDefaultSearchProviderInstantURL), ValueTestParams::ForStringPolicy( kPolicyDefaultSearchProviderIconURL, key::kDefaultSearchProviderIconURL), ValueTestParams::ForStringPolicy( kPolicyDefaultSearchProviderEncodings, key::kDefaultSearchProviderEncodings), ValueTestParams::ForStringPolicy( kPolicyProxyMode, key::kProxyMode), ValueTestParams::ForIntegerPolicy( kPolicyProxyServerMode, key::kProxyServerMode), ValueTestParams::ForStringPolicy( kPolicyProxyServer, key::kProxyServer), ValueTestParams::ForStringPolicy( kPolicyProxyPacUrl, key::kProxyPacUrl), ValueTestParams::ForStringPolicy( kPolicyProxyBypassList, key::kProxyBypassList), ValueTestParams::ForBooleanPolicy( kPolicyAlternateErrorPagesEnabled, key::kAlternateErrorPagesEnabled), ValueTestParams::ForBooleanPolicy( kPolicySearchSuggestEnabled, key::kSearchSuggestEnabled), ValueTestParams::ForBooleanPolicy( kPolicyDnsPrefetchingEnabled, key::kDnsPrefetchingEnabled), ValueTestParams::ForBooleanPolicy( kPolicySafeBrowsingEnabled, key::kSafeBrowsingEnabled), ValueTestParams::ForBooleanPolicy( kPolicyMetricsReportingEnabled, key::kMetricsReportingEnabled), ValueTestParams::ForBooleanPolicy( kPolicyPasswordManagerEnabled, key::kPasswordManagerEnabled), ValueTestParams::ForBooleanPolicy( kPolicyPasswordManagerAllowShowPasswords, key::kPasswordManagerAllowShowPasswords), ValueTestParams::ForListPolicy( kPolicyDisabledPlugins, key::kDisabledPlugins), ValueTestParams::ForListPolicy( kPolicyDisabledPluginsExceptions, key::kDisabledPluginsExceptions), ValueTestParams::ForListPolicy( kPolicyEnabledPlugins, key::kEnabledPlugins), ValueTestParams::ForBooleanPolicy( kPolicyAutoFillEnabled, key::kAutoFillEnabled), ValueTestParams::ForStringPolicy( kPolicyApplicationLocaleValue, key::kApplicationLocaleValue), ValueTestParams::ForBooleanPolicy( kPolicySyncDisabled, key::kSyncDisabled), ValueTestParams::ForListPolicy( kPolicyExtensionInstallWhitelist, key::kExtensionInstallWhitelist), ValueTestParams::ForListPolicy( kPolicyExtensionInstallBlacklist, key::kExtensionInstallBlacklist), ValueTestParams::ForBooleanPolicy( kPolicyShowHomeButton, key::kShowHomeButton), ValueTestParams::ForBooleanPolicy( kPolicyPrintingEnabled, key::kPrintingEnabled), ValueTestParams::ForIntegerPolicy( kPolicyPolicyRefreshRate, key::kPolicyRefreshRate), ValueTestParams::ForBooleanPolicy( kPolicyInstantEnabled, key::kInstantEnabled), ValueTestParams::ForBooleanPolicy( kPolicyIncognitoEnabled, key::kIncognitoEnabled), ValueTestParams::ForBooleanPolicy( kPolicyDisablePluginFinder, key::kDisablePluginFinder), ValueTestParams::ForBooleanPolicy( kPolicyClearSiteDataOnExit, key::kClearSiteDataOnExit), ValueTestParams::ForStringPolicy( kPolicyDownloadDirectory, key::kDownloadDirectory), ValueTestParams::ForBooleanPolicy( kPolicyDefaultBrowserSettingEnabled, key::kDefaultBrowserSettingEnabled), ValueTestParams::ForBooleanPolicy( kPolicyCloudPrintProxyEnabled, key::kCloudPrintProxyEnabled), ValueTestParams::ForBooleanPolicy( kPolicyTranslateEnabled, key::kTranslateEnabled), ValueTestParams::ForBooleanPolicy( kPolicyAllowOutdatedPlugins, key::kAllowOutdatedPlugins), ValueTestParams::ForBooleanPolicy( kPolicyBookmarkBarEnabled, key::kBookmarkBarEnabled), ValueTestParams::ForBooleanPolicy( kPolicyEditBookmarksEnabled, key::kEditBookmarksEnabled), ValueTestParams::ForListPolicy( kPolicyDisabledSchemes, key::kDisabledSchemes))); } // namespace policy