Index: chrome/browser/prefs/prefs_syncable_service_unittest.cc |
diff --git a/chrome/browser/prefs/prefs_syncable_service_unittest.cc b/chrome/browser/prefs/prefs_syncable_service_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3457775437d0ef296980185aa21a012860389078 |
--- /dev/null |
+++ b/chrome/browser/prefs/prefs_syncable_service_unittest.cc |
@@ -0,0 +1,720 @@ |
+// 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/test/base/testing_browser_process.h" |
+#include "chrome/test/base/testing_pref_service_syncable.h" |
+#include "chrome/test/base/testing_profile.h" |
+#include "chrome/test/base/testing_profile_manager.h" |
+#include "components/user_prefs/pref_registry_syncable.h" |
+#include "sync/api/attachments/attachment_id.h" |
+#include "sync/api/attachments/attachment_service_proxy_for_test.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/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 kTestProfileName[] = "test-profile"; |
+} // namespace |
+ |
+class TestSyncProcessorStub : public syncer::SyncChangeProcessor { |
+ public: |
+ explicit TestSyncProcessorStub(syncer::SyncChangeList* output) |
+ : output_(output), fail_next_(false) {} |
+ virtual 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; |
+ } |
+ |
+ virtual 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() : |
+ profile_manager_(TestingBrowserProcess::GetGlobal()), |
+ profile_(NULL), |
+ prefs_(NULL), |
+ pref_sync_service_(NULL), |
+ test_processor_(NULL), |
+ example_url0_("http://example.com/0"), |
Nicolas Zea
2014/04/25 20:43:18
make all these const char[]'s defined in an anon n
tim (not reviewing)
2014/04/28 18:28:51
Done.
|
+ example_url1_("http://example.com/1"), |
+ example_url2_("http://example.com/2"), |
+ not_synced_preference_name_("nonsense_pref_name"), |
+ not_synced_preference_default_value_("default"), |
+ non_default_charset_value_("foo"), |
+ next_pref_remote_sync_node_id_(0) {} |
+ |
+ virtual void SetUp() { |
+ ASSERT_TRUE(profile_manager_.SetUp()); |
+ profile_ = profile_manager_.CreateTestingProfile( |
Nicolas Zea
2014/04/25 20:43:18
Do you need a testing profile (and the profile man
tim (not reviewing)
2014/04/28 18:28:51
Maybe although that's a lot of boilerplate to writ
Nicolas Zea
2014/04/28 18:38:55
I just realized the reason I had that boilerplate
|
+ kTestProfileName, |
+ scoped_ptr<PrefServiceSyncable>(), |
+ base::UTF8ToUTF16(kTestProfileName), |
+ 0, |
+ std::string(), |
+ TestingProfile::TestingFactories()); |
+ prefs_ = profile_->GetTestingPrefService(); |
+ |
+ prefs_->registry()->RegisterStringPref( |
+ not_synced_preference_name_.c_str(), |
+ not_synced_preference_default_value_, |
+ user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
+ |
+ pref_sync_service_ = reinterpret_cast<PrefModelAssociator*>( |
+ prefs_->GetSyncableService(syncer::PREFERENCES)); |
+ ASSERT_TRUE(pref_sync_service_); |
+ next_pref_remote_sync_node_id_ = 0; |
+ } |
+ |
+ virtual void TearDown() { |
+ profile_ = NULL; |
+ profile_manager_.DeleteTestingProfile(kTestProfileName); |
+ } |
+ |
+ 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 AddPrefToDataList(const std::string& name, |
Nicolas Zea
2014/04/25 20:43:18
nit: AddPrefToRemoteDataList is a bit clearer I th
tim (not reviewing)
2014/04/28 18:28:51
Good call on 'Remote', went with AddToRemoteDataLi
|
+ 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(); |
+ } |
+ |
+ const base::Value* FindValue(const std::string& name, |
Nicolas Zea
2014/04/25 20:43:18
Is this transferring ownereship? Return scoped_ptr
tim (not reviewing)
2014/04/28 18:28:51
Done.
|
+ 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 base::JSONReader::Read( |
+ it->sync_data().GetSpecifics().preference().value()); |
+ } |
+ } |
+ return NULL; |
+ } |
+ |
+ 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); |
+ } |
+ |
+ protected: |
+ TestingProfileManager profile_manager_; |
+ TestingProfile* profile_; |
+ TestingPrefServiceSyncable* prefs_; |
+ |
+ PrefModelAssociator* pref_sync_service_; |
+ TestSyncProcessorStub* test_processor_; |
+ |
+ // TODO(tim): Remove this by fixing AttachmentServiceProxyForTest. |
+ base::MessageLoop loop_; |
+ |
+ std::string example_url0_; |
+ std::string example_url1_; |
+ std::string example_url2_; |
+ std::string not_synced_preference_name_; |
+ std::string not_synced_preference_default_value_; |
+ std::string non_default_charset_value_; |
+ int next_pref_remote_sync_node_id_; |
+}; |
+ |
+TEST_F(PrefsSyncableServiceTest, CreatePrefSyncData) { |
+ prefs_->SetString(prefs::kHomePage, example_url0_); |
+ |
+ 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)); |
+} |
+ |
+TEST_F(PrefsSyncableServiceTest, ModelAssociationEmptyCloud) { |
+ prefs_->SetString(prefs::kHomePage, example_url0_); |
+ { |
+ ListPrefUpdate update(prefs_, prefs::kURLsToRestoreOnStartup); |
+ base::ListValue* url_list = update.Get(); |
+ url_list->Append(new base::StringValue(example_url0_)); |
+ url_list->Append(new base::StringValue(example_url1_)); |
+ } |
+ syncer::SyncChangeList out; |
+ InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); |
+ |
+ scoped_ptr<const base::Value> value(FindValue(prefs::kHomePage, out)); |
+ ASSERT_TRUE(value.get()); |
+ EXPECT_TRUE(GetPreferenceValue(prefs::kHomePage).Equals(value.get())); |
+ value.reset(FindValue(prefs::kURLsToRestoreOnStartup, out)); |
+ ASSERT_TRUE(value.get()); |
+ EXPECT_TRUE( |
+ GetPreferenceValue(prefs::kURLsToRestoreOnStartup).Equals(value.get())); |
+} |
+ |
+TEST_F(PrefsSyncableServiceTest, ModelAssociationCloudHasData) { |
+ prefs_->SetString(prefs::kHomePage, example_url0_); |
+ { |
+ ListPrefUpdate update(prefs_, prefs::kURLsToRestoreOnStartup); |
+ base::ListValue* url_list = update.Get(); |
+ url_list->Append(new base::StringValue(example_url0_)); |
+ url_list->Append(new base::StringValue(example_url1_)); |
+ } |
+ |
+ syncer::SyncDataList in; |
+ syncer::SyncChangeList out; |
+ AddPrefToDataList(prefs::kHomePage, base::StringValue(example_url1_), &in); |
+ base::ListValue urls_to_restore; |
+ urls_to_restore.Append(new base::StringValue(example_url1_)); |
+ urls_to_restore.Append(new base::StringValue(example_url2_)); |
+ AddPrefToDataList(prefs::kURLsToRestoreOnStartup, urls_to_restore, &in); |
+ AddPrefToDataList(prefs::kDefaultCharset, |
+ base::StringValue(non_default_charset_value_), |
+ &in); |
+ InitWithSyncDataTakeOutput(in, &out); |
+ |
+ ASSERT_FALSE(FindValue(prefs::kHomePage, out)); |
+ ASSERT_FALSE(FindValue(prefs::kDefaultCharset, out)); |
+ |
+ EXPECT_EQ(example_url1_, prefs_->GetString(prefs::kHomePage)); |
+ |
+ scoped_ptr<base::ListValue> expected_urls(new base::ListValue); |
+ expected_urls->Append(new base::StringValue(example_url1_)); |
+ expected_urls->Append(new base::StringValue(example_url2_)); |
+ expected_urls->Append(new base::StringValue(example_url0_)); |
+ scoped_ptr<const 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(non_default_charset_value_, |
+ 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(example_url1_)); |
+ urls_to_restore.Append(new base::StringValue(example_url2_)); |
+ AddPrefToDataList(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(example_url1_)); |
+ expected_urls->Append(new base::StringValue(example_url2_)); |
+ |
+ ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup)); |
+ scoped_ptr<const 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)); |
+ 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, example_url0_); |
+ { |
+ ListPrefUpdate update(prefs_, prefs::kURLsToRestoreOnStartup); |
+ base::ListValue* url_list = update.Get(); |
+ url_list->Append(new base::StringValue(example_url0_)); |
+ url_list->Append(new base::StringValue(example_url1_)); |
+ } |
+ |
+ syncer::SyncDataList in; |
+ syncer::SyncChangeList out; |
+ base::ListValue urls_to_restore; |
+ urls_to_restore.Append(new base::StringValue(example_url1_)); |
+ urls_to_restore.Append(new base::StringValue(example_url2_)); |
+ AddPrefToDataList(prefs::kURLsToRestoreOnStartupOld, urls_to_restore, &in); |
+ AddPrefToDataList(prefs::kHomePage, base::StringValue(example_url1_), &in); |
+ InitWithSyncDataTakeOutput(in, &out); |
+ |
+ ASSERT_FALSE(FindValue(prefs::kHomePage, out)); |
+ |
+ // 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(example_url1_)); |
+ expected_urls->Append(new base::StringValue(example_url2_)); |
+ expected_urls->Append(new base::StringValue(example_url0_)); |
+ |
+ ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup)); |
+ scoped_ptr<const 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.reset(FindValue(prefs::kURLsToRestoreOnStartupOld, out)); |
+ 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, example_url0_); |
+ { |
+ ListPrefUpdate update(prefs_, prefs::kURLsToRestoreOnStartupOld); |
+ base::ListValue* url_list = update.Get(); |
+ url_list->Append(new base::StringValue(example_url0_)); |
+ url_list->Append(new base::StringValue(example_url1_)); |
+ } |
+ |
+ syncer::SyncDataList in; |
+ syncer::SyncChangeList out; |
+ base::ListValue urls_to_restore; |
+ urls_to_restore.Append(new base::StringValue(example_url1_)); |
+ urls_to_restore.Append(new base::StringValue(example_url2_)); |
+ AddPrefToDataList(prefs::kURLsToRestoreOnStartupOld, urls_to_restore, &in); |
+ AddPrefToDataList(prefs::kHomePage, base::StringValue(example_url1_), &in); |
+ InitWithSyncDataTakeOutput(in, &out); |
+ |
+ scoped_ptr<const 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(example_url1_)); |
+ expected_urls->Append(new base::StringValue(example_url2_)); |
+ |
+ ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup)); |
+ value.reset(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 data should still be here, though not synced. |
+ expected_urls.reset(new base::ListValue); |
+ expected_urls->Append(new base::StringValue(example_url0_)); |
+ expected_urls->Append(new base::StringValue(example_url1_)); |
+ |
+ value.reset(FindValue(prefs::kURLsToRestoreOnStartupOld, out)); |
+ 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, example_url0_); |
+ { |
+ ListPrefUpdate update_old(prefs_, prefs::kURLsToRestoreOnStartupOld); |
+ base::ListValue* url_list_old = update_old.Get(); |
+ url_list_old->Append(new base::StringValue(example_url0_)); |
+ url_list_old->Append(new base::StringValue(example_url1_)); |
+ ListPrefUpdate update(prefs_, prefs::kURLsToRestoreOnStartup); |
+ base::ListValue* url_list = update.Get(); |
+ url_list->Append(new base::StringValue(example_url1_)); |
+ url_list->Append(new base::StringValue(example_url2_)); |
+ } |
+ |
+ syncer::SyncDataList in; |
+ syncer::SyncChangeList out; |
+ AddPrefToDataList(prefs::kHomePage, base::StringValue(example_url1_), &in); |
+ InitWithSyncDataTakeOutput(in, &out); |
+ |
+ scoped_ptr<const 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(example_url1_)); |
+ expected_urls->Append(new base::StringValue(example_url2_)); |
+ |
+ ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup)); |
+ value.reset(FindValue(prefs::kURLsToRestoreOnStartup, out)); |
+ 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.reset(FindValue(prefs::kURLsToRestoreOnStartupOld, out)); |
+ 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(example_url0_); |
+ profile_->GetPrefs()->Set(prefs::kHomePage, expected); |
+ |
+ scoped_ptr<const base::Value> actual(FindValue(prefs::kHomePage, out)); |
+ ASSERT_TRUE(actual.get()); |
+ EXPECT_TRUE(expected.Equals(actual.get())); |
+} |
+ |
+TEST_F(PrefsSyncableServiceTest, UpdatedPreferenceWithValue) { |
+ profile_->GetPrefs()->SetString(prefs::kHomePage, example_url0_); |
+ syncer::SyncChangeList out; |
+ InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); |
+ out.clear(); |
+ |
+ base::StringValue expected(example_url1_); |
+ profile_->GetPrefs()->Set(prefs::kHomePage, expected); |
+ |
+ scoped_ptr<const base::Value> actual(FindValue(prefs::kHomePage, out)); |
+ ASSERT_TRUE(actual.get()); |
+ EXPECT_TRUE(expected.Equals(actual.get())); |
+} |
+ |
+TEST_F(PrefsSyncableServiceTest, UpdatedSyncNodeActionUpdate) { |
+ profile_->GetPrefs()->SetString(prefs::kHomePage, example_url0_); |
+ InitWithNoSyncData(); |
+ |
+ base::StringValue expected(example_url1_); |
+ 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(example_url0_); |
+ 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(example_url0_); |
+ 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(example_url0_)); |
+ managed_value.Append(new base::StringValue(example_url1_)); |
+ 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(example_url1_)); |
+ urls_to_restore.Append(new base::StringValue(example_url2_)); |
+ AddPrefToDataList(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)); |
+ 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)); |
+ |
+ // 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"); |
+ profile_->GetPrefs()->Set(prefs::kHomePage, initial_value); |
+ scoped_ptr<const 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"); |
+ profile_->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. |
+ profile_->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"); |
+ profile_->GetPrefs()->Set(prefs::kHomePage, initial_value); |
+ scoped_ptr<const 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"); |
+ profile_->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. |
+ profile_->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)); |
+ out.clear(); |
+ |
+ // Switch kHomePage to managed and set a different value. |
+ base::StringValue managed_value("http://example.com/managed"); |
+ profile_->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)); |
+ // Switch kHomePage back to unmanaged. |
+ profile_->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)); |
+} |