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 "base/memory/scoped_ptr.h"
      6 #include "base/values.h"
      7 #include "chrome/browser/prefs/pref_model_associator.h"
      8 #include "chrome/browser/prefs/scoped_user_pref_update.h"
      9 #include "chrome/common/pref_names.h"
     10 #include "chrome/test/base/testing_profile.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 
     13 class AbstractPreferenceMergeTest : public testing::Test {
     14  protected:
     15   virtual void SetUp() {
     16     pref_service_ = profile_.GetPrefs();
     17   }
     18 
     19   void SetContentPattern(DictionaryValue* patterns_dict,
     20                          const std::string& expression,
     21                          const std::string& content_type,
     22                          int setting) {
     23     DictionaryValue* expression_dict;
     24     bool found =
     25         patterns_dict->GetDictionaryWithoutPathExpansion(expression,
     26                                                          &expression_dict);
     27     if (!found) {
     28       expression_dict = new DictionaryValue;
     29       patterns_dict->SetWithoutPathExpansion(expression, expression_dict);
     30     }
     31     expression_dict->SetWithoutPathExpansion(
     32         content_type,
     33         Value::CreateIntegerValue(setting));
     34   }
     35 
     36   void SetPrefToEmpty(const std::string& pref_name) {
     37     scoped_ptr<Value> empty_value;
     38     const PrefService::Preference* pref =
     39         pref_service_->FindPreference(pref_name.c_str());
     40     ASSERT_TRUE(pref);
     41     base::Value::Type type = pref->GetType();
     42     if (type == Value::TYPE_DICTIONARY)
     43       empty_value.reset(new DictionaryValue);
     44     else if (type == Value::TYPE_LIST)
     45       empty_value.reset(new ListValue);
     46     else
     47       FAIL();
     48     pref_service_->Set(pref_name.c_str(), *empty_value);
     49   }
     50 
     51   TestingProfile profile_;
     52   PrefService* pref_service_;
     53 };
     54 
     55 class ListPreferenceMergeTest : public AbstractPreferenceMergeTest {
     56  protected:
     57   ListPreferenceMergeTest() :
     58       server_url0_("http://example.com/server0"),
     59       server_url1_("http://example.com/server1"),
     60       local_url0_("http://example.com/local0"),
     61       local_url1_("http://example.com/local1") {}
     62 
     63   virtual void SetUp() {
     64     AbstractPreferenceMergeTest::SetUp();
     65     server_url_list_.Append(Value::CreateStringValue(server_url0_));
     66     server_url_list_.Append(Value::CreateStringValue(server_url1_));
     67   }
     68 
     69   std::string server_url0_;
     70   std::string server_url1_;
     71   std::string local_url0_;
     72   std::string local_url1_;
     73   ListValue server_url_list_;
     74 };
     75 
     76 TEST_F(ListPreferenceMergeTest, NotListOrDictionary) {
     77   pref_service_->SetString(prefs::kHomePage, local_url0_);
     78   const PrefService::Preference* pref =
     79       pref_service_->FindPreference(prefs::kHomePage);
     80   scoped_ptr<Value> server_value(Value::CreateStringValue(server_url0_));
     81   scoped_ptr<Value> merged_value(
     82       PrefModelAssociator::MergePreference(pref->name(),
     83                                            *pref->GetValue(),
     84                                            *server_value));
     85   EXPECT_TRUE(merged_value->Equals(server_value.get()));
     86 }
     87 
     88 TEST_F(ListPreferenceMergeTest, LocalEmpty) {
     89   SetPrefToEmpty(prefs::kURLsToRestoreOnStartup);
     90   const PrefService::Preference* pref =
     91       pref_service_->FindPreference(prefs::kURLsToRestoreOnStartup);
     92   scoped_ptr<Value> merged_value(
     93       PrefModelAssociator::MergePreference(pref->name(),
     94                                            *pref->GetValue(),
     95                                            server_url_list_));
     96   EXPECT_TRUE(merged_value->Equals(&server_url_list_));
     97 }
     98 
     99 TEST_F(ListPreferenceMergeTest, ServerNull) {
    100   scoped_ptr<Value> null_value(Value::CreateNullValue());
    101   {
    102     ListPrefUpdate update(pref_service_, prefs::kURLsToRestoreOnStartup);
    103     ListValue* local_list_value = update.Get();
    104     local_list_value->Append(Value::CreateStringValue(local_url0_));
    105   }
    106 
    107   const PrefService::Preference* pref =
    108       pref_service_->FindPreference(prefs::kURLsToRestoreOnStartup);
    109   scoped_ptr<Value> merged_value(
    110       PrefModelAssociator::MergePreference(pref->name(),
    111                                            *pref->GetValue(),
    112                                            *null_value));
    113   const ListValue* local_list_value =
    114         pref_service_->GetList(prefs::kURLsToRestoreOnStartup);
    115   EXPECT_TRUE(merged_value->Equals(local_list_value));
    116 }
    117 
    118 TEST_F(ListPreferenceMergeTest, ServerEmpty) {
    119   scoped_ptr<Value> empty_value(new ListValue);
    120   {
    121     ListPrefUpdate update(pref_service_, prefs::kURLsToRestoreOnStartup);
    122     ListValue* local_list_value = update.Get();
    123     local_list_value->Append(Value::CreateStringValue(local_url0_));
    124   }
    125 
    126   const PrefService::Preference* pref =
    127       pref_service_->FindPreference(prefs::kURLsToRestoreOnStartup);
    128   scoped_ptr<Value> merged_value(
    129       PrefModelAssociator::MergePreference(pref->name(),
    130                                            *pref->GetValue(),
    131                                            *empty_value));
    132   const ListValue* local_list_value =
    133         pref_service_->GetList(prefs::kURLsToRestoreOnStartup);
    134   EXPECT_TRUE(merged_value->Equals(local_list_value));
    135 }
    136 
    137 TEST_F(ListPreferenceMergeTest, Merge) {
    138   {
    139     ListPrefUpdate update(pref_service_, prefs::kURLsToRestoreOnStartup);
    140     ListValue* local_list_value = update.Get();
    141     local_list_value->Append(Value::CreateStringValue(local_url0_));
    142     local_list_value->Append(Value::CreateStringValue(local_url1_));
    143   }
    144 
    145   const PrefService::Preference* pref =
    146       pref_service_->FindPreference(prefs::kURLsToRestoreOnStartup);
    147   scoped_ptr<Value> merged_value(
    148       PrefModelAssociator::MergePreference(pref->name(),
    149                                            *pref->GetValue(),
    150                                            server_url_list_));
    151 
    152   ListValue expected;
    153   expected.Append(Value::CreateStringValue(server_url0_));
    154   expected.Append(Value::CreateStringValue(server_url1_));
    155   expected.Append(Value::CreateStringValue(local_url0_));
    156   expected.Append(Value::CreateStringValue(local_url1_));
    157   EXPECT_TRUE(merged_value->Equals(&expected));
    158 }
    159 
    160 TEST_F(ListPreferenceMergeTest, Duplicates) {
    161   {
    162     ListPrefUpdate update(pref_service_, prefs::kURLsToRestoreOnStartup);
    163     ListValue* local_list_value = update.Get();
    164     local_list_value->Append(Value::CreateStringValue(local_url0_));
    165     local_list_value->Append(Value::CreateStringValue(server_url0_));
    166     local_list_value->Append(Value::CreateStringValue(server_url1_));
    167   }
    168 
    169   const PrefService::Preference* pref =
    170       pref_service_->FindPreference(prefs::kURLsToRestoreOnStartup);
    171   scoped_ptr<Value> merged_value(
    172       PrefModelAssociator::MergePreference(pref->name(),
    173                                            *pref->GetValue(),
    174                                            server_url_list_));
    175 
    176   ListValue expected;
    177   expected.Append(Value::CreateStringValue(server_url0_));
    178   expected.Append(Value::CreateStringValue(server_url1_));
    179   expected.Append(Value::CreateStringValue(local_url0_));
    180   EXPECT_TRUE(merged_value->Equals(&expected));
    181 }
    182 
    183 TEST_F(ListPreferenceMergeTest, Equals) {
    184   {
    185     ListPrefUpdate update(pref_service_, prefs::kURLsToRestoreOnStartup);
    186     ListValue* local_list_value = update.Get();
    187     local_list_value->Append(Value::CreateStringValue(server_url0_));
    188     local_list_value->Append(Value::CreateStringValue(server_url1_));
    189   }
    190 
    191   scoped_ptr<Value> original(server_url_list_.DeepCopy());
    192   const PrefService::Preference* pref =
    193       pref_service_->FindPreference(prefs::kURLsToRestoreOnStartup);
    194   scoped_ptr<Value> merged_value(
    195       PrefModelAssociator::MergePreference(pref->name(),
    196                                            *pref->GetValue(),
    197                                            server_url_list_));
    198   EXPECT_TRUE(merged_value->Equals(original.get()));
    199 }
    200 
    201 class DictionaryPreferenceMergeTest : public AbstractPreferenceMergeTest {
    202  protected:
    203   DictionaryPreferenceMergeTest() :
    204       expression0_("expression0"),
    205       expression1_("expression1"),
    206       expression2_("expression2"),
    207       content_type0_("content_type0"),
    208       content_type1_("content_type1") {}
    209 
    210   virtual void SetUp() {
    211     AbstractPreferenceMergeTest::SetUp();
    212     SetContentPattern(&server_patterns_, expression0_, content_type0_, 1);
    213     SetContentPattern(&server_patterns_, expression0_, content_type1_, 2);
    214     SetContentPattern(&server_patterns_, expression1_, content_type0_, 1);
    215   }
    216 
    217   std::string expression0_;
    218   std::string expression1_;
    219   std::string expression2_;
    220   std::string content_type0_;
    221   std::string content_type1_;
    222   DictionaryValue server_patterns_;
    223 };
    224 
    225 TEST_F(DictionaryPreferenceMergeTest, LocalEmpty) {
    226   SetPrefToEmpty(prefs::kContentSettingsPatternPairs);
    227   const PrefService::Preference* pref =
    228       pref_service_->FindPreference(prefs::kContentSettingsPatternPairs);
    229   scoped_ptr<Value> merged_value(
    230       PrefModelAssociator::MergePreference(pref->name(),
    231                                            *pref->GetValue(),
    232                                            server_patterns_));
    233   EXPECT_TRUE(merged_value->Equals(&server_patterns_));
    234 }
    235 
    236 TEST_F(DictionaryPreferenceMergeTest, ServerNull) {
    237   scoped_ptr<Value> null_value(Value::CreateNullValue());
    238   {
    239     DictionaryPrefUpdate update(pref_service_,
    240                                 prefs::kContentSettingsPatternPairs);
    241     DictionaryValue* local_dict_value = update.Get();
    242     SetContentPattern(local_dict_value, expression2_, content_type0_, 1);
    243   }
    244 
    245   const PrefService::Preference* pref =
    246       pref_service_->FindPreference(prefs::kContentSettingsPatternPairs);
    247   scoped_ptr<Value> merged_value(
    248       PrefModelAssociator::MergePreference(pref->name(),
    249                                            *pref->GetValue(),
    250                                            *null_value));
    251   const DictionaryValue* local_dict_value =
    252       pref_service_->GetDictionary(prefs::kContentSettingsPatternPairs);
    253   EXPECT_TRUE(merged_value->Equals(local_dict_value));
    254 }
    255 
    256 TEST_F(DictionaryPreferenceMergeTest, ServerEmpty) {
    257   scoped_ptr<Value> empty_value(new DictionaryValue);
    258   {
    259     DictionaryPrefUpdate update(pref_service_,
    260                                 prefs::kContentSettingsPatternPairs);
    261     DictionaryValue* local_dict_value = update.Get();
    262     SetContentPattern(local_dict_value, expression2_, content_type0_, 1);
    263   }
    264 
    265   const PrefService::Preference* pref =
    266       pref_service_->FindPreference(prefs::kContentSettingsPatternPairs);
    267   scoped_ptr<Value> merged_value(
    268       PrefModelAssociator::MergePreference(pref->name(),
    269                                            *pref->GetValue(),
    270                                            *empty_value));
    271   const DictionaryValue* local_dict_value =
    272       pref_service_->GetDictionary(prefs::kContentSettingsPatternPairs);
    273   EXPECT_TRUE(merged_value->Equals(local_dict_value));
    274 }
    275 
    276 TEST_F(DictionaryPreferenceMergeTest, MergeNoConflicts) {
    277   {
    278     DictionaryPrefUpdate update(pref_service_,
    279                                 prefs::kContentSettingsPatternPairs);
    280     DictionaryValue* local_dict_value = update.Get();
    281     SetContentPattern(local_dict_value, expression2_, content_type0_, 1);
    282   }
    283 
    284   scoped_ptr<Value> merged_value(PrefModelAssociator::MergePreference(
    285      prefs::kContentSettingsPatternPairs,
    286       *pref_service_->FindPreference(prefs::kContentSettingsPatternPairs)->
    287           GetValue(),
    288       server_patterns_));
    289 
    290   DictionaryValue expected;
    291   SetContentPattern(&expected, expression0_, content_type0_, 1);
    292   SetContentPattern(&expected, expression0_, content_type1_, 2);
    293   SetContentPattern(&expected, expression1_, content_type0_, 1);
    294   SetContentPattern(&expected, expression2_, content_type0_, 1);
    295   EXPECT_TRUE(merged_value->Equals(&expected));
    296 }
    297 
    298 TEST_F(DictionaryPreferenceMergeTest, MergeConflicts) {
    299   {
    300     DictionaryPrefUpdate update(pref_service_,
    301                                 prefs::kContentSettingsPatternPairs);
    302     DictionaryValue* local_dict_value = update.Get();
    303     SetContentPattern(local_dict_value, expression0_, content_type0_, 2);
    304     SetContentPattern(local_dict_value, expression1_, content_type0_, 1);
    305     SetContentPattern(local_dict_value, expression1_, content_type1_, 1);
    306     SetContentPattern(local_dict_value, expression2_, content_type0_, 2);
    307   }
    308 
    309   scoped_ptr<Value> merged_value(PrefModelAssociator::MergePreference(
    310       prefs::kContentSettingsPatternPairs,
    311       *pref_service_->FindPreference(prefs::kContentSettingsPatternPairs)->
    312           GetValue(),
    313       server_patterns_));
    314 
    315   DictionaryValue expected;
    316   SetContentPattern(&expected, expression0_, content_type0_, 1);
    317   SetContentPattern(&expected, expression0_, content_type1_, 2);
    318   SetContentPattern(&expected, expression1_, content_type0_, 1);
    319   SetContentPattern(&expected, expression1_, content_type1_, 1);
    320   SetContentPattern(&expected, expression2_, content_type0_, 2);
    321   EXPECT_TRUE(merged_value->Equals(&expected));
    322 }
    323 
    324 TEST_F(DictionaryPreferenceMergeTest, Equal) {
    325   {
    326     DictionaryPrefUpdate update(pref_service_,
    327                                 prefs::kContentSettingsPatternPairs);
    328     DictionaryValue* local_dict_value = update.Get();
    329     SetContentPattern(local_dict_value, expression0_, content_type0_, 1);
    330     SetContentPattern(local_dict_value, expression0_, content_type1_, 2);
    331     SetContentPattern(local_dict_value, expression1_, content_type0_, 1);
    332   }
    333 
    334   scoped_ptr<Value> merged_value(PrefModelAssociator::MergePreference(
    335       prefs::kContentSettingsPatternPairs,
    336       *pref_service_->
    337           FindPreference(prefs::kContentSettingsPatternPairs)->GetValue(),
    338       server_patterns_));
    339   EXPECT_TRUE(merged_value->Equals(&server_patterns_));
    340 }
    341 
    342 TEST_F(DictionaryPreferenceMergeTest, ConflictButServerWins) {
    343   {
    344     DictionaryPrefUpdate update(pref_service_,
    345                                 prefs::kContentSettingsPatternPairs);
    346     DictionaryValue* local_dict_value = update.Get();
    347     SetContentPattern(local_dict_value, expression0_, content_type0_, 2);
    348     SetContentPattern(local_dict_value, expression0_, content_type1_, 2);
    349     SetContentPattern(local_dict_value, expression1_, content_type0_, 1);
    350   }
    351 
    352   scoped_ptr<Value> merged_value(PrefModelAssociator::MergePreference(
    353       prefs::kContentSettingsPatternPairs,
    354       *pref_service_->
    355           FindPreference(prefs::kContentSettingsPatternPairs)->GetValue(),
    356       server_patterns_));
    357   EXPECT_TRUE(merged_value->Equals(&server_patterns_));
    358 }
    359 
    360 class IndividualPreferenceMergeTest : public AbstractPreferenceMergeTest {
    361  protected:
    362   IndividualPreferenceMergeTest() :
    363       url0_("http://example.com/server0"),
    364       url1_("http://example.com/server1"),
    365       expression0_("expression0"),
    366       expression1_("expression1"),
    367       content_type0_("content_type0") {}
    368 
    369   virtual void SetUp() {
    370     AbstractPreferenceMergeTest::SetUp();
    371     server_url_list_.Append(Value::CreateStringValue(url0_));
    372     SetContentPattern(&server_patterns_, expression0_, content_type0_, 1);
    373   }
    374 
    375   bool MergeListPreference(const char* pref) {
    376     {
    377       ListPrefUpdate update(pref_service_, pref);
    378       ListValue* local_list_value = update.Get();
    379       local_list_value->Append(Value::CreateStringValue(url1_));
    380     }
    381 
    382     scoped_ptr<Value> merged_value(PrefModelAssociator::MergePreference(
    383         pref,
    384         *pref_service_->GetUserPrefValue(pref),
    385         server_url_list_));
    386 
    387     ListValue expected;
    388     expected.Append(Value::CreateStringValue(url0_));
    389     expected.Append(Value::CreateStringValue(url1_));
    390     return merged_value->Equals(&expected);
    391   }
    392 
    393   bool MergeDictionaryPreference(const char* pref) {
    394     {
    395       DictionaryPrefUpdate update(pref_service_, pref);
    396       DictionaryValue* local_dict_value = update.Get();
    397       SetContentPattern(local_dict_value, expression1_, content_type0_, 1);
    398     }
    399 
    400     scoped_ptr<Value> merged_value(PrefModelAssociator::MergePreference(
    401         pref,
    402         *pref_service_->GetUserPrefValue(pref),
    403         server_patterns_));
    404 
    405     DictionaryValue expected;
    406     SetContentPattern(&expected, expression0_, content_type0_, 1);
    407     SetContentPattern(&expected, expression1_, content_type0_, 1);
    408     return merged_value->Equals(&expected);
    409   }
    410 
    411   std::string url0_;
    412   std::string url1_;
    413   std::string expression0_;
    414   std::string expression1_;
    415   std::string content_type0_;
    416   ListValue server_url_list_;
    417   DictionaryValue server_patterns_;
    418 };
    419 
    420 TEST_F(IndividualPreferenceMergeTest, URLsToRestoreOnStartup) {
    421   EXPECT_TRUE(MergeListPreference(prefs::kURLsToRestoreOnStartup));
    422 }
    423