// Copyright (c) 2012 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 "components/sync_driver/sync_prefs.h"
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include "base/prefs/pref_notifier_impl.h"
#include "base/prefs/pref_value_store.h"
#include "base/prefs/testing_pref_service.h"
#include "base/time/time.h"
#include "components/pref_registry/testing_pref_service_syncable.h"
#include "components/sync_driver/pref_names.h"
#include "sync/internal_api/public/base/model_type.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace sync_driver {
namespace {
using ::testing::InSequence;
using ::testing::StrictMock;
class SyncPrefsTest : public testing::Test {
protected:
virtual void SetUp() OVERRIDE {
SyncPrefs::RegisterProfilePrefs(pref_service_.registry());
}
user_prefs::TestingPrefServiceSyncable pref_service_;
private:
base::MessageLoop loop_;
};
TEST_F(SyncPrefsTest, Basic) {
SyncPrefs sync_prefs(&pref_service_);
EXPECT_FALSE(sync_prefs.HasSyncSetupCompleted());
sync_prefs.SetSyncSetupCompleted();
EXPECT_TRUE(sync_prefs.HasSyncSetupCompleted());
EXPECT_FALSE(sync_prefs.IsStartSuppressed());
sync_prefs.SetStartSuppressed(true);
EXPECT_TRUE(sync_prefs.IsStartSuppressed());
sync_prefs.SetStartSuppressed(false);
EXPECT_FALSE(sync_prefs.IsStartSuppressed());
EXPECT_EQ(base::Time(), sync_prefs.GetLastSyncedTime());
const base::Time& now = base::Time::Now();
sync_prefs.SetLastSyncedTime(now);
EXPECT_EQ(now, sync_prefs.GetLastSyncedTime());
EXPECT_TRUE(sync_prefs.HasKeepEverythingSynced());
sync_prefs.SetKeepEverythingSynced(false);
EXPECT_FALSE(sync_prefs.HasKeepEverythingSynced());
sync_prefs.SetKeepEverythingSynced(true);
EXPECT_TRUE(sync_prefs.HasKeepEverythingSynced());
EXPECT_TRUE(sync_prefs.GetEncryptionBootstrapToken().empty());
sync_prefs.SetEncryptionBootstrapToken("token");
EXPECT_EQ("token", sync_prefs.GetEncryptionBootstrapToken());
}
TEST_F(SyncPrefsTest, DefaultTypes) {
SyncPrefs sync_prefs(&pref_service_);
sync_prefs.SetKeepEverythingSynced(false);
// Only bookmarks and device info are enabled by default.
syncer::ModelTypeSet expected(syncer::BOOKMARKS, syncer::DEVICE_INFO);
syncer::ModelTypeSet preferred_types =
sync_prefs.GetPreferredDataTypes(syncer::UserTypes());
EXPECT_TRUE(preferred_types.Equals(expected));
// Simulate an upgrade to delete directives + proxy tabs support. None of the
// new types or their pref group types should be registering, ensuring they
// don't have pref values.
syncer::ModelTypeSet registered_types = syncer::UserTypes();
registered_types.Remove(syncer::PROXY_TABS);
registered_types.Remove(syncer::TYPED_URLS);
registered_types.Remove(syncer::SESSIONS);
registered_types.Remove(syncer::HISTORY_DELETE_DIRECTIVES);
// Enable all other types.
sync_prefs.SetPreferredDataTypes(registered_types, registered_types);
// Manually enable typed urls (to simulate the old world).
pref_service_.SetBoolean(prefs::kSyncTypedUrls, true);
// Proxy tabs should not be enabled (since sessions wasn't), but history
// delete directives should (since typed urls was).
preferred_types = sync_prefs.GetPreferredDataTypes(syncer::UserTypes());
EXPECT_FALSE(preferred_types.Has(syncer::PROXY_TABS));
EXPECT_TRUE(preferred_types.Has(syncer::HISTORY_DELETE_DIRECTIVES));
// Now manually enable sessions, which should result in proxy tabs also being
// enabled. Also, manually disable typed urls, which should mean that history
// delete directives are not enabled.
pref_service_.SetBoolean(prefs::kSyncTypedUrls, false);
pref_service_.SetBoolean(prefs::kSyncSessions, true);
preferred_types = sync_prefs.GetPreferredDataTypes(syncer::UserTypes());
EXPECT_TRUE(preferred_types.Has(syncer::PROXY_TABS));
EXPECT_FALSE(preferred_types.Has(syncer::HISTORY_DELETE_DIRECTIVES));
}
TEST_F(SyncPrefsTest, PreferredTypesKeepEverythingSynced) {
SyncPrefs sync_prefs(&pref_service_);
EXPECT_TRUE(sync_prefs.HasKeepEverythingSynced());
const syncer::ModelTypeSet user_types = syncer::UserTypes();
EXPECT_TRUE(user_types.Equals(sync_prefs.GetPreferredDataTypes(user_types)));
const syncer::ModelTypeSet user_visible_types = syncer::UserSelectableTypes();
for (syncer::ModelTypeSet::Iterator it = user_visible_types.First();
it.Good();
it.Inc()) {
syncer::ModelTypeSet preferred_types;
preferred_types.Put(it.Get());
sync_prefs.SetPreferredDataTypes(user_types, preferred_types);
EXPECT_TRUE(
user_types.Equals(sync_prefs.GetPreferredDataTypes(user_types)));
}
}
TEST_F(SyncPrefsTest, PreferredTypesNotKeepEverythingSynced) {
SyncPrefs sync_prefs(&pref_service_);
sync_prefs.SetKeepEverythingSynced(false);
const syncer::ModelTypeSet user_types = syncer::UserTypes();
EXPECT_FALSE(user_types.Equals(sync_prefs.GetPreferredDataTypes(user_types)));
const syncer::ModelTypeSet user_visible_types = syncer::UserSelectableTypes();
for (syncer::ModelTypeSet::Iterator it = user_visible_types.First();
it.Good();
it.Inc()) {
syncer::ModelTypeSet preferred_types;
preferred_types.Put(it.Get());
syncer::ModelTypeSet expected_preferred_types(preferred_types);
if (it.Get() == syncer::AUTOFILL) {
expected_preferred_types.Put(syncer::AUTOFILL_PROFILE);
}
if (it.Get() == syncer::PREFERENCES) {
expected_preferred_types.Put(syncer::DICTIONARY);
expected_preferred_types.Put(syncer::PRIORITY_PREFERENCES);
expected_preferred_types.Put(syncer::SEARCH_ENGINES);
}
if (it.Get() == syncer::APPS) {
expected_preferred_types.Put(syncer::APP_LIST);
expected_preferred_types.Put(syncer::APP_NOTIFICATIONS);
expected_preferred_types.Put(syncer::APP_SETTINGS);
}
if (it.Get() == syncer::EXTENSIONS) {
expected_preferred_types.Put(syncer::EXTENSION_SETTINGS);
}
if (it.Get() == syncer::TYPED_URLS) {
expected_preferred_types.Put(syncer::HISTORY_DELETE_DIRECTIVES);
expected_preferred_types.Put(syncer::SESSIONS);
expected_preferred_types.Put(syncer::FAVICON_IMAGES);
expected_preferred_types.Put(syncer::FAVICON_TRACKING);
}
if (it.Get() == syncer::PROXY_TABS) {
expected_preferred_types.Put(syncer::SESSIONS);
expected_preferred_types.Put(syncer::FAVICON_IMAGES);
expected_preferred_types.Put(syncer::FAVICON_TRACKING);
}
// Device info is always preferred.
expected_preferred_types.Put(syncer::DEVICE_INFO);
sync_prefs.SetPreferredDataTypes(user_types, preferred_types);
EXPECT_TRUE(expected_preferred_types.Equals(
sync_prefs.GetPreferredDataTypes(user_types)));
}
}
class MockSyncPrefObserver : public SyncPrefObserver {
public:
MOCK_METHOD1(OnSyncManagedPrefChange, void(bool));
};
TEST_F(SyncPrefsTest, ObservedPrefs) {
SyncPrefs sync_prefs(&pref_service_);
StrictMock<MockSyncPrefObserver> mock_sync_pref_observer;
InSequence dummy;
EXPECT_CALL(mock_sync_pref_observer, OnSyncManagedPrefChange(true));
EXPECT_CALL(mock_sync_pref_observer, OnSyncManagedPrefChange(false));
EXPECT_FALSE(sync_prefs.IsManaged());
sync_prefs.AddSyncPrefObserver(&mock_sync_pref_observer);
sync_prefs.SetManagedForTest(true);
EXPECT_TRUE(sync_prefs.IsManaged());
sync_prefs.SetManagedForTest(false);
EXPECT_FALSE(sync_prefs.IsManaged());
sync_prefs.RemoveSyncPrefObserver(&mock_sync_pref_observer);
}
TEST_F(SyncPrefsTest, AcknowledgeSyncedTypes) {
SyncPrefs sync_prefs(&pref_service_);
syncer::ModelTypeSet expected_acknowledge_synced_types =
sync_prefs.GetAcknowledgeSyncedTypesForTest();
for (int i = syncer::EXTENSION_SETTINGS; i < syncer::MODEL_TYPE_COUNT; ++i) {
const syncer::ModelType type = syncer::ModelTypeFromInt(i);
syncer::ModelTypeSet acknowledge_synced_types(type);
expected_acknowledge_synced_types.Put(type);
sync_prefs.AcknowledgeSyncedTypes(acknowledge_synced_types);
EXPECT_TRUE(expected_acknowledge_synced_types.Equals(
sync_prefs.GetAcknowledgeSyncedTypesForTest()));
}
}
TEST_F(SyncPrefsTest, ClearPreferences) {
SyncPrefs sync_prefs(&pref_service_);
EXPECT_FALSE(sync_prefs.HasSyncSetupCompleted());
EXPECT_EQ(base::Time(), sync_prefs.GetLastSyncedTime());
EXPECT_TRUE(sync_prefs.GetEncryptionBootstrapToken().empty());
sync_prefs.SetSyncSetupCompleted();
sync_prefs.SetLastSyncedTime(base::Time::Now());
sync_prefs.SetEncryptionBootstrapToken("token");
EXPECT_TRUE(sync_prefs.HasSyncSetupCompleted());
EXPECT_NE(base::Time(), sync_prefs.GetLastSyncedTime());
EXPECT_EQ("token", sync_prefs.GetEncryptionBootstrapToken());
sync_prefs.ClearPreferences();
EXPECT_FALSE(sync_prefs.HasSyncSetupCompleted());
EXPECT_EQ(base::Time(), sync_prefs.GetLastSyncedTime());
EXPECT_TRUE(sync_prefs.GetEncryptionBootstrapToken().empty());
}
// Device info should always be enabled.
TEST_F(SyncPrefsTest, DeviceInfo) {
SyncPrefs sync_prefs(&pref_service_);
EXPECT_TRUE(sync_prefs.GetPreferredDataTypes(syncer::UserTypes())
.Has(syncer::DEVICE_INFO));
sync_prefs.SetKeepEverythingSynced(true);
EXPECT_TRUE(sync_prefs.GetPreferredDataTypes(syncer::UserTypes())
.Has(syncer::DEVICE_INFO));
sync_prefs.SetKeepEverythingSynced(false);
EXPECT_TRUE(sync_prefs.GetPreferredDataTypes(syncer::UserTypes())
.Has(syncer::DEVICE_INFO));
}
} // namespace
} // namespace sync_driver