#include "components/sync/driver/sync_user_settings_impl.h"
#include <memory>
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/test/scoped_feature_list.h"
#include "build/chromeos_buildflags.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "components/sync/base/features.h"
#include "components/sync/base/model_type.h"
#include "components/sync/base/pref_names.h"
#include "components/sync/base/sync_prefs.h"
#include "components/sync/base/user_selectable_type.h"
#include "components/sync/driver/sync_service_crypto.h"
#include "components/sync/engine/configure_reason.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace syncer {
namespace {
ModelTypeSet GetUserTypes() {
ModelTypeSet user_types = UserTypes();
#if !BUILDFLAG(IS_CHROMEOS_ASH)
user_types.RemoveAll(
{APP_LIST, ARC_PACKAGE, OS_PREFERENCES, OS_PRIORITY_PREFERENCES, PRINTERS,
PRINTERS_AUTHORIZATION_SERVERS, WIFI_CONFIGURATIONS, WORKSPACE_DESK});
#endif
return user_types;
}
ModelTypeSet GetPreferredUserTypes(
const SyncUserSettingsImpl& sync_user_settings) {
return Intersection(UserTypes(), sync_user_settings.GetPreferredDataTypes());
}
class MockSyncServiceCryptoDelegate : public SyncServiceCrypto::Delegate {
public:
MockSyncServiceCryptoDelegate() = default;
~MockSyncServiceCryptoDelegate() override = default;
MOCK_METHOD(void, CryptoStateChanged, (), (override));
MOCK_METHOD(void, CryptoRequiredUserActionChanged, (), (override));
MOCK_METHOD(void, ReconfigureDataTypesDueToCrypto, (), (override));
MOCK_METHOD(void,
SetEncryptionBootstrapToken,
(const std::string&),
(override));
MOCK_METHOD(std::string, GetEncryptionBootstrapToken, (), (override));
};
class SyncUserSettingsImplTest : public testing::Test {
protected:
SyncUserSettingsImplTest() {
SyncPrefs::RegisterProfilePrefs(pref_service_.registry());
sync_prefs_ = std::make_unique<SyncPrefs>(&pref_service_);
sync_service_crypto_ =
std::make_unique<SyncServiceCrypto>(&sync_service_crypto_delegate_,
nullptr);
}
std::unique_ptr<SyncUserSettingsImpl> MakeSyncUserSettings(
ModelTypeSet registered_types) {
return std::make_unique<SyncUserSettingsImpl>(
sync_service_crypto_.get(), sync_prefs_.get(),
nullptr, registered_types);
}
TestingPrefServiceSimple pref_service_;
std::unique_ptr<SyncPrefs> sync_prefs_;
testing::NiceMock<MockSyncServiceCryptoDelegate>
sync_service_crypto_delegate_;
std::unique_ptr<SyncServiceCrypto> sync_service_crypto_;
};
TEST_F(SyncUserSettingsImplTest, PreferredTypesSyncEverything) {
std::unique_ptr<SyncUserSettingsImpl> sync_user_settings =
MakeSyncUserSettings(GetUserTypes());
ModelTypeSet expected_types = GetUserTypes();
EXPECT_TRUE(sync_user_settings->IsSyncEverythingEnabled());
EXPECT_EQ(expected_types, GetPreferredUserTypes(*sync_user_settings));
UserSelectableTypeSet all_registered_types =
sync_user_settings->GetRegisteredSelectableTypes();
for (UserSelectableType type : all_registered_types) {
sync_user_settings->SetSelectedTypes(true, {type});
EXPECT_EQ(expected_types, GetPreferredUserTypes(*sync_user_settings));
}
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
TEST_F(SyncUserSettingsImplTest, PreferredTypesSyncAllOsTypes) {
std::unique_ptr<SyncUserSettingsImpl> sync_user_settings =
MakeSyncUserSettings(GetUserTypes());
ModelTypeSet expected_types = GetUserTypes();
EXPECT_TRUE(sync_user_settings->IsSyncAllOsTypesEnabled());
EXPECT_EQ(expected_types, GetPreferredUserTypes(*sync_user_settings));
for (UserSelectableOsType type : UserSelectableOsTypeSet::All()) {
sync_user_settings->SetSelectedOsTypes(true,
{type});
EXPECT_EQ(expected_types, GetPreferredUserTypes(*sync_user_settings));
}
}
#endif
TEST_F(SyncUserSettingsImplTest, PreferredTypesNotKeepEverythingSynced) {
std::unique_ptr<SyncUserSettingsImpl> sync_user_settings =
MakeSyncUserSettings(GetUserTypes());
sync_user_settings->SetSelectedTypes(
false,
UserSelectableTypeSet());
#if BUILDFLAG(IS_CHROMEOS_ASH)
sync_user_settings->SetSelectedOsTypes(false,
UserSelectableOsTypeSet());
#endif
ASSERT_EQ(AlwaysPreferredUserTypes(),
GetPreferredUserTypes(*sync_user_settings));
UserSelectableTypeSet all_registered_types =
sync_user_settings->GetRegisteredSelectableTypes();
for (UserSelectableType type : all_registered_types) {
ModelTypeSet expected_preferred_types =
UserSelectableTypeToAllModelTypes(type);
expected_preferred_types.PutAll(AlwaysPreferredUserTypes());
sync_user_settings->SetSelectedTypes(false,
{type});
EXPECT_EQ(expected_preferred_types,
GetPreferredUserTypes(*sync_user_settings));
}
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
TEST_F(SyncUserSettingsImplTest, PreferredTypesNotAllOsTypesSynced) {
std::unique_ptr<SyncUserSettingsImpl> sync_user_settings =
MakeSyncUserSettings(GetUserTypes());
sync_user_settings->SetSelectedTypes(
false,
UserSelectableTypeSet());
sync_user_settings->SetSelectedOsTypes(
false,
UserSelectableOsTypeSet());
EXPECT_FALSE(sync_user_settings->IsSyncEverythingEnabled());
EXPECT_FALSE(sync_user_settings->IsSyncAllOsTypesEnabled());
EXPECT_EQ(AlwaysPreferredUserTypes(),
GetPreferredUserTypes(*sync_user_settings));
for (UserSelectableOsType type : UserSelectableOsTypeSet::All()) {
ModelTypeSet expected_preferred_types =
UserSelectableOsTypeToAllModelTypes(type);
expected_preferred_types.PutAll(AlwaysPreferredUserTypes());
sync_user_settings->SetSelectedOsTypes(false,
{type});
EXPECT_EQ(expected_preferred_types,
GetPreferredUserTypes(*sync_user_settings));
}
}
#endif
TEST_F(SyncUserSettingsImplTest, DeviceInfo) {
std::unique_ptr<SyncUserSettingsImpl> sync_user_settings =
MakeSyncUserSettings(GetUserTypes());
EXPECT_TRUE(sync_user_settings->GetPreferredDataTypes().Has(DEVICE_INFO));
UserSelectableTypeSet all_registered_types =
sync_user_settings->GetRegisteredSelectableTypes();
sync_user_settings->SetSelectedTypes(
true,
all_registered_types);
EXPECT_TRUE(sync_user_settings->GetPreferredDataTypes().Has(DEVICE_INFO));
sync_user_settings->SetSelectedTypes(
false,
all_registered_types);
EXPECT_TRUE(sync_user_settings->GetPreferredDataTypes().Has(DEVICE_INFO));
sync_user_settings = MakeSyncUserSettings(ModelTypeSet(DEVICE_INFO));
sync_user_settings->SetSelectedTypes(
false,
UserSelectableTypeSet());
EXPECT_TRUE(sync_user_settings->GetPreferredDataTypes().Has(DEVICE_INFO));
}
TEST_F(SyncUserSettingsImplTest, UserConsents) {
std::unique_ptr<SyncUserSettingsImpl> sync_user_settings =
MakeSyncUserSettings(GetUserTypes());
EXPECT_TRUE(sync_user_settings->GetPreferredDataTypes().Has(USER_CONSENTS));
UserSelectableTypeSet all_registered_types =
sync_user_settings->GetRegisteredSelectableTypes();
sync_user_settings->SetSelectedTypes(
true,
all_registered_types);
EXPECT_TRUE(sync_user_settings->GetPreferredDataTypes().Has(USER_CONSENTS));
sync_user_settings->SetSelectedTypes(
false,
all_registered_types);
EXPECT_TRUE(sync_user_settings->GetPreferredDataTypes().Has(USER_CONSENTS));
sync_user_settings = MakeSyncUserSettings(ModelTypeSet(USER_CONSENTS));
sync_user_settings->SetSelectedTypes(
false,
UserSelectableTypeSet());
EXPECT_TRUE(sync_user_settings->GetPreferredDataTypes().Has(USER_CONSENTS));
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
TEST_F(SyncUserSettingsImplTest, AlwaysPreferredTypes_ChromeOS) {
std::unique_ptr<SyncUserSettingsImpl> sync_user_settings =
MakeSyncUserSettings(GetUserTypes());
sync_user_settings->SetSelectedTypes(
false,
UserSelectableTypeSet());
sync_user_settings->SetSelectedOsTypes(
false,
UserSelectableOsTypeSet());
ModelTypeSet preferred_types = sync_user_settings->GetPreferredDataTypes();
EXPECT_TRUE(preferred_types.Has(DEVICE_INFO));
EXPECT_TRUE(preferred_types.Has(USER_CONSENTS));
}
TEST_F(SyncUserSettingsImplTest, AppsAreHandledByOsSettings) {
std::unique_ptr<SyncUserSettingsImpl> settings =
MakeSyncUserSettings(GetUserTypes());
ASSERT_TRUE(settings->IsSyncEverythingEnabled());
ASSERT_TRUE(settings->IsSyncAllOsTypesEnabled());
EXPECT_TRUE(settings->GetPreferredDataTypes().Has(APP_LIST));
EXPECT_TRUE(settings->GetPreferredDataTypes().Has(APP_SETTINGS));
EXPECT_TRUE(settings->GetPreferredDataTypes().Has(APPS));
EXPECT_TRUE(settings->GetPreferredDataTypes().Has(ARC_PACKAGE));
EXPECT_TRUE(settings->GetPreferredDataTypes().Has(WEB_APPS));
settings->SetSelectedTypes(
false,
UserSelectableTypeSet());
EXPECT_TRUE(settings->GetPreferredDataTypes().Has(APP_LIST));
EXPECT_TRUE(settings->GetPreferredDataTypes().Has(APP_SETTINGS));
EXPECT_TRUE(settings->GetPreferredDataTypes().Has(APPS));
EXPECT_TRUE(settings->GetPreferredDataTypes().Has(ARC_PACKAGE));
EXPECT_TRUE(settings->GetPreferredDataTypes().Has(WEB_APPS));
settings->SetSelectedOsTypes(
false,
UserSelectableOsTypeSet());
EXPECT_FALSE(settings->GetPreferredDataTypes().Has(APP_LIST));
EXPECT_FALSE(settings->GetPreferredDataTypes().Has(APP_SETTINGS));
EXPECT_FALSE(settings->GetPreferredDataTypes().Has(APPS));
EXPECT_FALSE(settings->GetPreferredDataTypes().Has(ARC_PACKAGE));
EXPECT_FALSE(settings->GetPreferredDataTypes().Has(WEB_APPS));
}
#endif
#if BUILDFLAG(IS_CHROMEOS_LACROS)
TEST_F(SyncUserSettingsImplTest, AppsAreHandledByOsSettings) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(kSyncChromeOSAppsToggleSharing);
std::unique_ptr<SyncUserSettingsImpl> settings =
MakeSyncUserSettings(GetUserTypes());
ASSERT_TRUE(settings->IsSyncEverythingEnabled());
EXPECT_FALSE(settings->GetPreferredDataTypes().Has(APP_SETTINGS));
EXPECT_FALSE(settings->GetPreferredDataTypes().Has(APPS));
EXPECT_FALSE(settings->GetPreferredDataTypes().Has(WEB_APPS));
settings->SetAppsSyncEnabledByOs(true);
EXPECT_TRUE(settings->GetPreferredDataTypes().Has(APP_SETTINGS));
EXPECT_TRUE(settings->GetPreferredDataTypes().Has(APPS));
EXPECT_TRUE(settings->GetPreferredDataTypes().Has(WEB_APPS));
settings->SetSelectedTypes(false,
UserSelectableTypeSet());
ASSERT_FALSE(settings->IsSyncEverythingEnabled());
EXPECT_TRUE(settings->GetPreferredDataTypes().Has(APP_SETTINGS));
EXPECT_TRUE(settings->GetPreferredDataTypes().Has(APPS));
EXPECT_TRUE(settings->GetPreferredDataTypes().Has(WEB_APPS));
}
#endif
TEST_F(SyncUserSettingsImplTest,
ShouldSyncSessionsIfHistoryOrOpenTabsAreSelectedPreFullHistorySync) {
base::test::ScopedFeatureList features;
features.InitAndDisableFeature(kSyncEnableHistoryDataType);
ASSERT_FALSE(AlwaysPreferredUserTypes().Has(TYPED_URLS));
ASSERT_FALSE(AlwaysPreferredUserTypes().Has(HISTORY));
ASSERT_FALSE(AlwaysPreferredUserTypes().Has(HISTORY_DELETE_DIRECTIVES));
ASSERT_FALSE(AlwaysPreferredUserTypes().Has(SESSIONS));
ASSERT_FALSE(AlwaysPreferredUserTypes().Has(PROXY_TABS));
std::unique_ptr<SyncUserSettingsImpl> sync_user_settings =
MakeSyncUserSettings(GetUserTypes());
#if BUILDFLAG(IS_CHROMEOS_ASH)
sync_user_settings->SetSelectedOsTypes(false,
UserSelectableOsTypeSet());
#endif
sync_user_settings->SetSelectedTypes(
false,
{UserSelectableType::kHistory, UserSelectableType::kTabs});
EXPECT_EQ(GetPreferredUserTypes(*sync_user_settings),
Union(AlwaysPreferredUserTypes(),
ModelTypeSet(TYPED_URLS, HISTORY, HISTORY_DELETE_DIRECTIVES,
SESSIONS, PROXY_TABS, USER_EVENTS)));
sync_user_settings->SetSelectedTypes(
false,
{UserSelectableType::kHistory});
EXPECT_EQ(GetPreferredUserTypes(*sync_user_settings),
Union(AlwaysPreferredUserTypes(),
ModelTypeSet(TYPED_URLS, HISTORY, HISTORY_DELETE_DIRECTIVES,
SESSIONS, USER_EVENTS)));
sync_user_settings->SetSelectedTypes(
false,
{UserSelectableType::kTabs});
EXPECT_EQ(
GetPreferredUserTypes(*sync_user_settings),
Union(AlwaysPreferredUserTypes(), ModelTypeSet(SESSIONS, PROXY_TABS)));
}
TEST_F(SyncUserSettingsImplTest,
ShouldSyncSessionsOnlyIfOpenTabsIsSelectedPostFullHistorySync) {
base::test::ScopedFeatureList features(kSyncEnableHistoryDataType);
ASSERT_FALSE(AlwaysPreferredUserTypes().Has(TYPED_URLS));
ASSERT_FALSE(AlwaysPreferredUserTypes().Has(HISTORY));
ASSERT_FALSE(AlwaysPreferredUserTypes().Has(HISTORY_DELETE_DIRECTIVES));
ASSERT_FALSE(AlwaysPreferredUserTypes().Has(SESSIONS));
ASSERT_FALSE(AlwaysPreferredUserTypes().Has(PROXY_TABS));
std::unique_ptr<SyncUserSettingsImpl> sync_user_settings =
MakeSyncUserSettings(GetUserTypes());
#if BUILDFLAG(IS_CHROMEOS_ASH)
sync_user_settings->SetSelectedOsTypes(false,
UserSelectableOsTypeSet());
#endif
sync_user_settings->SetSelectedTypes(
false,
{UserSelectableType::kHistory, UserSelectableType::kTabs});
EXPECT_EQ(GetPreferredUserTypes(*sync_user_settings),
Union(AlwaysPreferredUserTypes(),
ModelTypeSet(TYPED_URLS, HISTORY, HISTORY_DELETE_DIRECTIVES,
SESSIONS, PROXY_TABS, USER_EVENTS)));
sync_user_settings->SetSelectedTypes(
false,
{UserSelectableType::kHistory});
EXPECT_EQ(GetPreferredUserTypes(*sync_user_settings),
Union(AlwaysPreferredUserTypes(),
ModelTypeSet(TYPED_URLS, HISTORY, HISTORY_DELETE_DIRECTIVES,
USER_EVENTS)));
sync_user_settings->SetSelectedTypes(
false,
{UserSelectableType::kTabs});
EXPECT_EQ(
GetPreferredUserTypes(*sync_user_settings),
Union(AlwaysPreferredUserTypes(), ModelTypeSet(SESSIONS, PROXY_TABS)));
}
TEST_F(SyncUserSettingsImplTest, ShouldMutePassphrasePrompt) {
std::unique_ptr<SyncUserSettingsImpl> sync_user_settings =
MakeSyncUserSettings(GetUserTypes());
EXPECT_FALSE(
sync_user_settings->IsPassphrasePromptMutedForCurrentProductVersion());
sync_user_settings->MarkPassphrasePromptMutedForCurrentProductVersion();
EXPECT_TRUE(
sync_user_settings->IsPassphrasePromptMutedForCurrentProductVersion());
sync_prefs_->ClearPassphrasePromptMutedProductVersion();
EXPECT_FALSE(
sync_user_settings->IsPassphrasePromptMutedForCurrentProductVersion());
}
TEST_F(SyncUserSettingsImplTest, ShouldClearPassphrasePromptMuteUponUpgrade) {
sync_prefs_->SetPassphrasePromptMutedProductVersion(73);
std::unique_ptr<SyncUserSettingsImpl> sync_user_settings =
MakeSyncUserSettings(GetUserTypes());
EXPECT_FALSE(
sync_user_settings->IsPassphrasePromptMutedForCurrentProductVersion());
sync_user_settings->MarkPassphrasePromptMutedForCurrentProductVersion();
EXPECT_TRUE(
sync_user_settings->IsPassphrasePromptMutedForCurrentProductVersion());
}
}
}