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