Home | History | Annotate | Download | only in prefs
      1 // Copyright (c) 2011 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 <string>
      6 
      7 #include "app/test/data/resource.h"
      8 #include "base/command_line.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/values.h"
     11 #include "chrome/browser/policy/configuration_policy_pref_store.h"
     12 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
     13 #include "chrome/browser/prefs/browser_prefs.h"
     14 #include "chrome/browser/prefs/command_line_pref_store.h"
     15 #include "chrome/browser/prefs/pref_change_registrar.h"
     16 #include "chrome/browser/prefs/pref_observer_mock.h"
     17 #include "chrome/browser/prefs/pref_service_mock_builder.h"
     18 #include "chrome/browser/prefs/pref_value_store.h"
     19 #include "chrome/browser/prefs/proxy_config_dictionary.h"
     20 #include "chrome/browser/prefs/testing_pref_store.h"
     21 #include "chrome/common/chrome_paths.h"
     22 #include "chrome/common/chrome_switches.h"
     23 #include "chrome/common/pref_names.h"
     24 #include "chrome/test/testing_pref_service.h"
     25 #include "testing/gmock/include/gmock/gmock.h"
     26 #include "testing/gtest/include/gtest/gtest.h"
     27 
     28 using testing::_;
     29 using testing::Mock;
     30 
     31 // TODO(port): port this test to POSIX.
     32 #if defined(OS_WIN)
     33 TEST(PrefServiceTest, LocalizedPrefs) {
     34   TestingPrefService prefs;
     35   const char kBoolean[] = "boolean";
     36   const char kInteger[] = "integer";
     37   const char kString[] = "string";
     38   prefs.RegisterLocalizedBooleanPref(kBoolean, IDS_LOCALE_BOOL);
     39   prefs.RegisterLocalizedIntegerPref(kInteger, IDS_LOCALE_INT);
     40   prefs.RegisterLocalizedStringPref(kString, IDS_LOCALE_STRING);
     41 
     42   // The locale default should take preference over the user default.
     43   EXPECT_FALSE(prefs.GetBoolean(kBoolean));
     44   EXPECT_EQ(1, prefs.GetInteger(kInteger));
     45   EXPECT_EQ("hello", prefs.GetString(kString));
     46 
     47   prefs.SetBoolean(kBoolean, true);
     48   EXPECT_TRUE(prefs.GetBoolean(kBoolean));
     49   prefs.SetInteger(kInteger, 5);
     50   EXPECT_EQ(5, prefs.GetInteger(kInteger));
     51   prefs.SetString(kString, "foo");
     52   EXPECT_EQ("foo", prefs.GetString(kString));
     53 }
     54 #endif
     55 
     56 TEST(PrefServiceTest, NoObserverFire) {
     57   TestingPrefService prefs;
     58 
     59   const char pref_name[] = "homepage";
     60   prefs.RegisterStringPref(pref_name, std::string());
     61 
     62   const char new_pref_value[] = "http://www.google.com/";
     63   PrefObserverMock obs;
     64   PrefChangeRegistrar registrar;
     65   registrar.Init(&prefs);
     66   registrar.Add(pref_name, &obs);
     67 
     68   // This should fire the checks in PrefObserverMock::Observe.
     69   const StringValue expected_value(new_pref_value);
     70   obs.Expect(&prefs, pref_name, &expected_value);
     71   prefs.SetString(pref_name, new_pref_value);
     72   Mock::VerifyAndClearExpectations(&obs);
     73 
     74   // Setting the pref to the same value should not set the pref value a second
     75   // time.
     76   EXPECT_CALL(obs, Observe(_, _, _)).Times(0);
     77   prefs.SetString(pref_name, new_pref_value);
     78   Mock::VerifyAndClearExpectations(&obs);
     79 
     80   // Clearing the pref should cause the pref to fire.
     81   const StringValue expected_default_value("");
     82   obs.Expect(&prefs, pref_name, &expected_default_value);
     83   prefs.ClearPref(pref_name);
     84   Mock::VerifyAndClearExpectations(&obs);
     85 
     86   // Clearing the pref again should not cause the pref to fire.
     87   EXPECT_CALL(obs, Observe(_, _, _)).Times(0);
     88   prefs.ClearPref(pref_name);
     89   Mock::VerifyAndClearExpectations(&obs);
     90 }
     91 
     92 TEST(PrefServiceTest, HasPrefPath) {
     93   TestingPrefService prefs;
     94 
     95   const char path[] = "fake.path";
     96 
     97   // Shouldn't initially have a path.
     98   EXPECT_FALSE(prefs.HasPrefPath(path));
     99 
    100   // Register the path. This doesn't set a value, so the path still shouldn't
    101   // exist.
    102   prefs.RegisterStringPref(path, std::string());
    103   EXPECT_FALSE(prefs.HasPrefPath(path));
    104 
    105   // Set a value and make sure we have a path.
    106   prefs.SetString(path, "blah");
    107   EXPECT_TRUE(prefs.HasPrefPath(path));
    108 }
    109 
    110 TEST(PrefServiceTest, Observers) {
    111   const char pref_name[] = "homepage";
    112 
    113   TestingPrefService prefs;
    114   prefs.SetUserPref(pref_name, Value::CreateStringValue("http://www.cnn.com"));
    115   prefs.RegisterStringPref(pref_name, std::string());
    116 
    117   const char new_pref_value[] = "http://www.google.com/";
    118   const StringValue expected_new_pref_value(new_pref_value);
    119   PrefObserverMock obs;
    120   PrefChangeRegistrar registrar;
    121   registrar.Init(&prefs);
    122   registrar.Add(pref_name, &obs);
    123 
    124   // This should fire the checks in PrefObserverMock::Observe.
    125   obs.Expect(&prefs, pref_name, &expected_new_pref_value);
    126   prefs.SetString(pref_name, new_pref_value);
    127   Mock::VerifyAndClearExpectations(&obs);
    128 
    129   // Now try adding a second pref observer.
    130   const char new_pref_value2[] = "http://www.youtube.com/";
    131   const StringValue expected_new_pref_value2(new_pref_value2);
    132   PrefObserverMock obs2;
    133   obs.Expect(&prefs, pref_name, &expected_new_pref_value2);
    134   obs2.Expect(&prefs, pref_name, &expected_new_pref_value2);
    135   registrar.Add(pref_name, &obs2);
    136   // This should fire the checks in obs and obs2.
    137   prefs.SetString(pref_name, new_pref_value2);
    138   Mock::VerifyAndClearExpectations(&obs);
    139   Mock::VerifyAndClearExpectations(&obs2);
    140 
    141   // Make sure obs2 still works after removing obs.
    142   registrar.Remove(pref_name, &obs);
    143   EXPECT_CALL(obs, Observe(_, _, _)).Times(0);
    144   obs2.Expect(&prefs, pref_name, &expected_new_pref_value);
    145   // This should only fire the observer in obs2.
    146   prefs.SetString(pref_name, new_pref_value);
    147   Mock::VerifyAndClearExpectations(&obs);
    148   Mock::VerifyAndClearExpectations(&obs2);
    149 }
    150 
    151 // Make sure that if a preference changes type, so the wrong type is stored in
    152 // the user pref file, it uses the correct fallback value instead.
    153 TEST(PrefServiceTest, GetValueChangedType) {
    154   const int kTestValue = 10;
    155   TestingPrefService prefs;
    156   prefs.RegisterIntegerPref(prefs::kStabilityLaunchCount, kTestValue);
    157 
    158   // Check falling back to a recommended value.
    159   prefs.SetUserPref(prefs::kStabilityLaunchCount,
    160                     Value::CreateStringValue("not an integer"));
    161   const PrefService::Preference* pref =
    162       prefs.FindPreference(prefs::kStabilityLaunchCount);
    163   ASSERT_TRUE(pref);
    164   const Value* value = pref->GetValue();
    165   ASSERT_TRUE(value);
    166   EXPECT_EQ(Value::TYPE_INTEGER, value->GetType());
    167   int actual_int_value = -1;
    168   EXPECT_TRUE(value->GetAsInteger(&actual_int_value));
    169   EXPECT_EQ(kTestValue, actual_int_value);
    170 }
    171 
    172 void assertProxyMode(const ProxyConfigDictionary& dict,
    173                      ProxyPrefs::ProxyMode expected_mode) {
    174   ProxyPrefs::ProxyMode actual_mode;
    175   ASSERT_TRUE(dict.GetMode(&actual_mode));
    176   EXPECT_EQ(expected_mode, actual_mode);
    177 }
    178 
    179 void assertProxyServer(const ProxyConfigDictionary& dict,
    180                        const std::string& expected) {
    181   std::string actual;
    182   if (!expected.empty()) {
    183     ASSERT_TRUE(dict.GetProxyServer(&actual));
    184     EXPECT_EQ(expected, actual);
    185   } else {
    186     EXPECT_FALSE(dict.GetProxyServer(&actual));
    187   }
    188 }
    189 
    190 void assertPacUrl(const ProxyConfigDictionary& dict,
    191                   const std::string& expected) {
    192   std::string actual;
    193   if (!expected.empty()) {
    194     ASSERT_TRUE(dict.GetPacUrl(&actual));
    195     EXPECT_EQ(expected, actual);
    196   } else {
    197     EXPECT_FALSE(dict.GetPacUrl(&actual));
    198   }
    199 }
    200 
    201 void assertBypassList(const ProxyConfigDictionary& dict,
    202                       const std::string& expected) {
    203   std::string actual;
    204   if (!expected.empty()) {
    205     ASSERT_TRUE(dict.GetBypassList(&actual));
    206     EXPECT_EQ(expected, actual);
    207   } else {
    208     EXPECT_FALSE(dict.GetBypassList(&actual));
    209   }
    210 }
    211 
    212 void assertProxyModeWithoutParams(const ProxyConfigDictionary& dict,
    213                                   ProxyPrefs::ProxyMode proxy_mode) {
    214   assertProxyMode(dict, proxy_mode);
    215   assertProxyServer(dict, "");
    216   assertPacUrl(dict, "");
    217   assertBypassList(dict, "");
    218 }
    219 
    220 TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineOptions) {
    221   CommandLine command_line(CommandLine::NO_PROGRAM);
    222   command_line.AppendSwitchASCII(switches::kProxyBypassList, "123");
    223   command_line.AppendSwitchASCII(switches::kProxyServer, "789");
    224   scoped_ptr<policy::MockConfigurationPolicyProvider> provider(
    225       new policy::MockConfigurationPolicyProvider());
    226   Value* mode_name = Value::CreateStringValue(
    227       ProxyPrefs::kFixedServersProxyModeName);
    228   provider->AddPolicy(policy::kPolicyProxyMode, mode_name);
    229   provider->AddPolicy(policy::kPolicyProxyBypassList,
    230                       Value::CreateStringValue("abc"));
    231   provider->AddPolicy(policy::kPolicyProxyServer,
    232                       Value::CreateStringValue("ghi"));
    233 
    234   // First verify that command-line options are set correctly when
    235   // there is no policy in effect.
    236   PrefServiceMockBuilder builder;
    237   builder.WithCommandLine(&command_line);
    238   scoped_ptr<PrefService> prefs(builder.Create());
    239   browser::RegisterUserPrefs(prefs.get());
    240   ProxyConfigDictionary dict(prefs->GetDictionary(prefs::kProxy));
    241   assertProxyMode(dict, ProxyPrefs::MODE_FIXED_SERVERS);
    242   assertProxyServer(dict, "789");
    243   assertPacUrl(dict, "");
    244   assertBypassList(dict, "123");
    245 
    246   // Try a second time time with the managed PrefStore in place, the
    247   // manual proxy policy should have removed all traces of the command
    248   // line and replaced them with the policy versions.
    249   builder.WithCommandLine(&command_line);
    250   builder.WithManagedPlatformProvider(provider.get());
    251   scoped_ptr<PrefService> prefs2(builder.Create());
    252   browser::RegisterUserPrefs(prefs2.get());
    253   ProxyConfigDictionary dict2(prefs2->GetDictionary(prefs::kProxy));
    254   assertProxyMode(dict2, ProxyPrefs::MODE_FIXED_SERVERS);
    255   assertProxyServer(dict2, "ghi");
    256   assertPacUrl(dict2, "");
    257   assertBypassList(dict2, "abc");
    258 }
    259 
    260 TEST(PrefServiceTest, ProxyPolicyOverridesUnrelatedCommandLineOptions) {
    261   CommandLine command_line(CommandLine::NO_PROGRAM);
    262   command_line.AppendSwitchASCII(switches::kProxyBypassList, "123");
    263   command_line.AppendSwitchASCII(switches::kProxyServer, "789");
    264   scoped_ptr<policy::MockConfigurationPolicyProvider> provider(
    265       new policy::MockConfigurationPolicyProvider());
    266   Value* mode_name = Value::CreateStringValue(
    267       ProxyPrefs::kAutoDetectProxyModeName);
    268   provider->AddPolicy(policy::kPolicyProxyMode, mode_name);
    269 
    270   // First verify that command-line options are set correctly when
    271   // there is no policy in effect.
    272   PrefServiceMockBuilder builder;
    273   builder.WithCommandLine(&command_line);
    274   scoped_ptr<PrefService> prefs(builder.Create());
    275   browser::RegisterUserPrefs(prefs.get());
    276   ProxyConfigDictionary dict(prefs->GetDictionary(prefs::kProxy));
    277   assertProxyMode(dict, ProxyPrefs::MODE_FIXED_SERVERS);
    278   assertProxyServer(dict, "789");
    279   assertPacUrl(dict, "");
    280   assertBypassList(dict, "123");
    281 
    282   // Try a second time time with the managed PrefStore in place, the
    283   // no proxy policy should have removed all traces of the command
    284   // line proxy settings, even though they were not the specific one
    285   // set in policy.
    286   builder.WithCommandLine(&command_line);
    287   builder.WithManagedPlatformProvider(provider.get());
    288   scoped_ptr<PrefService> prefs2(builder.Create());
    289   browser::RegisterUserPrefs(prefs2.get());
    290   ProxyConfigDictionary dict2(prefs2->GetDictionary(prefs::kProxy));
    291   assertProxyModeWithoutParams(dict2, ProxyPrefs::MODE_AUTO_DETECT);
    292 }
    293 
    294 TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineNoProxy) {
    295   CommandLine command_line(CommandLine::NO_PROGRAM);
    296   command_line.AppendSwitch(switches::kNoProxyServer);
    297   scoped_ptr<policy::MockConfigurationPolicyProvider> provider(
    298       new policy::MockConfigurationPolicyProvider());
    299   Value* mode_name = Value::CreateStringValue(
    300       ProxyPrefs::kAutoDetectProxyModeName);
    301   provider->AddPolicy(policy::kPolicyProxyMode, mode_name);
    302 
    303   // First verify that command-line options are set correctly when
    304   // there is no policy in effect.
    305   PrefServiceMockBuilder builder;
    306   builder.WithCommandLine(&command_line);
    307   scoped_ptr<PrefService> prefs(builder.Create());
    308   browser::RegisterUserPrefs(prefs.get());
    309   ProxyConfigDictionary dict(prefs->GetDictionary(prefs::kProxy));
    310   assertProxyModeWithoutParams(dict, ProxyPrefs::MODE_DIRECT);
    311 
    312   // Try a second time time with the managed PrefStore in place, the
    313   // auto-detect should be overridden. The default pref store must be
    314   // in place with the appropriate default value for this to work.
    315   builder.WithCommandLine(&command_line);
    316   builder.WithManagedPlatformProvider(provider.get());
    317   scoped_ptr<PrefService> prefs2(builder.Create());
    318   browser::RegisterUserPrefs(prefs2.get());
    319   ProxyConfigDictionary dict2(prefs2->GetDictionary(prefs::kProxy));
    320   assertProxyModeWithoutParams(dict2, ProxyPrefs::MODE_AUTO_DETECT);
    321 }
    322 
    323 TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineAutoDetect) {
    324   CommandLine command_line(CommandLine::NO_PROGRAM);
    325   command_line.AppendSwitch(switches::kProxyAutoDetect);
    326   scoped_ptr<policy::MockConfigurationPolicyProvider> provider(
    327       new policy::MockConfigurationPolicyProvider());
    328   Value* mode_name = Value::CreateStringValue(
    329       ProxyPrefs::kDirectProxyModeName);
    330   provider->AddPolicy(policy::kPolicyProxyMode, mode_name);
    331 
    332   // First verify that the auto-detect is set if there is no managed
    333   // PrefStore.
    334   PrefServiceMockBuilder builder;
    335   builder.WithCommandLine(&command_line);
    336   scoped_ptr<PrefService> prefs(builder.Create());
    337   browser::RegisterUserPrefs(prefs.get());
    338   ProxyConfigDictionary dict(prefs->GetDictionary(prefs::kProxy));
    339   assertProxyModeWithoutParams(dict, ProxyPrefs::MODE_AUTO_DETECT);
    340 
    341   // Try a second time time with the managed PrefStore in place, the
    342   // auto-detect should be overridden. The default pref store must be
    343   // in place with the appropriate default value for this to work.
    344   builder.WithCommandLine(&command_line);
    345   builder.WithManagedPlatformProvider(provider.get());
    346   scoped_ptr<PrefService> prefs2(builder.Create());
    347   browser::RegisterUserPrefs(prefs2.get());
    348   ProxyConfigDictionary dict2(prefs2->GetDictionary(prefs::kProxy));
    349   assertProxyModeWithoutParams(dict2, ProxyPrefs::MODE_DIRECT);
    350 }
    351 
    352 class PrefServiceSetValueTest : public testing::Test {
    353  protected:
    354   static const char kName[];
    355   static const char kValue[];
    356 
    357   TestingPrefService prefs_;
    358   PrefObserverMock observer_;
    359 };
    360 
    361 const char PrefServiceSetValueTest::kName[] = "name";
    362 const char PrefServiceSetValueTest::kValue[] = "value";
    363 
    364 TEST_F(PrefServiceSetValueTest, SetStringValue) {
    365   const char default_string[] = "default";
    366   const StringValue default_value(default_string);
    367   prefs_.RegisterStringPref(kName, default_string);
    368 
    369   PrefChangeRegistrar registrar;
    370   registrar.Init(&prefs_);
    371   registrar.Add(kName, &observer_);
    372 
    373   // Changing the controlling store from default to user triggers notification.
    374   observer_.Expect(&prefs_, kName, &default_value);
    375   prefs_.Set(kName, default_value);
    376   Mock::VerifyAndClearExpectations(&observer_);
    377 
    378   EXPECT_CALL(observer_, Observe(_, _, _)).Times(0);
    379   prefs_.Set(kName, default_value);
    380   Mock::VerifyAndClearExpectations(&observer_);
    381 
    382   StringValue new_value(kValue);
    383   observer_.Expect(&prefs_, kName, &new_value);
    384   prefs_.Set(kName, new_value);
    385   Mock::VerifyAndClearExpectations(&observer_);
    386 }
    387 
    388 TEST_F(PrefServiceSetValueTest, SetDictionaryValue) {
    389   prefs_.RegisterDictionaryPref(kName);
    390   PrefChangeRegistrar registrar;
    391   registrar.Init(&prefs_);
    392   registrar.Add(kName, &observer_);
    393 
    394   EXPECT_CALL(observer_, Observe(_, _, _)).Times(0);
    395   prefs_.RemoveUserPref(kName);
    396   Mock::VerifyAndClearExpectations(&observer_);
    397 
    398   DictionaryValue new_value;
    399   new_value.SetString(kName, kValue);
    400   observer_.Expect(&prefs_, kName, &new_value);
    401   prefs_.Set(kName, new_value);
    402   Mock::VerifyAndClearExpectations(&observer_);
    403 
    404   EXPECT_CALL(observer_, Observe(_, _, _)).Times(0);
    405   prefs_.Set(kName, new_value);
    406   Mock::VerifyAndClearExpectations(&observer_);
    407 
    408   DictionaryValue empty;
    409   observer_.Expect(&prefs_, kName, &empty);
    410   prefs_.Set(kName, empty);
    411   Mock::VerifyAndClearExpectations(&observer_);
    412 }
    413 
    414 TEST_F(PrefServiceSetValueTest, SetListValue) {
    415   prefs_.RegisterListPref(kName);
    416   PrefChangeRegistrar registrar;
    417   registrar.Init(&prefs_);
    418   registrar.Add(kName, &observer_);
    419 
    420   EXPECT_CALL(observer_, Observe(_, _, _)).Times(0);
    421   prefs_.RemoveUserPref(kName);
    422   Mock::VerifyAndClearExpectations(&observer_);
    423 
    424   ListValue new_value;
    425   new_value.Append(Value::CreateStringValue(kValue));
    426   observer_.Expect(&prefs_, kName, &new_value);
    427   prefs_.Set(kName, new_value);
    428   Mock::VerifyAndClearExpectations(&observer_);
    429 
    430   EXPECT_CALL(observer_, Observe(_, _, _)).Times(0);
    431   prefs_.Set(kName, new_value);
    432   Mock::VerifyAndClearExpectations(&observer_);
    433 
    434   ListValue empty;
    435   observer_.Expect(&prefs_, kName, &empty);
    436   prefs_.Set(kName, empty);
    437   Mock::VerifyAndClearExpectations(&observer_);
    438 }
    439