| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/json/json_reader.h" |
| #include "base/json/json_string_value_serializer.h" |
| #include "base/json/json_writer.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/prefs/scoped_user_pref_update.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "chrome/browser/prefs/pref_model_associator.h" |
| #include "chrome/browser/prefs/pref_service_syncable.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/grit/locale_settings.h" |
| #include "chrome/test/base/testing_pref_service_syncable.h" |
| #include "components/pref_registry/pref_registry_syncable.h" |
| #include "sync/api/attachments/attachment_id.h" |
| #include "sync/api/sync_change.h" |
| #include "sync/api/sync_data.h" |
| #include "sync/api/sync_error_factory_mock.h" |
| #include "sync/api/syncable_service.h" |
| #include "sync/internal_api/public/attachments/attachment_service_proxy_for_test.h" |
| #include "sync/protocol/preference_specifics.pb.h" |
| #include "sync/protocol/sync.pb.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using syncer::SyncChange; |
| using syncer::SyncData; |
| |
| namespace { |
| const char kExampleUrl0[] = "http://example.com/0"; |
| const char kExampleUrl1[] = "http://example.com/1"; |
| const char kExampleUrl2[] = "http://example.com/2"; |
| const char kUnsyncedPreferenceName[] = "nonsense_pref_name"; |
| const char kUnsyncedPreferenceDefaultValue[] = "default"; |
| const char kNonDefaultCharsetValue[] = "foo"; |
| } // namespace |
| |
| class TestSyncProcessorStub : public syncer::SyncChangeProcessor { |
| public: |
| explicit TestSyncProcessorStub(syncer::SyncChangeList* output) |
| : output_(output), fail_next_(false) {} |
| syncer::SyncError ProcessSyncChanges( |
| const tracked_objects::Location& from_here, |
| const syncer::SyncChangeList& change_list) override { |
| if (output_) |
| output_->insert(output_->end(), change_list.begin(), change_list.end()); |
| if (fail_next_) { |
| fail_next_ = false; |
| return syncer::SyncError( |
| FROM_HERE, syncer::SyncError::DATATYPE_ERROR, "Error", |
| syncer::PREFERENCES); |
| } |
| return syncer::SyncError(); |
| } |
| |
| void FailNextProcessSyncChanges() { |
| fail_next_ = true; |
| } |
| |
| syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override { |
| return syncer::SyncDataList(); |
| } |
| private: |
| syncer::SyncChangeList* output_; |
| bool fail_next_; |
| }; |
| |
| class PrefsSyncableServiceTest : public testing::Test { |
| public: |
| PrefsSyncableServiceTest() : |
| pref_sync_service_(NULL), |
| test_processor_(NULL), |
| next_pref_remote_sync_node_id_(0) {} |
| |
| void SetUp() override { |
| prefs_.registry()->RegisterStringPref( |
| kUnsyncedPreferenceName, |
| kUnsyncedPreferenceDefaultValue, |
| user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| prefs_.registry()->RegisterStringPref( |
| prefs::kHomePage, |
| std::string(), |
| user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); |
| prefs_.registry()->RegisterListPref( |
| prefs::kURLsToRestoreOnStartup, |
| user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); |
| prefs_.registry()->RegisterListPref( |
| prefs::kURLsToRestoreOnStartupOld, |
| user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| prefs_.registry()->RegisterLocalizedStringPref( |
| prefs::kDefaultCharset, |
| IDS_DEFAULT_ENCODING, |
| user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); |
| |
| pref_sync_service_ = reinterpret_cast<PrefModelAssociator*>( |
| prefs_.GetSyncableService(syncer::PREFERENCES)); |
| ASSERT_TRUE(pref_sync_service_); |
| next_pref_remote_sync_node_id_ = 0; |
| } |
| |
| syncer::SyncChange MakeRemoteChange( |
| int64 id, |
| const std::string& name, |
| const base::Value& value, |
| SyncChange::SyncChangeType type) { |
| std::string serialized; |
| JSONStringValueSerializer json(&serialized); |
| if (!json.Serialize(value)) |
| return syncer::SyncChange(); |
| sync_pb::EntitySpecifics entity; |
| sync_pb::PreferenceSpecifics* pref_one = entity.mutable_preference(); |
| pref_one->set_name(name); |
| pref_one->set_value(serialized); |
| return syncer::SyncChange( |
| FROM_HERE, |
| type, |
| syncer::SyncData::CreateRemoteData( |
| id, |
| entity, |
| base::Time(), |
| syncer::AttachmentIdList(), |
| syncer::AttachmentServiceProxyForTest::Create())); |
| } |
| |
| void AddToRemoteDataList(const std::string& name, |
| const base::Value& value, |
| syncer::SyncDataList* out) { |
| std::string serialized; |
| JSONStringValueSerializer json(&serialized); |
| ASSERT_TRUE(json.Serialize(value)); |
| sync_pb::EntitySpecifics one; |
| sync_pb::PreferenceSpecifics* pref_one = one.mutable_preference(); |
| pref_one->set_name(name); |
| pref_one->set_value(serialized); |
| out->push_back(SyncData::CreateRemoteData( |
| ++next_pref_remote_sync_node_id_, |
| one, |
| base::Time(), |
| syncer::AttachmentIdList(), |
| syncer::AttachmentServiceProxyForTest::Create())); |
| } |
| |
| void InitWithSyncDataTakeOutput(const syncer::SyncDataList& initial_data, |
| syncer::SyncChangeList* output) { |
| test_processor_ = new TestSyncProcessorStub(output); |
| syncer::SyncMergeResult r = pref_sync_service_->MergeDataAndStartSyncing( |
| syncer::PREFERENCES, initial_data, |
| scoped_ptr<syncer::SyncChangeProcessor>(test_processor_), |
| scoped_ptr<syncer::SyncErrorFactory>( |
| new syncer::SyncErrorFactoryMock())); |
| EXPECT_FALSE(r.error().IsSet()); |
| } |
| |
| void InitWithNoSyncData() { |
| InitWithSyncDataTakeOutput(syncer::SyncDataList(), NULL); |
| } |
| |
| const base::Value& GetPreferenceValue(const std::string& name) { |
| const PrefService::Preference* preference = |
| prefs_.FindPreference(name.c_str()); |
| return *preference->GetValue(); |
| } |
| |
| scoped_ptr<base::Value> FindValue(const std::string& name, |
| const syncer::SyncChangeList& list) { |
| syncer::SyncChangeList::const_iterator it = list.begin(); |
| for (; it != list.end(); ++it) { |
| if (syncer::SyncDataLocal(it->sync_data()).GetTag() == name) { |
| return make_scoped_ptr(base::JSONReader::Read( |
| it->sync_data().GetSpecifics().preference().value())); |
| } |
| } |
| return scoped_ptr<base::Value>(); |
| } |
| |
| bool IsSynced(const std::string& pref_name) { |
| return pref_sync_service_->registered_preferences().count(pref_name) > 0; |
| } |
| |
| bool HasSyncData(const std::string& pref_name) { |
| return pref_sync_service_->IsPrefSynced(pref_name); |
| } |
| |
| // Returns whether a given preference name is a new name of a migrated |
| // preference. Exposed here for testing. |
| static bool IsMigratedPreference(const char* preference_name) { |
| return PrefModelAssociator::IsMigratedPreference(preference_name); |
| } |
| static bool IsOldMigratedPreference(const char* old_preference_name) { |
| return PrefModelAssociator::IsOldMigratedPreference(old_preference_name); |
| } |
| |
| PrefService* GetPrefs() { return &prefs_; } |
| TestingPrefServiceSyncable* GetTestingPrefService() { return &prefs_; } |
| |
| protected: |
| TestingPrefServiceSyncable prefs_; |
| |
| PrefModelAssociator* pref_sync_service_; |
| TestSyncProcessorStub* test_processor_; |
| |
| // TODO(tim): Remove this by fixing AttachmentServiceProxyForTest. |
| base::MessageLoop loop_; |
| |
| int next_pref_remote_sync_node_id_; |
| }; |
| |
| TEST_F(PrefsSyncableServiceTest, CreatePrefSyncData) { |
| prefs_.SetString(prefs::kHomePage, kExampleUrl0); |
| |
| const PrefService::Preference* pref = |
| prefs_.FindPreference(prefs::kHomePage); |
| syncer::SyncData sync_data; |
| EXPECT_TRUE(pref_sync_service_->CreatePrefSyncData(pref->name(), |
| *pref->GetValue(), &sync_data)); |
| EXPECT_EQ(std::string(prefs::kHomePage), |
| syncer::SyncDataLocal(sync_data).GetTag()); |
| const sync_pb::PreferenceSpecifics& specifics(sync_data.GetSpecifics(). |
| preference()); |
| EXPECT_EQ(std::string(prefs::kHomePage), specifics.name()); |
| |
| scoped_ptr<base::Value> value(base::JSONReader::Read(specifics.value())); |
| EXPECT_TRUE(pref->GetValue()->Equals(value.get())); |
| } |
| |
| TEST_F(PrefsSyncableServiceTest, ModelAssociationDoNotSyncDefaults) { |
| const PrefService::Preference* pref = |
| prefs_.FindPreference(prefs::kHomePage); |
| EXPECT_TRUE(pref->IsDefaultValue()); |
| syncer::SyncChangeList out; |
| InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); |
| |
| EXPECT_TRUE(IsSynced(prefs::kHomePage)); |
| EXPECT_TRUE(pref->IsDefaultValue()); |
| EXPECT_FALSE(FindValue(prefs::kHomePage, out).get()); |
| } |
| |
| TEST_F(PrefsSyncableServiceTest, ModelAssociationEmptyCloud) { |
| prefs_.SetString(prefs::kHomePage, kExampleUrl0); |
| { |
| ListPrefUpdate update(GetPrefs(), prefs::kURLsToRestoreOnStartup); |
| base::ListValue* url_list = update.Get(); |
| url_list->Append(new base::StringValue(kExampleUrl0)); |
| url_list->Append(new base::StringValue(kExampleUrl1)); |
| } |
| syncer::SyncChangeList out; |
| InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); |
| |
| scoped_ptr<base::Value> value(FindValue(prefs::kHomePage, out)); |
| ASSERT_TRUE(value.get()); |
| EXPECT_TRUE(GetPreferenceValue(prefs::kHomePage).Equals(value.get())); |
| value = FindValue(prefs::kURLsToRestoreOnStartup, out).Pass(); |
| ASSERT_TRUE(value.get()); |
| EXPECT_TRUE( |
| GetPreferenceValue(prefs::kURLsToRestoreOnStartup).Equals(value.get())); |
| } |
| |
| TEST_F(PrefsSyncableServiceTest, ModelAssociationCloudHasData) { |
| prefs_.SetString(prefs::kHomePage, kExampleUrl0); |
| { |
| ListPrefUpdate update(GetPrefs(), prefs::kURLsToRestoreOnStartup); |
| base::ListValue* url_list = update.Get(); |
| url_list->Append(new base::StringValue(kExampleUrl0)); |
| url_list->Append(new base::StringValue(kExampleUrl1)); |
| } |
| |
| syncer::SyncDataList in; |
| syncer::SyncChangeList out; |
| AddToRemoteDataList(prefs::kHomePage, base::StringValue(kExampleUrl1), &in); |
| base::ListValue urls_to_restore; |
| urls_to_restore.Append(new base::StringValue(kExampleUrl1)); |
| urls_to_restore.Append(new base::StringValue(kExampleUrl2)); |
| AddToRemoteDataList(prefs::kURLsToRestoreOnStartup, urls_to_restore, &in); |
| AddToRemoteDataList(prefs::kDefaultCharset, |
| base::StringValue(kNonDefaultCharsetValue), |
| &in); |
| InitWithSyncDataTakeOutput(in, &out); |
| |
| ASSERT_FALSE(FindValue(prefs::kHomePage, out).get()); |
| ASSERT_FALSE(FindValue(prefs::kDefaultCharset, out).get()); |
| |
| EXPECT_EQ(kExampleUrl1, prefs_.GetString(prefs::kHomePage)); |
| |
| scoped_ptr<base::ListValue> expected_urls(new base::ListValue); |
| expected_urls->Append(new base::StringValue(kExampleUrl1)); |
| expected_urls->Append(new base::StringValue(kExampleUrl2)); |
| expected_urls->Append(new base::StringValue(kExampleUrl0)); |
| scoped_ptr<base::Value> value( |
| FindValue(prefs::kURLsToRestoreOnStartup, out)); |
| ASSERT_TRUE(value.get()); |
| EXPECT_TRUE(value->Equals(expected_urls.get())); |
| EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup). |
| Equals(expected_urls.get())); |
| EXPECT_EQ(kNonDefaultCharsetValue, |
| prefs_.GetString(prefs::kDefaultCharset)); |
| } |
| |
| TEST_F(PrefsSyncableServiceTest, ModelAssociationMigrateOldData) { |
| ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup)); |
| ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld)); |
| |
| syncer::SyncDataList in; |
| syncer::SyncChangeList out; |
| base::ListValue urls_to_restore; |
| urls_to_restore.Append(new base::StringValue(kExampleUrl1)); |
| urls_to_restore.Append(new base::StringValue(kExampleUrl2)); |
| AddToRemoteDataList(prefs::kURLsToRestoreOnStartupOld, urls_to_restore, |
| &in); |
| InitWithSyncDataTakeOutput(in, &out); |
| |
| // Expect that the new preference data contains the old pref's values. |
| scoped_ptr<base::ListValue> expected_urls(new base::ListValue); |
| expected_urls->Append(new base::StringValue(kExampleUrl1)); |
| expected_urls->Append(new base::StringValue(kExampleUrl2)); |
| |
| ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup)); |
| scoped_ptr<base::Value> value( |
| FindValue(prefs::kURLsToRestoreOnStartup, out)); |
| ASSERT_TRUE(value.get()); |
| EXPECT_TRUE(value->Equals(expected_urls.get())); |
| EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup). |
| Equals(expected_urls.get())); |
| |
| // The old preference value should be the same. |
| expected_urls.reset(new base::ListValue); |
| ASSERT_FALSE(FindValue(prefs::kURLsToRestoreOnStartupOld, out).get()); |
| EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld). |
| Equals(expected_urls.get())); |
| } |
| |
| TEST_F(PrefsSyncableServiceTest, |
| ModelAssociationCloudHasOldMigratedData) { |
| ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup)); |
| ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld)); |
| prefs_.SetString(prefs::kHomePage, kExampleUrl0); |
| { |
| ListPrefUpdate update(GetPrefs(), prefs::kURLsToRestoreOnStartup); |
| base::ListValue* url_list = update.Get(); |
| url_list->Append(new base::StringValue(kExampleUrl0)); |
| url_list->Append(new base::StringValue(kExampleUrl1)); |
| } |
| |
| syncer::SyncDataList in; |
| syncer::SyncChangeList out; |
| base::ListValue urls_to_restore; |
| urls_to_restore.Append(new base::StringValue(kExampleUrl1)); |
| urls_to_restore.Append(new base::StringValue(kExampleUrl2)); |
| AddToRemoteDataList(prefs::kURLsToRestoreOnStartupOld, urls_to_restore, &in); |
| AddToRemoteDataList(prefs::kHomePage, base::StringValue(kExampleUrl1), &in); |
| InitWithSyncDataTakeOutput(in, &out); |
| |
| ASSERT_FALSE(FindValue(prefs::kHomePage, out).get()); |
| |
| // Expect that the new preference data contains the merged old prefs values. |
| scoped_ptr<base::ListValue> expected_urls(new base::ListValue); |
| expected_urls->Append(new base::StringValue(kExampleUrl1)); |
| expected_urls->Append(new base::StringValue(kExampleUrl2)); |
| expected_urls->Append(new base::StringValue(kExampleUrl0)); |
| |
| ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup)); |
| scoped_ptr<base::Value> value( |
| FindValue(prefs::kURLsToRestoreOnStartup, out)); |
| ASSERT_TRUE(value.get()); |
| EXPECT_TRUE(value->Equals(expected_urls.get())); |
| EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup). |
| Equals(expected_urls.get())); |
| |
| expected_urls.reset(new base::ListValue); |
| value = FindValue(prefs::kURLsToRestoreOnStartupOld, out).Pass(); |
| ASSERT_TRUE(value.get()); |
| EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld). |
| Equals(expected_urls.get())); |
| } |
| |
| TEST_F(PrefsSyncableServiceTest, |
| ModelAssociationCloudHasNewMigratedData) { |
| ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup)); |
| ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld)); |
| prefs_.SetString(prefs::kHomePage, kExampleUrl0); |
| { |
| ListPrefUpdate update(GetPrefs(), prefs::kURLsToRestoreOnStartupOld); |
| base::ListValue* url_list = update.Get(); |
| url_list->Append(new base::StringValue(kExampleUrl0)); |
| url_list->Append(new base::StringValue(kExampleUrl1)); |
| } |
| |
| syncer::SyncDataList in; |
| syncer::SyncChangeList out; |
| base::ListValue urls_to_restore; |
| urls_to_restore.Append(new base::StringValue(kExampleUrl1)); |
| urls_to_restore.Append(new base::StringValue(kExampleUrl2)); |
| AddToRemoteDataList(prefs::kURLsToRestoreOnStartupOld, urls_to_restore, &in); |
| AddToRemoteDataList(prefs::kHomePage, base::StringValue(kExampleUrl1), &in); |
| InitWithSyncDataTakeOutput(in, &out); |
| |
| scoped_ptr<base::Value> value(FindValue(prefs::kHomePage, out)); |
| ASSERT_FALSE(value.get()); |
| |
| // Expect that the cloud data under the new migrated preference name sticks. |
| scoped_ptr<base::ListValue> expected_urls(new base::ListValue); |
| expected_urls->Append(new base::StringValue(kExampleUrl1)); |
| expected_urls->Append(new base::StringValue(kExampleUrl2)); |
| |
| ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup)); |
| value = FindValue(prefs::kURLsToRestoreOnStartup, out).Pass(); |
| ASSERT_TRUE(value.get()); |
| EXPECT_TRUE(value->Equals(expected_urls.get())); |
| EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup). |
| Equals(expected_urls.get())); |
| |
| // The old preference data should still be here, though not synced. |
| expected_urls.reset(new base::ListValue); |
| expected_urls->Append(new base::StringValue(kExampleUrl0)); |
| expected_urls->Append(new base::StringValue(kExampleUrl1)); |
| |
| value = FindValue(prefs::kURLsToRestoreOnStartupOld, out).Pass(); |
| ASSERT_FALSE(value.get()); |
| EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld). |
| Equals(expected_urls.get())); |
| } |
| |
| TEST_F(PrefsSyncableServiceTest, |
| ModelAssociationCloudAddsOldAndNewMigratedData) { |
| ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup)); |
| ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld)); |
| prefs_.SetString(prefs::kHomePage, kExampleUrl0); |
| { |
| ListPrefUpdate update_old(GetPrefs(), prefs::kURLsToRestoreOnStartupOld); |
| base::ListValue* url_list_old = update_old.Get(); |
| url_list_old->Append(new base::StringValue(kExampleUrl0)); |
| url_list_old->Append(new base::StringValue(kExampleUrl1)); |
| ListPrefUpdate update(GetPrefs(), prefs::kURLsToRestoreOnStartup); |
| base::ListValue* url_list = update.Get(); |
| url_list->Append(new base::StringValue(kExampleUrl1)); |
| url_list->Append(new base::StringValue(kExampleUrl2)); |
| } |
| |
| syncer::SyncDataList in; |
| syncer::SyncChangeList out; |
| AddToRemoteDataList(prefs::kHomePage, base::StringValue(kExampleUrl1), &in); |
| InitWithSyncDataTakeOutput(in, &out); |
| |
| scoped_ptr<base::Value> value(FindValue(prefs::kHomePage, out)); |
| ASSERT_FALSE(value.get()); |
| |
| // Expect that the cloud data under the new migrated preference name sticks. |
| scoped_ptr<base::ListValue> expected_urls(new base::ListValue); |
| expected_urls->Append(new base::StringValue(kExampleUrl1)); |
| expected_urls->Append(new base::StringValue(kExampleUrl2)); |
| |
| ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup)); |
| value = FindValue(prefs::kURLsToRestoreOnStartup, out).Pass(); |
| ASSERT_TRUE(value.get()); |
| EXPECT_TRUE(value->Equals(expected_urls.get())); |
| EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup). |
| Equals(expected_urls.get())); |
| |
| // Should not have synced in the old startup url values. |
| value = FindValue(prefs::kURLsToRestoreOnStartupOld, out).Pass(); |
| ASSERT_FALSE(value.get()); |
| EXPECT_FALSE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld). |
| Equals(expected_urls.get())); |
| } |
| |
| TEST_F(PrefsSyncableServiceTest, FailModelAssociation) { |
| syncer::SyncChangeList output; |
| TestSyncProcessorStub* stub = new TestSyncProcessorStub(&output); |
| stub->FailNextProcessSyncChanges(); |
| syncer::SyncMergeResult r = pref_sync_service_->MergeDataAndStartSyncing( |
| syncer::PREFERENCES, syncer::SyncDataList(), |
| scoped_ptr<syncer::SyncChangeProcessor>(stub), |
| scoped_ptr<syncer::SyncErrorFactory>( |
| new syncer::SyncErrorFactoryMock())); |
| EXPECT_TRUE(r.error().IsSet()); |
| } |
| |
| TEST_F(PrefsSyncableServiceTest, UpdatedPreferenceWithDefaultValue) { |
| const PrefService::Preference* pref = |
| prefs_.FindPreference(prefs::kHomePage); |
| EXPECT_TRUE(pref->IsDefaultValue()); |
| |
| syncer::SyncChangeList out; |
| InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); |
| out.clear(); |
| |
| base::StringValue expected(kExampleUrl0); |
| GetPrefs()->Set(prefs::kHomePage, expected); |
| |
| scoped_ptr<base::Value> actual(FindValue(prefs::kHomePage, out)); |
| ASSERT_TRUE(actual.get()); |
| EXPECT_TRUE(expected.Equals(actual.get())); |
| } |
| |
| TEST_F(PrefsSyncableServiceTest, UpdatedPreferenceWithValue) { |
| GetPrefs()->SetString(prefs::kHomePage, kExampleUrl0); |
| syncer::SyncChangeList out; |
| InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); |
| out.clear(); |
| |
| base::StringValue expected(kExampleUrl1); |
| GetPrefs()->Set(prefs::kHomePage, expected); |
| |
| scoped_ptr<base::Value> actual(FindValue(prefs::kHomePage, out)); |
| ASSERT_TRUE(actual.get()); |
| EXPECT_TRUE(expected.Equals(actual.get())); |
| } |
| |
| TEST_F(PrefsSyncableServiceTest, UpdatedSyncNodeActionUpdate) { |
| GetPrefs()->SetString(prefs::kHomePage, kExampleUrl0); |
| InitWithNoSyncData(); |
| |
| base::StringValue expected(kExampleUrl1); |
| syncer::SyncChangeList list; |
| list.push_back(MakeRemoteChange( |
| 1, prefs::kHomePage, expected, SyncChange::ACTION_UPDATE)); |
| pref_sync_service_->ProcessSyncChanges(FROM_HERE, list); |
| |
| const base::Value& actual = GetPreferenceValue(prefs::kHomePage); |
| EXPECT_TRUE(expected.Equals(&actual)); |
| } |
| |
| TEST_F(PrefsSyncableServiceTest, UpdatedSyncNodeActionAdd) { |
| InitWithNoSyncData(); |
| |
| base::StringValue expected(kExampleUrl0); |
| syncer::SyncChangeList list; |
| list.push_back(MakeRemoteChange( |
| 1, prefs::kHomePage, expected, SyncChange::ACTION_ADD)); |
| pref_sync_service_->ProcessSyncChanges(FROM_HERE, list); |
| |
| const base::Value& actual = GetPreferenceValue(prefs::kHomePage); |
| EXPECT_TRUE(expected.Equals(&actual)); |
| EXPECT_EQ(1U, |
| pref_sync_service_->registered_preferences().count(prefs::kHomePage)); |
| } |
| |
| TEST_F(PrefsSyncableServiceTest, UpdatedSyncNodeUnknownPreference) { |
| InitWithNoSyncData(); |
| syncer::SyncChangeList list; |
| base::StringValue expected(kExampleUrl0); |
| list.push_back(MakeRemoteChange( |
| 1, "unknown preference", expected, SyncChange::ACTION_UPDATE)); |
| pref_sync_service_->ProcessSyncChanges(FROM_HERE, list); |
| // Nothing interesting happens on the client when it gets an update |
| // of an unknown preference. We just should not crash. |
| } |
| |
| TEST_F(PrefsSyncableServiceTest, ManagedPreferences) { |
| // Make the homepage preference managed. |
| base::StringValue managed_value("http://example.com"); |
| prefs_.SetManagedPref(prefs::kHomePage, managed_value.DeepCopy()); |
| |
| syncer::SyncChangeList out; |
| InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); |
| out.clear(); |
| |
| // Changing the homepage preference should not sync anything. |
| base::StringValue user_value("http://chromium..com"); |
| prefs_.SetUserPref(prefs::kHomePage, user_value.DeepCopy()); |
| EXPECT_TRUE(out.empty()); |
| |
| // An incoming sync transaction should change the user value, not the managed |
| // value. |
| base::StringValue sync_value("http://crbug.com"); |
| syncer::SyncChangeList list; |
| list.push_back(MakeRemoteChange( |
| 1, prefs::kHomePage, sync_value, SyncChange::ACTION_UPDATE)); |
| pref_sync_service_->ProcessSyncChanges(FROM_HERE, list); |
| |
| EXPECT_TRUE(managed_value.Equals(prefs_.GetManagedPref(prefs::kHomePage))); |
| EXPECT_TRUE(sync_value.Equals(prefs_.GetUserPref(prefs::kHomePage))); |
| } |
| |
| // List preferences have special handling at association time due to our ability |
| // to merge the local and sync value. Make sure the merge logic doesn't merge |
| // managed preferences. |
| TEST_F(PrefsSyncableServiceTest, ManagedListPreferences) { |
| // Make the list of urls to restore on startup managed. |
| base::ListValue managed_value; |
| managed_value.Append(new base::StringValue(kExampleUrl0)); |
| managed_value.Append(new base::StringValue(kExampleUrl1)); |
| prefs_.SetManagedPref(prefs::kURLsToRestoreOnStartup, |
| managed_value.DeepCopy()); |
| |
| // Set a cloud version. |
| syncer::SyncDataList in; |
| syncer::SyncChangeList out; |
| base::ListValue urls_to_restore; |
| urls_to_restore.Append(new base::StringValue(kExampleUrl1)); |
| urls_to_restore.Append(new base::StringValue(kExampleUrl2)); |
| AddToRemoteDataList(prefs::kURLsToRestoreOnStartup, urls_to_restore, &in); |
| |
| // Start sync and verify the synced value didn't get merged. |
| InitWithSyncDataTakeOutput(in, &out); |
| EXPECT_FALSE(FindValue(prefs::kURLsToRestoreOnStartup, out).get()); |
| out.clear(); |
| |
| // Changing the user's urls to restore on startup pref should not sync |
| // anything. |
| base::ListValue user_value; |
| user_value.Append(new base::StringValue("http://chromium.org")); |
| prefs_.SetUserPref(prefs::kURLsToRestoreOnStartup, user_value.DeepCopy()); |
| EXPECT_FALSE(FindValue(prefs::kURLsToRestoreOnStartup, out).get()); |
| |
| // An incoming sync transaction should change the user value, not the managed |
| // value. |
| base::ListValue sync_value; |
| sync_value.Append(new base::StringValue("http://crbug.com")); |
| syncer::SyncChangeList list; |
| list.push_back(MakeRemoteChange( |
| 1, prefs::kURLsToRestoreOnStartup, sync_value, |
| SyncChange::ACTION_UPDATE)); |
| pref_sync_service_->ProcessSyncChanges(FROM_HERE, list); |
| |
| EXPECT_TRUE(managed_value.Equals( |
| prefs_.GetManagedPref(prefs::kURLsToRestoreOnStartup))); |
| EXPECT_TRUE(sync_value.Equals( |
| prefs_.GetUserPref(prefs::kURLsToRestoreOnStartup))); |
| } |
| |
| TEST_F(PrefsSyncableServiceTest, DynamicManagedPreferences) { |
| syncer::SyncChangeList out; |
| InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); |
| out.clear(); |
| base::StringValue initial_value("http://example.com/initial"); |
| GetPrefs()->Set(prefs::kHomePage, initial_value); |
| scoped_ptr<base::Value> actual(FindValue(prefs::kHomePage, out)); |
| ASSERT_TRUE(actual.get()); |
| EXPECT_TRUE(initial_value.Equals(actual.get())); |
| |
| // Switch kHomePage to managed and set a different value. |
| base::StringValue managed_value("http://example.com/managed"); |
| GetTestingPrefService()->SetManagedPref(prefs::kHomePage, |
| managed_value.DeepCopy()); |
| |
| // The pref value should be the one dictated by policy. |
| EXPECT_TRUE(managed_value.Equals(&GetPreferenceValue(prefs::kHomePage))); |
| |
| // Switch kHomePage back to unmanaged. |
| GetTestingPrefService()->RemoveManagedPref(prefs::kHomePage); |
| |
| // The original value should be picked up. |
| EXPECT_TRUE(initial_value.Equals(&GetPreferenceValue(prefs::kHomePage))); |
| } |
| |
| TEST_F(PrefsSyncableServiceTest, |
| DynamicManagedPreferencesWithSyncChange) { |
| syncer::SyncChangeList out; |
| InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); |
| out.clear(); |
| |
| base::StringValue initial_value("http://example.com/initial"); |
| GetPrefs()->Set(prefs::kHomePage, initial_value); |
| scoped_ptr<base::Value> actual(FindValue(prefs::kHomePage, out)); |
| EXPECT_TRUE(initial_value.Equals(actual.get())); |
| |
| // Switch kHomePage to managed and set a different value. |
| base::StringValue managed_value("http://example.com/managed"); |
| GetTestingPrefService()->SetManagedPref(prefs::kHomePage, |
| managed_value.DeepCopy()); |
| |
| // Change the sync value. |
| base::StringValue sync_value("http://example.com/sync"); |
| syncer::SyncChangeList list; |
| list.push_back(MakeRemoteChange( |
| 1, prefs::kHomePage, sync_value, SyncChange::ACTION_UPDATE)); |
| pref_sync_service_->ProcessSyncChanges(FROM_HERE, list); |
| |
| // The pref value should still be the one dictated by policy. |
| EXPECT_TRUE(managed_value.Equals(&GetPreferenceValue(prefs::kHomePage))); |
| |
| // Switch kHomePage back to unmanaged. |
| GetTestingPrefService()->RemoveManagedPref(prefs::kHomePage); |
| |
| // Sync value should be picked up. |
| EXPECT_TRUE(sync_value.Equals(&GetPreferenceValue(prefs::kHomePage))); |
| } |
| |
| TEST_F(PrefsSyncableServiceTest, DynamicManagedDefaultPreferences) { |
| const PrefService::Preference* pref = |
| prefs_.FindPreference(prefs::kHomePage); |
| EXPECT_TRUE(pref->IsDefaultValue()); |
| syncer::SyncChangeList out; |
| InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); |
| |
| EXPECT_TRUE(IsSynced(prefs::kHomePage)); |
| EXPECT_TRUE(pref->IsDefaultValue()); |
| EXPECT_FALSE(FindValue(prefs::kHomePage, out).get()); |
| out.clear(); |
| |
| // Switch kHomePage to managed and set a different value. |
| base::StringValue managed_value("http://example.com/managed"); |
| GetTestingPrefService()->SetManagedPref(prefs::kHomePage, |
| managed_value.DeepCopy()); |
| // The pref value should be the one dictated by policy. |
| EXPECT_TRUE(managed_value.Equals(&GetPreferenceValue(prefs::kHomePage))); |
| EXPECT_FALSE(pref->IsDefaultValue()); |
| // There should be no synced value. |
| EXPECT_FALSE(FindValue(prefs::kHomePage, out).get()); |
| // Switch kHomePage back to unmanaged. |
| GetTestingPrefService()->RemoveManagedPref(prefs::kHomePage); |
| // The original value should be picked up. |
| EXPECT_TRUE(pref->IsDefaultValue()); |
| // There should still be no synced value. |
| EXPECT_FALSE(FindValue(prefs::kHomePage, out).get()); |
| } |
| |
| TEST_F(PrefsSyncableServiceTest, DeletePreference) { |
| prefs_.SetString(prefs::kHomePage, kExampleUrl0); |
| const PrefService::Preference* pref = |
| prefs_.FindPreference(prefs::kHomePage); |
| EXPECT_FALSE(pref->IsDefaultValue()); |
| |
| InitWithNoSyncData(); |
| |
| scoped_ptr<base::Value> null_value(base::Value::CreateNullValue()); |
| syncer::SyncChangeList list; |
| list.push_back(MakeRemoteChange( |
| 1, prefs::kHomePage, *null_value, SyncChange::ACTION_DELETE)); |
| pref_sync_service_->ProcessSyncChanges(FROM_HERE, list); |
| EXPECT_TRUE(pref->IsDefaultValue()); |
| } |