| Index: chrome/browser/sync/test/integration/single_client_extensions_sync_test.cc
|
| diff --git a/chrome/browser/sync/test/integration/single_client_extensions_sync_test.cc b/chrome/browser/sync/test/integration/single_client_extensions_sync_test.cc
|
| index a5cda2282a38829284cb1b8dedc8562d06fd7610..efb7788a2b6228dd156d84e53ea389dc8309509c 100644
|
| --- a/chrome/browser/sync/test/integration/single_client_extensions_sync_test.cc
|
| +++ b/chrome/browser/sync/test/integration/single_client_extensions_sync_test.cc
|
| @@ -3,13 +3,18 @@
|
| // found in the LICENSE file.
|
|
|
| #include "base/macros.h"
|
| +#include "chrome/browser/sync/test/integration/await_match_status_change_checker.h"
|
| #include "chrome/browser/sync/test/integration/extensions_helper.h"
|
| #include "chrome/browser/sync/test/integration/sync_integration_test_util.h"
|
| #include "chrome/browser/sync/test/integration/sync_test.h"
|
| #include "components/browser_sync/browser/profile_sync_service.h"
|
| +#include "sync/test/fake_server/tombstone_entity.h"
|
|
|
| using extensions_helper::AllProfilesHaveSameExtensionsAsVerifier;
|
| +using extensions_helper::DisableExtension;
|
| +using extensions_helper::GetInstalledExtensions;
|
| using extensions_helper::InstallExtension;
|
| +using extensions_helper::InstallExtensionForAllProfiles;
|
| using sync_integration_test_util::AwaitCommitActivityCompletion;
|
|
|
| class SingleClientExtensionsSyncTest : public SyncTest {
|
| @@ -56,3 +61,48 @@ IN_PROC_BROWSER_TEST_F(SingleClientExtensionsSyncTest, InstallSomeExtensions) {
|
|
|
| ASSERT_TRUE(AllProfilesHaveSameExtensionsAsVerifier());
|
| }
|
| +
|
| +// Helper function for waiting to see the extension count in a profile
|
| +// become a specific number.
|
| +static bool ExtensionCountCheck(Profile* profile, size_t expected_count) {
|
| + return GetInstalledExtensions(profile).size() == expected_count;
|
| +}
|
| +
|
| +// Tests the case of an uninstall from the server conflicting with a local
|
| +// modification, which we expect to be resolved in favor of the uninstall.
|
| +IN_PROC_BROWSER_TEST_F(SingleClientExtensionsSyncTest, UninstallWinsConflicts) {
|
| + ASSERT_TRUE(SetupClients());
|
| +
|
| + // Start with an extension installed, and setup sync.
|
| + InstallExtensionForAllProfiles(0);
|
| + ASSERT_TRUE(SetupSync());
|
| + EXPECT_TRUE(AllProfilesHaveSameExtensionsAsVerifier());
|
| +
|
| + // Simulate a delete at the server.
|
| + std::vector<sync_pb::SyncEntity> server_extensions =
|
| + GetFakeServer()->GetSyncEntitiesByModelType(syncer::EXTENSIONS);
|
| + ASSERT_EQ(1ul, server_extensions.size());
|
| + std::string entity_id = server_extensions[0].id_string();
|
| + scoped_ptr<fake_server::FakeServerEntity> tombstone(
|
| + fake_server::TombstoneEntity::Create(entity_id));
|
| + GetFakeServer()->InjectEntity(std::move(tombstone));
|
| +
|
| + // Modify the extension in the local profile to cause a conflict.
|
| + DisableExtension(GetProfile(0), 0);
|
| + EXPECT_EQ(1u, GetInstalledExtensions(GetProfile(0)).size());
|
| +
|
| + // Trigger sync, and expect the extension to remain uninstalled at the server
|
| + // and get uninstalled locally.
|
| + const syncer::ModelTypeSet kExtensionsType(syncer::EXTENSIONS);
|
| + TriggerSyncForModelTypes(0, kExtensionsType);
|
| + server_extensions =
|
| + GetFakeServer()->GetSyncEntitiesByModelType(syncer::EXTENSIONS);
|
| + EXPECT_EQ(0ul, server_extensions.size());
|
| +
|
| + AwaitMatchStatusChangeChecker checker(
|
| + base::Bind(&ExtensionCountCheck, GetProfile(0), 0u),
|
| + "Waiting for profile to have no extensions");
|
| + checker.Wait();
|
| + EXPECT_TRUE(!checker.TimedOut());
|
| + EXPECT_TRUE(GetInstalledExtensions(GetProfile(0)).empty());
|
| +}
|
|
|