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