chromium/components/sync/service/sync_service_impl_unittest.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/sync/service/sync_service_impl.h"

#include <map>
#include <memory>
#include <string>
#include <utility>

#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/test/gmock_callback_support.h"
#include "base/test/gtest_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/test/test_future.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "components/prefs/testing_pref_service.h"
#include "components/signin/public/base/signin_pref_names.h"
#include "components/signin/public/base/signin_switches.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "components/signin/public/identity_manager/identity_test_environment.h"
#include "components/signin/public/identity_manager/identity_test_utils.h"
#include "components/signin/public/identity_manager/primary_account_mutator.h"
#include "components/sync/base/command_line_switches.h"
#include "components/sync/base/data_type.h"
#include "components/sync/base/features.h"
#include "components/sync/base/pref_names.h"
#include "components/sync/base/sync_util.h"
#include "components/sync/base/user_selectable_type.h"
#include "components/sync/engine/nigori/key_derivation_params.h"
#include "components/sync/engine/sync_status.h"
#include "components/sync/service/sync_service_observer.h"
#include "components/sync/service/sync_token_status.h"
#include "components/sync/service/trusted_vault_synthetic_field_trial.h"
#include "components/sync/test/fake_data_type_controller.h"
#include "components/sync/test/fake_sync_engine.h"
#include "components/sync/test/fake_sync_engine_factory.h"
#include "components/sync/test/mock_data_type_local_data_batch_uploader.h"
#include "components/sync/test/sync_client_mock.h"
#include "components/sync/test/sync_service_impl_bundle.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "components/trusted_vault/test/fake_trusted_vault_client.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

_;
AllOf;
AnyNumber;
AtLeast;
ByMove;
Eq;
Invoke;
IsEmpty;
IsNull;
Not;
NotNull;
Pair;
Return;
UnorderedElementsAre;

namespace syncer {

namespace {

constexpr char kTestUser[] =;

// Construction parameters for FakeDataTypeController.
struct FakeControllerInitParams {};

MATCHER_P(ContainsDataType, type, "") {}

MATCHER_P(IsValidFieldTrialGroupWithName, expected_name, "") {}

SyncCycleSnapshot MakeDefaultSyncCycleSnapshot() {}

class MockSyncServiceObserver : public SyncServiceObserver {};

class TestSyncServiceObserver : public SyncServiceObserver {};

// A test harness that uses a real SyncServiceImpl and in most cases a
// FakeSyncEngine.
//
// This is useful if we want to test the SyncServiceImpl and don't care about
// testing the SyncEngine.
class SyncServiceImplTest : public ::testing::Test {};

// Verify that the server URLs are sane.
TEST_F(SyncServiceImplTest, InitialState) {}

TEST_F(SyncServiceImplTest, SuccessfulInitialization) {}

TEST_F(SyncServiceImplTest, SuccessfulLocalBackendInitialization) {}

// ChromeOS Ash sets FirstSetupComplete automatically.
#if !BUILDFLAG(IS_CHROMEOS_ASH)
// Verify that an initialization where first setup is not complete does not
// start up Sync-the-feature.
TEST_F(SyncServiceImplTest, NeedsConfirmation) {}
#endif

TEST_F(SyncServiceImplTest, DataTypesForTransportMode) {}

// Verify that the SetSetupInProgress function call updates state
// and notifies observers.
TEST_F(SyncServiceImplTest, SetupInProgress) {}

// Verify that disable by enterprise policy works.
TEST_F(SyncServiceImplTest, DisabledByPolicyBeforeInit) {}

TEST_F(SyncServiceImplTest, DisabledByPolicyBeforeInitThenPolicyRemoved) {}

// Verify that disable by enterprise policy works even after the backend has
// been initialized.
TEST_F(SyncServiceImplTest, DisabledByPolicyAfterInit) {}

// Exercises the SyncServiceImpl's code paths related to getting shut down
// before the backend initialize call returns.
TEST_F(SyncServiceImplTest, AbortedByShutdown) {}

// Certain SyncServiceImpl tests don't apply to Chrome OS, for example
// things that deal with concepts like "signing out".
#if !BUILDFLAG(IS_CHROMEOS_ASH)
// Test the user signing out before the backend's initialization completes.
TEST_F(SyncServiceImplTest, EarlySignOut) {}
#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)

// Certain SyncServiceImpl tests don't apply to Chrome OS, for example
// things that deal with concepts like "signing out".
#if !BUILDFLAG(IS_CHROMEOS_ASH)
TEST_F(SyncServiceImplTest, SignOutDisablesSyncTransportAndSyncFeature) {}

TEST_F(SyncServiceImplTest,
       SignOutClearsSyncTransportDataAndSyncTheFeaturePrefs) {}

TEST_F(SyncServiceImplTest,
       SignOutDuringTransportModeClearsTransportDataAndAccountStorageOptIn) {}
#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)

TEST_F(
    SyncServiceImplTest,
    AddressesSyncShouldBeDisabledForNewlySigninUsersWithAlreadyCustomPassphraseSet) {}

TEST_F(
    SyncServiceImplTest,
    AddressesSyncShouldNotBeDisabledForSignedInUsersWithNewlyCustomPassphraseSet) {}

TEST_F(SyncServiceImplTest, GetSyncTokenStatus) {}

TEST_F(SyncServiceImplTest, RevokeAccessTokenFromTokenService) {}

// Checks that CREDENTIALS_REJECTED_BY_CLIENT resets the access token and stops
// Sync. Regression test for https://crbug.com/824791.
TEST_F(SyncServiceImplTest, CredentialsRejectedByClient_StopSync) {}

// CrOS Ash does not support signout.
#if !BUILDFLAG(IS_CHROMEOS_ASH)
TEST_F(SyncServiceImplTest, SignOutRevokeAccessToken) {}
#endif

// Verify that sync transport data is cleared when the service is initializing
// and account is signed out.
// This code path doesn't exist on ChromeOS-Ash, since signout is not possible.
#if !BUILDFLAG(IS_CHROMEOS_ASH)
TEST_F(SyncServiceImplTest, ClearTransportDataOnInitializeWhenSignedOut) {}
#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)

TEST_F(SyncServiceImplTest, DashboardResetTwiceDoesNotCrash) {}

// Verify that credential errors get returned from GetAuthError().
TEST_F(SyncServiceImplTest, CredentialErrorReturned) {}

TEST_F(SyncServiceImplTest,
       TransportIsDisabledIfBothAuthErrorAndDisableReason) {}

// Verify that credential errors get cleared when a new token is fetched
// successfully.
TEST_F(SyncServiceImplTest, CredentialErrorClearsOnNewToken) {}

// Verify that the disable sync flag disables sync.
TEST_F(SyncServiceImplTest, DisableSyncFlag) {}

// Verify that no disable sync flag enables sync.
TEST_F(SyncServiceImplTest, NoDisableSyncFlag) {}

// Test that when SyncServiceImpl receives actionable error
// RESET_LOCAL_SYNC_DATA it restarts sync.
TEST_F(SyncServiceImplTest, ResetLocalSyncData) {}

// Test that when SyncServiceImpl receives actionable error
// DISABLE_SYNC_ON_CLIENT it disables sync and restarts the engine in transport
// mode.
TEST_F(SyncServiceImplTest, DisableSyncOnClient) {}

TEST_F(SyncServiceImplTest,
       DisableSyncOnClientLogsPassphraseTypeForNotMyBirthday) {}

TEST_F(SyncServiceImplTest,
       DisableSyncOnClientLogsPassphraseTypeForEncryptionObsolete) {}

TEST_F(SyncServiceImplTest, DisableSyncOnClientClearsPassphrasePrefForAccount) {}

TEST_F(SyncServiceImplTest,
       DisableSyncOnClientClearsPassphrasePrefForSyncingAccount) {}

TEST_F(SyncServiceImplTest, EncryptionObsoleteClearsPassphrasePrefForAccount) {}

// Verify a that local sync mode isn't impacted by sync being disabled.
TEST_F(SyncServiceImplTest, LocalBackendUnimpactedByPolicy) {}

// Test ConfigureDataTypeManagerReason on First and Nth start.
TEST_F(SyncServiceImplTest, ConfigureDataTypeManagerReason) {}

// Regression test for crbug.com/1043642, can be removed once
// SyncServiceImpl usages after shutdown are addressed.
TEST_F(SyncServiceImplTest, ShouldProvideDisableReasonsAfterShutdown) {}

TEST_F(SyncServiceImplTest, ShouldSendDataTypesToSyncInvalidationsService) {}

#if !BUILDFLAG(IS_CHROMEOS_ASH)
TEST_F(SyncServiceImplTest,
       ShouldSendDataTypesToSyncInvalidationsServiceInTransportMode) {}
#else
TEST_F(SyncServiceImplTest,
       ShouldSendDataTypesToSyncInvalidationsServiceInTransportModeAsh) {
  SignInWithSyncConsent();
  std::vector<FakeControllerInitParams> params;
  params.emplace_back(BOOKMARKS, /*enable_transport_mode=*/false);
  params.emplace_back(DEVICE_INFO, /*enable_transport_mode=*/true);
  InitializeService(std::move(params));
  base::RunLoop().RunUntilIdle();

  // In this test, BOOKMARKS doesn't support transport mode, so it should *not*
  // be included.
  // Note: Even though NIGORI technically isn't registered, it should always be
  // considered part of the interested data types.
  // Note2: InitializeForFirstSync() issued a first SetInterestedDataTypes()
  // with sync-the-feature enabled, which we don't care about. That's why this
  // expectation is set afterwards.
  EXPECT_CALL(*sync_invalidations_service(),
              SetInterestedDataTypes(AllOf(ContainsDataType(NIGORI),
                                           Not(ContainsDataType(BOOKMARKS)),
                                           ContainsDataType(DEVICE_INFO))));

  // Sync-the-feature is normally enabled in Ash. Triggering a dashboard reset
  // is one way to achieve otherwise.
  SyncProtocolError client_cmd;
  client_cmd.action = DISABLE_SYNC_ON_CLIENT;
  service()->OnActionableProtocolError(client_cmd);
  base::RunLoop().RunUntilIdle();

  ASSERT_FALSE(service()->IsSyncFeatureActive());
  EXPECT_TRUE(engine()->started_handling_invalidations());
}
#endif

TEST_F(SyncServiceImplTest, ShouldEnableAndDisableInvalidationsForSessions) {}

TEST_F(SyncServiceImplTest, ShouldNotSubscribeToProxyTypes) {}

TEST_F(SyncServiceImplTest, ShouldNotSubscribeToFailedTypes) {}

TEST_F(SyncServiceImplTest, ShouldNotSubscribeToStopAndClearDataTypes) {}

TEST_F(SyncServiceImplTest, ShouldSubscribeToStopAndKeepDataTypes) {}

TEST_F(SyncServiceImplTest, ShouldUnsubscribeWhenStopAndClear) {}

TEST_F(SyncServiceImplTest, ShouldUnsubscribeOnTypeFailure) {}

TEST_F(SyncServiceImplTest,
       ShouldActivateSyncInvalidationsServiceWhenSyncIsInitialized) {}

TEST_F(SyncServiceImplTest,
       ShouldNotStartListeningInvalidationsWhenLocalSyncEnabled) {}

TEST_F(SyncServiceImplTest,
       ShouldNotStopListeningPermanentlyOnShutdownBrowserAndKeepData) {}

TEST_F(SyncServiceImplTest, ShouldStopListeningPermanentlyOnDashboardReset) {}

TEST_F(SyncServiceImplTest, ShouldCallStopUponResetEngineIfAlreadyShutDown) {}

TEST_F(SyncServiceImplTest, ShouldReturnErrorDownloadStatus) {}

TEST_F(SyncServiceImplTest, ShouldReturnErrorDownloadStatusWhenSyncDisabled) {}

TEST_F(SyncServiceImplTest, ShouldReturnWaitingDownloadStatus) {}

TEST_F(SyncServiceImplTest, ShouldReturnErrorWhenDataTypeDisabled) {}

TEST_F(SyncServiceImplTest, ShouldWaitUntilNoInvalidations) {}

TEST_F(SyncServiceImplTest, ShouldWaitForInitializedInvalidations) {}

TEST_F(SyncServiceImplTest, ShouldWaitForPollRequest) {}

TEST_F(SyncServiceImplTest, ShouldReturnErrorOnSyncPaused) {}

// These tests cover signing in after browser startup, which isn't supported on
// ChromeOS-Ash (where there's always a signed-in user).
#if !BUILDFLAG(IS_CHROMEOS_ASH)
TEST_F(
    SyncServiceImplTest,
    GetTypesWithPendingDownloadForInitialSyncDuringFirstSyncInTransportMode) {}

TEST_F(SyncServiceImplTest,
       GetTypesWithPendingDownloadForInitialSyncDuringFirstSync) {}
#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)

TEST_F(SyncServiceImplTest,
       GetTypesWithPendingDownloadForInitialSyncDuringNthSync) {}

TEST_F(SyncServiceImplTest, EarlyCallToGetTypesWithUnsyncedDataShouldNotCrash) {}

TEST_F(SyncServiceImplTest,
       ShouldOnlyForwardEnabledTypesUponGetLocalDataDescriptions) {}

TEST_F(SyncServiceImplTest,
       ShouldNotForwardTypesWithErrorUponGetLocalDataDescriptions) {}

TEST_F(SyncServiceImplTest,
       ShouldNotForwardUponGetLocalDataDescriptionsIfSyncDisabled) {}

TEST_F(SyncServiceImplTest,
       ShouldReturnEmptyUponGetLocalDataDescriptionsForSignedOutUsers) {}

TEST_F(SyncServiceImplTest,
       ShouldReturnEmptyUponGetLocalDataDescriptionsForSyncingUsers) {}

TEST_F(SyncServiceImplTest, ShouldJoinLocalDataDescriptionsForDifferentTypes) {}

TEST_F(SyncServiceImplTest,
       ShouldOnlyForwardEnabledTypesUponTriggerLocalDataMigration) {}

TEST_F(SyncServiceImplTest,
       ShouldNotForwardTypesWithErrorUponTriggerLocalDataMigration) {}

TEST_F(SyncServiceImplTest,
       ShouldNotForwardUponTriggerLocalDataMigrationIfSyncDisabled) {}

TEST_F(SyncServiceImplTest,
       ShouldDoNothingUponTriggerLocalDataMigrationForNotSignedInUsers) {}

TEST_F(SyncServiceImplTest,
       ShouldDoNothingUponTriggerLocalDataMigrationForSyncingUsers) {}

TEST_F(SyncServiceImplTest, ShouldRecordLocalDataMigrationRequests) {}

TEST_F(SyncServiceImplTest, ShouldNotifyOnManagedPrefDisabled) {}

TEST_F(SyncServiceImplTest, ShouldCacheTrustedVaultAutoUpgradeDebugInfo) {}

}  // namespace
}  // namespace syncer