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