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