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 3 // found in the LICENSE file. 4 5 #include "base/json/json_reader.h" 6 #include "base/json/json_string_value_serializer.h" 7 #include "base/json/json_writer.h" 8 #include "base/message_loop/message_loop.h" 9 #include "base/prefs/scoped_user_pref_update.h" 10 #include "base/strings/utf_string_conversions.h" 11 #include "chrome/browser/prefs/pref_model_associator.h" 12 #include "chrome/browser/prefs/pref_service_syncable.h" 13 #include "chrome/common/pref_names.h" 14 #include "chrome/grit/locale_settings.h" 15 #include "chrome/test/base/testing_pref_service_syncable.h" 16 #include "components/pref_registry/pref_registry_syncable.h" 17 #include "sync/api/attachments/attachment_id.h" 18 #include "sync/api/sync_change.h" 19 #include "sync/api/sync_data.h" 20 #include "sync/api/sync_error_factory_mock.h" 21 #include "sync/api/syncable_service.h" 22 #include "sync/internal_api/public/attachments/attachment_service_proxy_for_test.h" 23 #include "sync/protocol/preference_specifics.pb.h" 24 #include "sync/protocol/sync.pb.h" 25 #include "testing/gtest/include/gtest/gtest.h" 26 27 using syncer::SyncChange; 28 using syncer::SyncData; 29 30 namespace { 31 const char kExampleUrl0[] = "http://example.com/0"; 32 const char kExampleUrl1[] = "http://example.com/1"; 33 const char kExampleUrl2[] = "http://example.com/2"; 34 const char kUnsyncedPreferenceName[] = "nonsense_pref_name"; 35 const char kUnsyncedPreferenceDefaultValue[] = "default"; 36 const char kNonDefaultCharsetValue[] = "foo"; 37 } // namespace 38 39 class TestSyncProcessorStub : public syncer::SyncChangeProcessor { 40 public: 41 explicit TestSyncProcessorStub(syncer::SyncChangeList* output) 42 : output_(output), fail_next_(false) {} 43 virtual syncer::SyncError ProcessSyncChanges( 44 const tracked_objects::Location& from_here, 45 const syncer::SyncChangeList& change_list) OVERRIDE { 46 if (output_) 47 output_->insert(output_->end(), change_list.begin(), change_list.end()); 48 if (fail_next_) { 49 fail_next_ = false; 50 return syncer::SyncError( 51 FROM_HERE, syncer::SyncError::DATATYPE_ERROR, "Error", 52 syncer::PREFERENCES); 53 } 54 return syncer::SyncError(); 55 } 56 57 void FailNextProcessSyncChanges() { 58 fail_next_ = true; 59 } 60 61 virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) 62 const OVERRIDE { 63 return syncer::SyncDataList(); 64 } 65 private: 66 syncer::SyncChangeList* output_; 67 bool fail_next_; 68 }; 69 70 class PrefsSyncableServiceTest : public testing::Test { 71 public: 72 PrefsSyncableServiceTest() : 73 pref_sync_service_(NULL), 74 test_processor_(NULL), 75 next_pref_remote_sync_node_id_(0) {} 76 77 virtual void SetUp() { 78 prefs_.registry()->RegisterStringPref( 79 kUnsyncedPreferenceName, 80 kUnsyncedPreferenceDefaultValue, 81 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 82 prefs_.registry()->RegisterStringPref( 83 prefs::kHomePage, 84 std::string(), 85 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 86 prefs_.registry()->RegisterListPref( 87 prefs::kURLsToRestoreOnStartup, 88 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 89 prefs_.registry()->RegisterListPref( 90 prefs::kURLsToRestoreOnStartupOld, 91 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 92 prefs_.registry()->RegisterLocalizedStringPref( 93 prefs::kDefaultCharset, 94 IDS_DEFAULT_ENCODING, 95 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 96 97 pref_sync_service_ = reinterpret_cast<PrefModelAssociator*>( 98 prefs_.GetSyncableService(syncer::PREFERENCES)); 99 ASSERT_TRUE(pref_sync_service_); 100 next_pref_remote_sync_node_id_ = 0; 101 } 102 103 syncer::SyncChange MakeRemoteChange( 104 int64 id, 105 const std::string& name, 106 const base::Value& value, 107 SyncChange::SyncChangeType type) { 108 std::string serialized; 109 JSONStringValueSerializer json(&serialized); 110 if (!json.Serialize(value)) 111 return syncer::SyncChange(); 112 sync_pb::EntitySpecifics entity; 113 sync_pb::PreferenceSpecifics* pref_one = entity.mutable_preference(); 114 pref_one->set_name(name); 115 pref_one->set_value(serialized); 116 return syncer::SyncChange( 117 FROM_HERE, 118 type, 119 syncer::SyncData::CreateRemoteData( 120 id, 121 entity, 122 base::Time(), 123 syncer::AttachmentIdList(), 124 syncer::AttachmentServiceProxyForTest::Create())); 125 } 126 127 void AddToRemoteDataList(const std::string& name, 128 const base::Value& value, 129 syncer::SyncDataList* out) { 130 std::string serialized; 131 JSONStringValueSerializer json(&serialized); 132 ASSERT_TRUE(json.Serialize(value)); 133 sync_pb::EntitySpecifics one; 134 sync_pb::PreferenceSpecifics* pref_one = one.mutable_preference(); 135 pref_one->set_name(name); 136 pref_one->set_value(serialized); 137 out->push_back(SyncData::CreateRemoteData( 138 ++next_pref_remote_sync_node_id_, 139 one, 140 base::Time(), 141 syncer::AttachmentIdList(), 142 syncer::AttachmentServiceProxyForTest::Create())); 143 } 144 145 void InitWithSyncDataTakeOutput(const syncer::SyncDataList& initial_data, 146 syncer::SyncChangeList* output) { 147 test_processor_ = new TestSyncProcessorStub(output); 148 syncer::SyncMergeResult r = pref_sync_service_->MergeDataAndStartSyncing( 149 syncer::PREFERENCES, initial_data, 150 scoped_ptr<syncer::SyncChangeProcessor>(test_processor_), 151 scoped_ptr<syncer::SyncErrorFactory>( 152 new syncer::SyncErrorFactoryMock())); 153 EXPECT_FALSE(r.error().IsSet()); 154 } 155 156 void InitWithNoSyncData() { 157 InitWithSyncDataTakeOutput(syncer::SyncDataList(), NULL); 158 } 159 160 const base::Value& GetPreferenceValue(const std::string& name) { 161 const PrefService::Preference* preference = 162 prefs_.FindPreference(name.c_str()); 163 return *preference->GetValue(); 164 } 165 166 scoped_ptr<base::Value> FindValue(const std::string& name, 167 const syncer::SyncChangeList& list) { 168 syncer::SyncChangeList::const_iterator it = list.begin(); 169 for (; it != list.end(); ++it) { 170 if (syncer::SyncDataLocal(it->sync_data()).GetTag() == name) { 171 return make_scoped_ptr(base::JSONReader::Read( 172 it->sync_data().GetSpecifics().preference().value())); 173 } 174 } 175 return scoped_ptr<base::Value>(); 176 } 177 178 bool IsSynced(const std::string& pref_name) { 179 return pref_sync_service_->registered_preferences().count(pref_name) > 0; 180 } 181 182 bool HasSyncData(const std::string& pref_name) { 183 return pref_sync_service_->IsPrefSynced(pref_name); 184 } 185 186 // Returns whether a given preference name is a new name of a migrated 187 // preference. Exposed here for testing. 188 static bool IsMigratedPreference(const char* preference_name) { 189 return PrefModelAssociator::IsMigratedPreference(preference_name); 190 } 191 static bool IsOldMigratedPreference(const char* old_preference_name) { 192 return PrefModelAssociator::IsOldMigratedPreference(old_preference_name); 193 } 194 195 PrefService* GetPrefs() { return &prefs_; } 196 TestingPrefServiceSyncable* GetTestingPrefService() { return &prefs_; } 197 198 protected: 199 TestingPrefServiceSyncable prefs_; 200 201 PrefModelAssociator* pref_sync_service_; 202 TestSyncProcessorStub* test_processor_; 203 204 // TODO(tim): Remove this by fixing AttachmentServiceProxyForTest. 205 base::MessageLoop loop_; 206 207 int next_pref_remote_sync_node_id_; 208 }; 209 210 TEST_F(PrefsSyncableServiceTest, CreatePrefSyncData) { 211 prefs_.SetString(prefs::kHomePage, kExampleUrl0); 212 213 const PrefService::Preference* pref = 214 prefs_.FindPreference(prefs::kHomePage); 215 syncer::SyncData sync_data; 216 EXPECT_TRUE(pref_sync_service_->CreatePrefSyncData(pref->name(), 217 *pref->GetValue(), &sync_data)); 218 EXPECT_EQ(std::string(prefs::kHomePage), 219 syncer::SyncDataLocal(sync_data).GetTag()); 220 const sync_pb::PreferenceSpecifics& specifics(sync_data.GetSpecifics(). 221 preference()); 222 EXPECT_EQ(std::string(prefs::kHomePage), specifics.name()); 223 224 scoped_ptr<base::Value> value(base::JSONReader::Read(specifics.value())); 225 EXPECT_TRUE(pref->GetValue()->Equals(value.get())); 226 } 227 228 TEST_F(PrefsSyncableServiceTest, ModelAssociationDoNotSyncDefaults) { 229 const PrefService::Preference* pref = 230 prefs_.FindPreference(prefs::kHomePage); 231 EXPECT_TRUE(pref->IsDefaultValue()); 232 syncer::SyncChangeList out; 233 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); 234 235 EXPECT_TRUE(IsSynced(prefs::kHomePage)); 236 EXPECT_TRUE(pref->IsDefaultValue()); 237 EXPECT_FALSE(FindValue(prefs::kHomePage, out).get()); 238 } 239 240 TEST_F(PrefsSyncableServiceTest, ModelAssociationEmptyCloud) { 241 prefs_.SetString(prefs::kHomePage, kExampleUrl0); 242 { 243 ListPrefUpdate update(GetPrefs(), prefs::kURLsToRestoreOnStartup); 244 base::ListValue* url_list = update.Get(); 245 url_list->Append(new base::StringValue(kExampleUrl0)); 246 url_list->Append(new base::StringValue(kExampleUrl1)); 247 } 248 syncer::SyncChangeList out; 249 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); 250 251 scoped_ptr<base::Value> value(FindValue(prefs::kHomePage, out)); 252 ASSERT_TRUE(value.get()); 253 EXPECT_TRUE(GetPreferenceValue(prefs::kHomePage).Equals(value.get())); 254 value = FindValue(prefs::kURLsToRestoreOnStartup, out).Pass(); 255 ASSERT_TRUE(value.get()); 256 EXPECT_TRUE( 257 GetPreferenceValue(prefs::kURLsToRestoreOnStartup).Equals(value.get())); 258 } 259 260 TEST_F(PrefsSyncableServiceTest, ModelAssociationCloudHasData) { 261 prefs_.SetString(prefs::kHomePage, kExampleUrl0); 262 { 263 ListPrefUpdate update(GetPrefs(), prefs::kURLsToRestoreOnStartup); 264 base::ListValue* url_list = update.Get(); 265 url_list->Append(new base::StringValue(kExampleUrl0)); 266 url_list->Append(new base::StringValue(kExampleUrl1)); 267 } 268 269 syncer::SyncDataList in; 270 syncer::SyncChangeList out; 271 AddToRemoteDataList(prefs::kHomePage, base::StringValue(kExampleUrl1), &in); 272 base::ListValue urls_to_restore; 273 urls_to_restore.Append(new base::StringValue(kExampleUrl1)); 274 urls_to_restore.Append(new base::StringValue(kExampleUrl2)); 275 AddToRemoteDataList(prefs::kURLsToRestoreOnStartup, urls_to_restore, &in); 276 AddToRemoteDataList(prefs::kDefaultCharset, 277 base::StringValue(kNonDefaultCharsetValue), 278 &in); 279 InitWithSyncDataTakeOutput(in, &out); 280 281 ASSERT_FALSE(FindValue(prefs::kHomePage, out).get()); 282 ASSERT_FALSE(FindValue(prefs::kDefaultCharset, out).get()); 283 284 EXPECT_EQ(kExampleUrl1, prefs_.GetString(prefs::kHomePage)); 285 286 scoped_ptr<base::ListValue> expected_urls(new base::ListValue); 287 expected_urls->Append(new base::StringValue(kExampleUrl1)); 288 expected_urls->Append(new base::StringValue(kExampleUrl2)); 289 expected_urls->Append(new base::StringValue(kExampleUrl0)); 290 scoped_ptr<base::Value> value( 291 FindValue(prefs::kURLsToRestoreOnStartup, out)); 292 ASSERT_TRUE(value.get()); 293 EXPECT_TRUE(value->Equals(expected_urls.get())); 294 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup). 295 Equals(expected_urls.get())); 296 EXPECT_EQ(kNonDefaultCharsetValue, 297 prefs_.GetString(prefs::kDefaultCharset)); 298 } 299 300 TEST_F(PrefsSyncableServiceTest, ModelAssociationMigrateOldData) { 301 ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup)); 302 ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld)); 303 304 syncer::SyncDataList in; 305 syncer::SyncChangeList out; 306 base::ListValue urls_to_restore; 307 urls_to_restore.Append(new base::StringValue(kExampleUrl1)); 308 urls_to_restore.Append(new base::StringValue(kExampleUrl2)); 309 AddToRemoteDataList(prefs::kURLsToRestoreOnStartupOld, urls_to_restore, 310 &in); 311 InitWithSyncDataTakeOutput(in, &out); 312 313 // Expect that the new preference data contains the old pref's values. 314 scoped_ptr<base::ListValue> expected_urls(new base::ListValue); 315 expected_urls->Append(new base::StringValue(kExampleUrl1)); 316 expected_urls->Append(new base::StringValue(kExampleUrl2)); 317 318 ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup)); 319 scoped_ptr<base::Value> value( 320 FindValue(prefs::kURLsToRestoreOnStartup, out)); 321 ASSERT_TRUE(value.get()); 322 EXPECT_TRUE(value->Equals(expected_urls.get())); 323 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup). 324 Equals(expected_urls.get())); 325 326 // The old preference value should be the same. 327 expected_urls.reset(new base::ListValue); 328 ASSERT_FALSE(FindValue(prefs::kURLsToRestoreOnStartupOld, out).get()); 329 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld). 330 Equals(expected_urls.get())); 331 } 332 333 TEST_F(PrefsSyncableServiceTest, 334 ModelAssociationCloudHasOldMigratedData) { 335 ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup)); 336 ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld)); 337 prefs_.SetString(prefs::kHomePage, kExampleUrl0); 338 { 339 ListPrefUpdate update(GetPrefs(), prefs::kURLsToRestoreOnStartup); 340 base::ListValue* url_list = update.Get(); 341 url_list->Append(new base::StringValue(kExampleUrl0)); 342 url_list->Append(new base::StringValue(kExampleUrl1)); 343 } 344 345 syncer::SyncDataList in; 346 syncer::SyncChangeList out; 347 base::ListValue urls_to_restore; 348 urls_to_restore.Append(new base::StringValue(kExampleUrl1)); 349 urls_to_restore.Append(new base::StringValue(kExampleUrl2)); 350 AddToRemoteDataList(prefs::kURLsToRestoreOnStartupOld, urls_to_restore, &in); 351 AddToRemoteDataList(prefs::kHomePage, base::StringValue(kExampleUrl1), &in); 352 InitWithSyncDataTakeOutput(in, &out); 353 354 ASSERT_FALSE(FindValue(prefs::kHomePage, out).get()); 355 356 // Expect that the new preference data contains the merged old prefs values. 357 scoped_ptr<base::ListValue> expected_urls(new base::ListValue); 358 expected_urls->Append(new base::StringValue(kExampleUrl1)); 359 expected_urls->Append(new base::StringValue(kExampleUrl2)); 360 expected_urls->Append(new base::StringValue(kExampleUrl0)); 361 362 ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup)); 363 scoped_ptr<base::Value> value( 364 FindValue(prefs::kURLsToRestoreOnStartup, out)); 365 ASSERT_TRUE(value.get()); 366 EXPECT_TRUE(value->Equals(expected_urls.get())); 367 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup). 368 Equals(expected_urls.get())); 369 370 expected_urls.reset(new base::ListValue); 371 value = FindValue(prefs::kURLsToRestoreOnStartupOld, out).Pass(); 372 ASSERT_TRUE(value.get()); 373 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld). 374 Equals(expected_urls.get())); 375 } 376 377 TEST_F(PrefsSyncableServiceTest, 378 ModelAssociationCloudHasNewMigratedData) { 379 ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup)); 380 ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld)); 381 prefs_.SetString(prefs::kHomePage, kExampleUrl0); 382 { 383 ListPrefUpdate update(GetPrefs(), prefs::kURLsToRestoreOnStartupOld); 384 base::ListValue* url_list = update.Get(); 385 url_list->Append(new base::StringValue(kExampleUrl0)); 386 url_list->Append(new base::StringValue(kExampleUrl1)); 387 } 388 389 syncer::SyncDataList in; 390 syncer::SyncChangeList out; 391 base::ListValue urls_to_restore; 392 urls_to_restore.Append(new base::StringValue(kExampleUrl1)); 393 urls_to_restore.Append(new base::StringValue(kExampleUrl2)); 394 AddToRemoteDataList(prefs::kURLsToRestoreOnStartupOld, urls_to_restore, &in); 395 AddToRemoteDataList(prefs::kHomePage, base::StringValue(kExampleUrl1), &in); 396 InitWithSyncDataTakeOutput(in, &out); 397 398 scoped_ptr<base::Value> value(FindValue(prefs::kHomePage, out)); 399 ASSERT_FALSE(value.get()); 400 401 // Expect that the cloud data under the new migrated preference name sticks. 402 scoped_ptr<base::ListValue> expected_urls(new base::ListValue); 403 expected_urls->Append(new base::StringValue(kExampleUrl1)); 404 expected_urls->Append(new base::StringValue(kExampleUrl2)); 405 406 ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup)); 407 value = FindValue(prefs::kURLsToRestoreOnStartup, out).Pass(); 408 ASSERT_TRUE(value.get()); 409 EXPECT_TRUE(value->Equals(expected_urls.get())); 410 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup). 411 Equals(expected_urls.get())); 412 413 // The old preference data should still be here, though not synced. 414 expected_urls.reset(new base::ListValue); 415 expected_urls->Append(new base::StringValue(kExampleUrl0)); 416 expected_urls->Append(new base::StringValue(kExampleUrl1)); 417 418 value = FindValue(prefs::kURLsToRestoreOnStartupOld, out).Pass(); 419 ASSERT_FALSE(value.get()); 420 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld). 421 Equals(expected_urls.get())); 422 } 423 424 TEST_F(PrefsSyncableServiceTest, 425 ModelAssociationCloudAddsOldAndNewMigratedData) { 426 ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup)); 427 ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld)); 428 prefs_.SetString(prefs::kHomePage, kExampleUrl0); 429 { 430 ListPrefUpdate update_old(GetPrefs(), prefs::kURLsToRestoreOnStartupOld); 431 base::ListValue* url_list_old = update_old.Get(); 432 url_list_old->Append(new base::StringValue(kExampleUrl0)); 433 url_list_old->Append(new base::StringValue(kExampleUrl1)); 434 ListPrefUpdate update(GetPrefs(), prefs::kURLsToRestoreOnStartup); 435 base::ListValue* url_list = update.Get(); 436 url_list->Append(new base::StringValue(kExampleUrl1)); 437 url_list->Append(new base::StringValue(kExampleUrl2)); 438 } 439 440 syncer::SyncDataList in; 441 syncer::SyncChangeList out; 442 AddToRemoteDataList(prefs::kHomePage, base::StringValue(kExampleUrl1), &in); 443 InitWithSyncDataTakeOutput(in, &out); 444 445 scoped_ptr<base::Value> value(FindValue(prefs::kHomePage, out)); 446 ASSERT_FALSE(value.get()); 447 448 // Expect that the cloud data under the new migrated preference name sticks. 449 scoped_ptr<base::ListValue> expected_urls(new base::ListValue); 450 expected_urls->Append(new base::StringValue(kExampleUrl1)); 451 expected_urls->Append(new base::StringValue(kExampleUrl2)); 452 453 ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup)); 454 value = FindValue(prefs::kURLsToRestoreOnStartup, out).Pass(); 455 ASSERT_TRUE(value.get()); 456 EXPECT_TRUE(value->Equals(expected_urls.get())); 457 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup). 458 Equals(expected_urls.get())); 459 460 // Should not have synced in the old startup url values. 461 value = FindValue(prefs::kURLsToRestoreOnStartupOld, out).Pass(); 462 ASSERT_FALSE(value.get()); 463 EXPECT_FALSE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld). 464 Equals(expected_urls.get())); 465 } 466 467 TEST_F(PrefsSyncableServiceTest, FailModelAssociation) { 468 syncer::SyncChangeList output; 469 TestSyncProcessorStub* stub = new TestSyncProcessorStub(&output); 470 stub->FailNextProcessSyncChanges(); 471 syncer::SyncMergeResult r = pref_sync_service_->MergeDataAndStartSyncing( 472 syncer::PREFERENCES, syncer::SyncDataList(), 473 scoped_ptr<syncer::SyncChangeProcessor>(stub), 474 scoped_ptr<syncer::SyncErrorFactory>( 475 new syncer::SyncErrorFactoryMock())); 476 EXPECT_TRUE(r.error().IsSet()); 477 } 478 479 TEST_F(PrefsSyncableServiceTest, UpdatedPreferenceWithDefaultValue) { 480 const PrefService::Preference* pref = 481 prefs_.FindPreference(prefs::kHomePage); 482 EXPECT_TRUE(pref->IsDefaultValue()); 483 484 syncer::SyncChangeList out; 485 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); 486 out.clear(); 487 488 base::StringValue expected(kExampleUrl0); 489 GetPrefs()->Set(prefs::kHomePage, expected); 490 491 scoped_ptr<base::Value> actual(FindValue(prefs::kHomePage, out)); 492 ASSERT_TRUE(actual.get()); 493 EXPECT_TRUE(expected.Equals(actual.get())); 494 } 495 496 TEST_F(PrefsSyncableServiceTest, UpdatedPreferenceWithValue) { 497 GetPrefs()->SetString(prefs::kHomePage, kExampleUrl0); 498 syncer::SyncChangeList out; 499 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); 500 out.clear(); 501 502 base::StringValue expected(kExampleUrl1); 503 GetPrefs()->Set(prefs::kHomePage, expected); 504 505 scoped_ptr<base::Value> actual(FindValue(prefs::kHomePage, out)); 506 ASSERT_TRUE(actual.get()); 507 EXPECT_TRUE(expected.Equals(actual.get())); 508 } 509 510 TEST_F(PrefsSyncableServiceTest, UpdatedSyncNodeActionUpdate) { 511 GetPrefs()->SetString(prefs::kHomePage, kExampleUrl0); 512 InitWithNoSyncData(); 513 514 base::StringValue expected(kExampleUrl1); 515 syncer::SyncChangeList list; 516 list.push_back(MakeRemoteChange( 517 1, prefs::kHomePage, expected, SyncChange::ACTION_UPDATE)); 518 pref_sync_service_->ProcessSyncChanges(FROM_HERE, list); 519 520 const base::Value& actual = GetPreferenceValue(prefs::kHomePage); 521 EXPECT_TRUE(expected.Equals(&actual)); 522 } 523 524 TEST_F(PrefsSyncableServiceTest, UpdatedSyncNodeActionAdd) { 525 InitWithNoSyncData(); 526 527 base::StringValue expected(kExampleUrl0); 528 syncer::SyncChangeList list; 529 list.push_back(MakeRemoteChange( 530 1, prefs::kHomePage, expected, SyncChange::ACTION_ADD)); 531 pref_sync_service_->ProcessSyncChanges(FROM_HERE, list); 532 533 const base::Value& actual = GetPreferenceValue(prefs::kHomePage); 534 EXPECT_TRUE(expected.Equals(&actual)); 535 EXPECT_EQ(1U, 536 pref_sync_service_->registered_preferences().count(prefs::kHomePage)); 537 } 538 539 TEST_F(PrefsSyncableServiceTest, UpdatedSyncNodeUnknownPreference) { 540 InitWithNoSyncData(); 541 syncer::SyncChangeList list; 542 base::StringValue expected(kExampleUrl0); 543 list.push_back(MakeRemoteChange( 544 1, "unknown preference", expected, SyncChange::ACTION_UPDATE)); 545 pref_sync_service_->ProcessSyncChanges(FROM_HERE, list); 546 // Nothing interesting happens on the client when it gets an update 547 // of an unknown preference. We just should not crash. 548 } 549 550 TEST_F(PrefsSyncableServiceTest, ManagedPreferences) { 551 // Make the homepage preference managed. 552 base::StringValue managed_value("http://example.com"); 553 prefs_.SetManagedPref(prefs::kHomePage, managed_value.DeepCopy()); 554 555 syncer::SyncChangeList out; 556 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); 557 out.clear(); 558 559 // Changing the homepage preference should not sync anything. 560 base::StringValue user_value("http://chromium..com"); 561 prefs_.SetUserPref(prefs::kHomePage, user_value.DeepCopy()); 562 EXPECT_TRUE(out.empty()); 563 564 // An incoming sync transaction should change the user value, not the managed 565 // value. 566 base::StringValue sync_value("http://crbug.com"); 567 syncer::SyncChangeList list; 568 list.push_back(MakeRemoteChange( 569 1, prefs::kHomePage, sync_value, SyncChange::ACTION_UPDATE)); 570 pref_sync_service_->ProcessSyncChanges(FROM_HERE, list); 571 572 EXPECT_TRUE(managed_value.Equals(prefs_.GetManagedPref(prefs::kHomePage))); 573 EXPECT_TRUE(sync_value.Equals(prefs_.GetUserPref(prefs::kHomePage))); 574 } 575 576 // List preferences have special handling at association time due to our ability 577 // to merge the local and sync value. Make sure the merge logic doesn't merge 578 // managed preferences. 579 TEST_F(PrefsSyncableServiceTest, ManagedListPreferences) { 580 // Make the list of urls to restore on startup managed. 581 base::ListValue managed_value; 582 managed_value.Append(new base::StringValue(kExampleUrl0)); 583 managed_value.Append(new base::StringValue(kExampleUrl1)); 584 prefs_.SetManagedPref(prefs::kURLsToRestoreOnStartup, 585 managed_value.DeepCopy()); 586 587 // Set a cloud version. 588 syncer::SyncDataList in; 589 syncer::SyncChangeList out; 590 base::ListValue urls_to_restore; 591 urls_to_restore.Append(new base::StringValue(kExampleUrl1)); 592 urls_to_restore.Append(new base::StringValue(kExampleUrl2)); 593 AddToRemoteDataList(prefs::kURLsToRestoreOnStartup, urls_to_restore, &in); 594 595 // Start sync and verify the synced value didn't get merged. 596 InitWithSyncDataTakeOutput(in, &out); 597 EXPECT_FALSE(FindValue(prefs::kURLsToRestoreOnStartup, out).get()); 598 out.clear(); 599 600 // Changing the user's urls to restore on startup pref should not sync 601 // anything. 602 base::ListValue user_value; 603 user_value.Append(new base::StringValue("http://chromium.org")); 604 prefs_.SetUserPref(prefs::kURLsToRestoreOnStartup, user_value.DeepCopy()); 605 EXPECT_FALSE(FindValue(prefs::kURLsToRestoreOnStartup, out).get()); 606 607 // An incoming sync transaction should change the user value, not the managed 608 // value. 609 base::ListValue sync_value; 610 sync_value.Append(new base::StringValue("http://crbug.com")); 611 syncer::SyncChangeList list; 612 list.push_back(MakeRemoteChange( 613 1, prefs::kURLsToRestoreOnStartup, sync_value, 614 SyncChange::ACTION_UPDATE)); 615 pref_sync_service_->ProcessSyncChanges(FROM_HERE, list); 616 617 EXPECT_TRUE(managed_value.Equals( 618 prefs_.GetManagedPref(prefs::kURLsToRestoreOnStartup))); 619 EXPECT_TRUE(sync_value.Equals( 620 prefs_.GetUserPref(prefs::kURLsToRestoreOnStartup))); 621 } 622 623 TEST_F(PrefsSyncableServiceTest, DynamicManagedPreferences) { 624 syncer::SyncChangeList out; 625 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); 626 out.clear(); 627 base::StringValue initial_value("http://example.com/initial"); 628 GetPrefs()->Set(prefs::kHomePage, initial_value); 629 scoped_ptr<base::Value> actual(FindValue(prefs::kHomePage, out)); 630 ASSERT_TRUE(actual.get()); 631 EXPECT_TRUE(initial_value.Equals(actual.get())); 632 633 // Switch kHomePage to managed and set a different value. 634 base::StringValue managed_value("http://example.com/managed"); 635 GetTestingPrefService()->SetManagedPref(prefs::kHomePage, 636 managed_value.DeepCopy()); 637 638 // The pref value should be the one dictated by policy. 639 EXPECT_TRUE(managed_value.Equals(&GetPreferenceValue(prefs::kHomePage))); 640 641 // Switch kHomePage back to unmanaged. 642 GetTestingPrefService()->RemoveManagedPref(prefs::kHomePage); 643 644 // The original value should be picked up. 645 EXPECT_TRUE(initial_value.Equals(&GetPreferenceValue(prefs::kHomePage))); 646 } 647 648 TEST_F(PrefsSyncableServiceTest, 649 DynamicManagedPreferencesWithSyncChange) { 650 syncer::SyncChangeList out; 651 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); 652 out.clear(); 653 654 base::StringValue initial_value("http://example.com/initial"); 655 GetPrefs()->Set(prefs::kHomePage, initial_value); 656 scoped_ptr<base::Value> actual(FindValue(prefs::kHomePage, out)); 657 EXPECT_TRUE(initial_value.Equals(actual.get())); 658 659 // Switch kHomePage to managed and set a different value. 660 base::StringValue managed_value("http://example.com/managed"); 661 GetTestingPrefService()->SetManagedPref(prefs::kHomePage, 662 managed_value.DeepCopy()); 663 664 // Change the sync value. 665 base::StringValue sync_value("http://example.com/sync"); 666 syncer::SyncChangeList list; 667 list.push_back(MakeRemoteChange( 668 1, prefs::kHomePage, sync_value, SyncChange::ACTION_UPDATE)); 669 pref_sync_service_->ProcessSyncChanges(FROM_HERE, list); 670 671 // The pref value should still be the one dictated by policy. 672 EXPECT_TRUE(managed_value.Equals(&GetPreferenceValue(prefs::kHomePage))); 673 674 // Switch kHomePage back to unmanaged. 675 GetTestingPrefService()->RemoveManagedPref(prefs::kHomePage); 676 677 // Sync value should be picked up. 678 EXPECT_TRUE(sync_value.Equals(&GetPreferenceValue(prefs::kHomePage))); 679 } 680 681 TEST_F(PrefsSyncableServiceTest, DynamicManagedDefaultPreferences) { 682 const PrefService::Preference* pref = 683 prefs_.FindPreference(prefs::kHomePage); 684 EXPECT_TRUE(pref->IsDefaultValue()); 685 syncer::SyncChangeList out; 686 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); 687 688 EXPECT_TRUE(IsSynced(prefs::kHomePage)); 689 EXPECT_TRUE(pref->IsDefaultValue()); 690 EXPECT_FALSE(FindValue(prefs::kHomePage, out).get()); 691 out.clear(); 692 693 // Switch kHomePage to managed and set a different value. 694 base::StringValue managed_value("http://example.com/managed"); 695 GetTestingPrefService()->SetManagedPref(prefs::kHomePage, 696 managed_value.DeepCopy()); 697 // The pref value should be the one dictated by policy. 698 EXPECT_TRUE(managed_value.Equals(&GetPreferenceValue(prefs::kHomePage))); 699 EXPECT_FALSE(pref->IsDefaultValue()); 700 // There should be no synced value. 701 EXPECT_FALSE(FindValue(prefs::kHomePage, out).get()); 702 // Switch kHomePage back to unmanaged. 703 GetTestingPrefService()->RemoveManagedPref(prefs::kHomePage); 704 // The original value should be picked up. 705 EXPECT_TRUE(pref->IsDefaultValue()); 706 // There should still be no synced value. 707 EXPECT_FALSE(FindValue(prefs::kHomePage, out).get()); 708 } 709 710 TEST_F(PrefsSyncableServiceTest, DeletePreference) { 711 prefs_.SetString(prefs::kHomePage, kExampleUrl0); 712 const PrefService::Preference* pref = 713 prefs_.FindPreference(prefs::kHomePage); 714 EXPECT_FALSE(pref->IsDefaultValue()); 715 716 InitWithNoSyncData(); 717 718 scoped_ptr<base::Value> null_value(base::Value::CreateNullValue()); 719 syncer::SyncChangeList list; 720 list.push_back(MakeRemoteChange( 721 1, prefs::kHomePage, *null_value, SyncChange::ACTION_DELETE)); 722 pref_sync_service_->ProcessSyncChanges(FROM_HERE, list); 723 EXPECT_TRUE(pref->IsDefaultValue()); 724 } 725