| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/syncable_prefs/pref_service_syncable.h" | 5 #include "components/syncable_prefs/pref_service_syncable.h" |
| 6 | 6 |
| 7 #include "base/json/json_reader.h" | 7 #include "base/json/json_reader.h" |
| 8 #include "base/json/json_string_value_serializer.h" | 8 #include "base/json/json_string_value_serializer.h" |
| 9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 using syncer::SyncData; | 28 using syncer::SyncData; |
| 29 | 29 |
| 30 namespace syncable_prefs { | 30 namespace syncable_prefs { |
| 31 | 31 |
| 32 namespace { | 32 namespace { |
| 33 | 33 |
| 34 const char kExampleUrl0[] = "http://example.com/0"; | 34 const char kExampleUrl0[] = "http://example.com/0"; |
| 35 const char kExampleUrl1[] = "http://example.com/1"; | 35 const char kExampleUrl1[] = "http://example.com/1"; |
| 36 const char kExampleUrl2[] = "http://example.com/2"; | 36 const char kExampleUrl2[] = "http://example.com/2"; |
| 37 const char kStringPrefName[] = "string_pref_name"; | 37 const char kStringPrefName[] = "string_pref_name"; |
| 38 const char kListPrefName[] = "new_list_pref_name"; | 38 const char kListPrefName[] = "list_pref_name"; |
| 39 const char kListOldPrefName[] = "list_pref_name"; | |
| 40 const char kUnsyncedPreferenceName[] = "nonsense_pref_name"; | 39 const char kUnsyncedPreferenceName[] = "nonsense_pref_name"; |
| 41 const char kUnsyncedPreferenceDefaultValue[] = "default"; | 40 const char kUnsyncedPreferenceDefaultValue[] = "default"; |
| 42 const char kDefaultCharsetPrefName[] = "default_charset"; | 41 const char kDefaultCharsetPrefName[] = "default_charset"; |
| 43 const char kNonDefaultCharsetValue[] = "foo"; | 42 const char kNonDefaultCharsetValue[] = "foo"; |
| 44 const char kDefaultCharsetValue[] = "utf-8"; | 43 const char kDefaultCharsetValue[] = "utf-8"; |
| 45 | 44 |
| 46 class TestPrefModelAssociatorClient : public PrefModelAssociatorClient { | 45 class TestPrefModelAssociatorClient : public PrefModelAssociatorClient { |
| 47 public: | 46 public: |
| 48 TestPrefModelAssociatorClient() {} | 47 TestPrefModelAssociatorClient() {} |
| 49 ~TestPrefModelAssociatorClient() override {} | 48 ~TestPrefModelAssociatorClient() override {} |
| 50 | 49 |
| 51 // PrefModelAssociatorClient implementation. | 50 // PrefModelAssociatorClient implementation. |
| 52 bool IsMergeableListPreference(const std::string& pref_name) const override { | 51 bool IsMergeableListPreference(const std::string& pref_name) const override { |
| 53 return pref_name == kListPrefName; | 52 return pref_name == kListPrefName; |
| 54 } | 53 } |
| 55 | 54 |
| 56 bool IsMergeableDictionaryPreference( | 55 bool IsMergeableDictionaryPreference( |
| 57 const std::string& pref_name) const override { | 56 const std::string& pref_name) const override { |
| 58 return false; | 57 return false; |
| 59 } | 58 } |
| 60 | 59 |
| 61 bool IsMigratedPreference(const std::string& new_pref_name, | |
| 62 std::string* old_pref_name) const override { | |
| 63 if (new_pref_name != kListPrefName) | |
| 64 return false; | |
| 65 old_pref_name->assign(kListOldPrefName); | |
| 66 return true; | |
| 67 } | |
| 68 | |
| 69 bool IsOldMigratedPreference(const std::string& old_pref_name, | |
| 70 std::string* new_pref_name) const override { | |
| 71 if (old_pref_name != kListOldPrefName) | |
| 72 return false; | |
| 73 new_pref_name->assign(kListPrefName); | |
| 74 return true; | |
| 75 } | |
| 76 | |
| 77 private: | 60 private: |
| 78 DISALLOW_COPY_AND_ASSIGN(TestPrefModelAssociatorClient); | 61 DISALLOW_COPY_AND_ASSIGN(TestPrefModelAssociatorClient); |
| 79 }; | 62 }; |
| 80 | 63 |
| 81 class TestSyncProcessorStub : public syncer::SyncChangeProcessor { | 64 class TestSyncProcessorStub : public syncer::SyncChangeProcessor { |
| 82 public: | 65 public: |
| 83 explicit TestSyncProcessorStub(syncer::SyncChangeList* output) | 66 explicit TestSyncProcessorStub(syncer::SyncChangeList* output) |
| 84 : output_(output), fail_next_(false) {} | 67 : output_(output), fail_next_(false) {} |
| 85 syncer::SyncError ProcessSyncChanges( | 68 syncer::SyncError ProcessSyncChanges( |
| 86 const tracked_objects::Location& from_here, | 69 const tracked_objects::Location& from_here, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 prefs_.SetPrefModelAssociatorClientForTesting(&client_); | 102 prefs_.SetPrefModelAssociatorClientForTesting(&client_); |
| 120 prefs_.registry()->RegisterStringPref(kUnsyncedPreferenceName, | 103 prefs_.registry()->RegisterStringPref(kUnsyncedPreferenceName, |
| 121 kUnsyncedPreferenceDefaultValue); | 104 kUnsyncedPreferenceDefaultValue); |
| 122 prefs_.registry()->RegisterStringPref( | 105 prefs_.registry()->RegisterStringPref( |
| 123 kStringPrefName, | 106 kStringPrefName, |
| 124 std::string(), | 107 std::string(), |
| 125 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); | 108 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); |
| 126 prefs_.registry()->RegisterListPref( | 109 prefs_.registry()->RegisterListPref( |
| 127 kListPrefName, | 110 kListPrefName, |
| 128 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); | 111 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); |
| 129 prefs_.registry()->RegisterListPref(kListOldPrefName); | |
| 130 prefs_.registry()->RegisterStringPref( | 112 prefs_.registry()->RegisterStringPref( |
| 131 kDefaultCharsetPrefName, | 113 kDefaultCharsetPrefName, |
| 132 kDefaultCharsetValue, | 114 kDefaultCharsetValue, |
| 133 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); | 115 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); |
| 134 | 116 |
| 135 pref_sync_service_ = reinterpret_cast<PrefModelAssociator*>( | 117 pref_sync_service_ = reinterpret_cast<PrefModelAssociator*>( |
| 136 prefs_.GetSyncableService(syncer::PREFERENCES)); | 118 prefs_.GetSyncableService(syncer::PREFERENCES)); |
| 137 ASSERT_TRUE(pref_sync_service_); | 119 ASSERT_TRUE(pref_sync_service_); |
| 138 next_pref_remote_sync_node_id_ = 0; | 120 next_pref_remote_sync_node_id_ = 0; |
| 139 } | 121 } |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 } | 196 } |
| 215 | 197 |
| 216 bool IsSynced(const std::string& pref_name) { | 198 bool IsSynced(const std::string& pref_name) { |
| 217 return pref_sync_service_->registered_preferences().count(pref_name) > 0; | 199 return pref_sync_service_->registered_preferences().count(pref_name) > 0; |
| 218 } | 200 } |
| 219 | 201 |
| 220 bool HasSyncData(const std::string& pref_name) { | 202 bool HasSyncData(const std::string& pref_name) { |
| 221 return pref_sync_service_->IsPrefSynced(pref_name); | 203 return pref_sync_service_->IsPrefSynced(pref_name); |
| 222 } | 204 } |
| 223 | 205 |
| 224 // Returns whether a given preference name is a new name of a migrated | |
| 225 // preference. Exposed here for testing. | |
| 226 bool IsMigratedPreference(const char* preference_name) { | |
| 227 std::string old_pref_name; | |
| 228 return client_.IsMigratedPreference(preference_name, &old_pref_name); | |
| 229 } | |
| 230 | |
| 231 bool IsOldMigratedPreference(const char* old_preference_name) { | |
| 232 std::string new_pref_name; | |
| 233 return client_.IsOldMigratedPreference(old_preference_name, &new_pref_name); | |
| 234 } | |
| 235 | |
| 236 PrefService* GetPrefs() { return &prefs_; } | 206 PrefService* GetPrefs() { return &prefs_; } |
| 237 TestingPrefServiceSyncable* GetTestingPrefService() { return &prefs_; } | 207 TestingPrefServiceSyncable* GetTestingPrefService() { return &prefs_; } |
| 238 | 208 |
| 239 protected: | 209 protected: |
| 240 TestPrefModelAssociatorClient client_; | 210 TestPrefModelAssociatorClient client_; |
| 241 TestingPrefServiceSyncable prefs_; | 211 TestingPrefServiceSyncable prefs_; |
| 242 | 212 |
| 243 PrefModelAssociator* pref_sync_service_; | 213 PrefModelAssociator* pref_sync_service_; |
| 244 TestSyncProcessorStub* test_processor_; | 214 TestSyncProcessorStub* test_processor_; |
| 245 | 215 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 expected_urls->Append(new base::StringValue(kExampleUrl1)); | 296 expected_urls->Append(new base::StringValue(kExampleUrl1)); |
| 327 expected_urls->Append(new base::StringValue(kExampleUrl2)); | 297 expected_urls->Append(new base::StringValue(kExampleUrl2)); |
| 328 expected_urls->Append(new base::StringValue(kExampleUrl0)); | 298 expected_urls->Append(new base::StringValue(kExampleUrl0)); |
| 329 scoped_ptr<base::Value> value(FindValue(kListPrefName, out)); | 299 scoped_ptr<base::Value> value(FindValue(kListPrefName, out)); |
| 330 ASSERT_TRUE(value.get()); | 300 ASSERT_TRUE(value.get()); |
| 331 EXPECT_TRUE(value->Equals(expected_urls.get())); | 301 EXPECT_TRUE(value->Equals(expected_urls.get())); |
| 332 EXPECT_TRUE(GetPreferenceValue(kListPrefName).Equals(expected_urls.get())); | 302 EXPECT_TRUE(GetPreferenceValue(kListPrefName).Equals(expected_urls.get())); |
| 333 EXPECT_EQ(kNonDefaultCharsetValue, prefs_.GetString(kDefaultCharsetPrefName)); | 303 EXPECT_EQ(kNonDefaultCharsetValue, prefs_.GetString(kDefaultCharsetPrefName)); |
| 334 } | 304 } |
| 335 | 305 |
| 336 TEST_F(PrefServiceSyncableTest, ModelAssociationMigrateOldData) { | |
| 337 ASSERT_TRUE(IsMigratedPreference(kListPrefName)); | |
| 338 ASSERT_TRUE(IsOldMigratedPreference(kListOldPrefName)); | |
| 339 | |
| 340 syncer::SyncDataList in; | |
| 341 syncer::SyncChangeList out; | |
| 342 base::ListValue urls_to_restore; | |
| 343 urls_to_restore.Append(new base::StringValue(kExampleUrl1)); | |
| 344 urls_to_restore.Append(new base::StringValue(kExampleUrl2)); | |
| 345 AddToRemoteDataList(kListOldPrefName, urls_to_restore, &in); | |
| 346 InitWithSyncDataTakeOutput(in, &out); | |
| 347 | |
| 348 // Expect that the new preference data contains the old pref's values. | |
| 349 scoped_ptr<base::ListValue> expected_urls(new base::ListValue); | |
| 350 expected_urls->Append(new base::StringValue(kExampleUrl1)); | |
| 351 expected_urls->Append(new base::StringValue(kExampleUrl2)); | |
| 352 | |
| 353 ASSERT_TRUE(HasSyncData(kListPrefName)); | |
| 354 scoped_ptr<base::Value> value(FindValue(kListPrefName, out)); | |
| 355 ASSERT_TRUE(value.get()); | |
| 356 EXPECT_TRUE(value->Equals(expected_urls.get())); | |
| 357 EXPECT_TRUE(GetPreferenceValue(kListPrefName).Equals(expected_urls.get())); | |
| 358 | |
| 359 // The old preference value should be the same. | |
| 360 expected_urls.reset(new base::ListValue); | |
| 361 ASSERT_FALSE(FindValue(kListOldPrefName, out).get()); | |
| 362 EXPECT_TRUE(GetPreferenceValue(kListOldPrefName).Equals(expected_urls.get())); | |
| 363 } | |
| 364 | |
| 365 TEST_F(PrefServiceSyncableTest, ModelAssociationCloudHasOldMigratedData) { | |
| 366 ASSERT_TRUE(IsMigratedPreference(kListPrefName)); | |
| 367 ASSERT_TRUE(IsOldMigratedPreference(kListOldPrefName)); | |
| 368 prefs_.SetString(kStringPrefName, kExampleUrl0); | |
| 369 { | |
| 370 ListPrefUpdate update(GetPrefs(), kListPrefName); | |
| 371 base::ListValue* url_list = update.Get(); | |
| 372 url_list->Append(new base::StringValue(kExampleUrl0)); | |
| 373 url_list->Append(new base::StringValue(kExampleUrl1)); | |
| 374 } | |
| 375 | |
| 376 syncer::SyncDataList in; | |
| 377 syncer::SyncChangeList out; | |
| 378 base::ListValue urls_to_restore; | |
| 379 urls_to_restore.Append(new base::StringValue(kExampleUrl1)); | |
| 380 urls_to_restore.Append(new base::StringValue(kExampleUrl2)); | |
| 381 AddToRemoteDataList(kListOldPrefName, urls_to_restore, &in); | |
| 382 AddToRemoteDataList(kStringPrefName, base::StringValue(kExampleUrl1), &in); | |
| 383 InitWithSyncDataTakeOutput(in, &out); | |
| 384 | |
| 385 ASSERT_FALSE(FindValue(kStringPrefName, out).get()); | |
| 386 | |
| 387 // Expect that the new preference data contains the merged old prefs values. | |
| 388 scoped_ptr<base::ListValue> expected_urls(new base::ListValue); | |
| 389 expected_urls->Append(new base::StringValue(kExampleUrl1)); | |
| 390 expected_urls->Append(new base::StringValue(kExampleUrl2)); | |
| 391 expected_urls->Append(new base::StringValue(kExampleUrl0)); | |
| 392 | |
| 393 ASSERT_TRUE(HasSyncData(kListPrefName)); | |
| 394 scoped_ptr<base::Value> value(FindValue(kListPrefName, out)); | |
| 395 ASSERT_TRUE(value.get()); | |
| 396 EXPECT_TRUE(value->Equals(expected_urls.get())); | |
| 397 EXPECT_TRUE(GetPreferenceValue(kListPrefName).Equals(expected_urls.get())); | |
| 398 | |
| 399 expected_urls.reset(new base::ListValue); | |
| 400 value = FindValue(kListOldPrefName, out).Pass(); | |
| 401 ASSERT_TRUE(value.get()); | |
| 402 EXPECT_TRUE(GetPreferenceValue(kListOldPrefName).Equals(expected_urls.get())); | |
| 403 } | |
| 404 | |
| 405 TEST_F(PrefServiceSyncableTest, ModelAssociationCloudHasNewMigratedData) { | |
| 406 ASSERT_TRUE(IsMigratedPreference(kListPrefName)); | |
| 407 ASSERT_TRUE(IsOldMigratedPreference(kListOldPrefName)); | |
| 408 prefs_.SetString(kStringPrefName, kExampleUrl0); | |
| 409 { | |
| 410 ListPrefUpdate update(GetPrefs(), kListOldPrefName); | |
| 411 base::ListValue* url_list = update.Get(); | |
| 412 url_list->Append(new base::StringValue(kExampleUrl0)); | |
| 413 url_list->Append(new base::StringValue(kExampleUrl1)); | |
| 414 } | |
| 415 | |
| 416 syncer::SyncDataList in; | |
| 417 syncer::SyncChangeList out; | |
| 418 base::ListValue urls_to_restore; | |
| 419 urls_to_restore.Append(new base::StringValue(kExampleUrl1)); | |
| 420 urls_to_restore.Append(new base::StringValue(kExampleUrl2)); | |
| 421 AddToRemoteDataList(kListOldPrefName, urls_to_restore, &in); | |
| 422 AddToRemoteDataList(kStringPrefName, base::StringValue(kExampleUrl1), &in); | |
| 423 InitWithSyncDataTakeOutput(in, &out); | |
| 424 | |
| 425 scoped_ptr<base::Value> value(FindValue(kStringPrefName, out)); | |
| 426 ASSERT_FALSE(value.get()); | |
| 427 | |
| 428 // Expect that the cloud data under the new migrated preference name sticks. | |
| 429 scoped_ptr<base::ListValue> expected_urls(new base::ListValue); | |
| 430 expected_urls->Append(new base::StringValue(kExampleUrl1)); | |
| 431 expected_urls->Append(new base::StringValue(kExampleUrl2)); | |
| 432 | |
| 433 ASSERT_TRUE(HasSyncData(kListPrefName)); | |
| 434 value = FindValue(kListPrefName, out).Pass(); | |
| 435 ASSERT_TRUE(value.get()); | |
| 436 EXPECT_TRUE(value->Equals(expected_urls.get())); | |
| 437 EXPECT_TRUE(GetPreferenceValue(kListPrefName).Equals(expected_urls.get())); | |
| 438 | |
| 439 // The old preference data should still be here, though not synced. | |
| 440 expected_urls.reset(new base::ListValue); | |
| 441 expected_urls->Append(new base::StringValue(kExampleUrl0)); | |
| 442 expected_urls->Append(new base::StringValue(kExampleUrl1)); | |
| 443 | |
| 444 value = FindValue(kListOldPrefName, out).Pass(); | |
| 445 ASSERT_FALSE(value.get()); | |
| 446 EXPECT_TRUE(GetPreferenceValue(kListOldPrefName).Equals(expected_urls.get())); | |
| 447 } | |
| 448 | |
| 449 TEST_F(PrefServiceSyncableTest, | |
| 450 ModelAssociationCloudAddsOldAndNewMigratedData) { | |
| 451 ASSERT_TRUE(IsMigratedPreference(kListPrefName)); | |
| 452 ASSERT_TRUE(IsOldMigratedPreference(kListOldPrefName)); | |
| 453 prefs_.SetString(kStringPrefName, kExampleUrl0); | |
| 454 { | |
| 455 ListPrefUpdate update_old(GetPrefs(), kListOldPrefName); | |
| 456 base::ListValue* url_list_old = update_old.Get(); | |
| 457 url_list_old->Append(new base::StringValue(kExampleUrl0)); | |
| 458 url_list_old->Append(new base::StringValue(kExampleUrl1)); | |
| 459 ListPrefUpdate update(GetPrefs(), kListPrefName); | |
| 460 base::ListValue* url_list = update.Get(); | |
| 461 url_list->Append(new base::StringValue(kExampleUrl1)); | |
| 462 url_list->Append(new base::StringValue(kExampleUrl2)); | |
| 463 } | |
| 464 | |
| 465 syncer::SyncDataList in; | |
| 466 syncer::SyncChangeList out; | |
| 467 AddToRemoteDataList(kStringPrefName, base::StringValue(kExampleUrl1), &in); | |
| 468 InitWithSyncDataTakeOutput(in, &out); | |
| 469 | |
| 470 scoped_ptr<base::Value> value(FindValue(kStringPrefName, out)); | |
| 471 ASSERT_FALSE(value.get()); | |
| 472 | |
| 473 // Expect that the cloud data under the new migrated preference name sticks. | |
| 474 scoped_ptr<base::ListValue> expected_urls(new base::ListValue); | |
| 475 expected_urls->Append(new base::StringValue(kExampleUrl1)); | |
| 476 expected_urls->Append(new base::StringValue(kExampleUrl2)); | |
| 477 | |
| 478 ASSERT_TRUE(HasSyncData(kListPrefName)); | |
| 479 value = FindValue(kListPrefName, out).Pass(); | |
| 480 ASSERT_TRUE(value.get()); | |
| 481 EXPECT_TRUE(value->Equals(expected_urls.get())); | |
| 482 EXPECT_TRUE(GetPreferenceValue(kListPrefName).Equals(expected_urls.get())); | |
| 483 | |
| 484 // Should not have synced in the old startup url values. | |
| 485 value = FindValue(kListOldPrefName, out).Pass(); | |
| 486 ASSERT_FALSE(value.get()); | |
| 487 EXPECT_FALSE( | |
| 488 GetPreferenceValue(kListOldPrefName).Equals(expected_urls.get())); | |
| 489 } | |
| 490 | |
| 491 TEST_F(PrefServiceSyncableTest, FailModelAssociation) { | 306 TEST_F(PrefServiceSyncableTest, FailModelAssociation) { |
| 492 syncer::SyncChangeList output; | 307 syncer::SyncChangeList output; |
| 493 TestSyncProcessorStub* stub = new TestSyncProcessorStub(&output); | 308 TestSyncProcessorStub* stub = new TestSyncProcessorStub(&output); |
| 494 stub->FailNextProcessSyncChanges(); | 309 stub->FailNextProcessSyncChanges(); |
| 495 syncer::SyncMergeResult r = pref_sync_service_->MergeDataAndStartSyncing( | 310 syncer::SyncMergeResult r = pref_sync_service_->MergeDataAndStartSyncing( |
| 496 syncer::PREFERENCES, syncer::SyncDataList(), | 311 syncer::PREFERENCES, syncer::SyncDataList(), |
| 497 scoped_ptr<syncer::SyncChangeProcessor>(stub), | 312 scoped_ptr<syncer::SyncChangeProcessor>(stub), |
| 498 scoped_ptr<syncer::SyncErrorFactory>( | 313 scoped_ptr<syncer::SyncErrorFactory>( |
| 499 new syncer::SyncErrorFactoryMock())); | 314 new syncer::SyncErrorFactoryMock())); |
| 500 EXPECT_TRUE(r.error().IsSet()); | 315 EXPECT_TRUE(r.error().IsSet()); |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 736 syncer::SyncChangeList list; | 551 syncer::SyncChangeList list; |
| 737 list.push_back(MakeRemoteChange( | 552 list.push_back(MakeRemoteChange( |
| 738 1, kStringPrefName, *null_value, SyncChange::ACTION_DELETE)); | 553 1, kStringPrefName, *null_value, SyncChange::ACTION_DELETE)); |
| 739 pref_sync_service_->ProcessSyncChanges(FROM_HERE, list); | 554 pref_sync_service_->ProcessSyncChanges(FROM_HERE, list); |
| 740 EXPECT_TRUE(pref->IsDefaultValue()); | 555 EXPECT_TRUE(pref->IsDefaultValue()); |
| 741 } | 556 } |
| 742 | 557 |
| 743 } // namespace | 558 } // namespace |
| 744 | 559 |
| 745 } // namespace syncable_prefs | 560 } // namespace syncable_prefs |
| OLD | NEW |