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