Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1249)

Unified Diff: chrome/browser/prefs/prefs_syncable_service_unittest.cc

Issue 258753002: prefs / sync: rewrite ProfileSyncServicePreferenceTest to rely on sync/api instead of c/b/s/glue. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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));
+}

Powered by Google App Engine
This is Rietveld 408576698