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

Unified Diff: chrome/browser/extensions/extension_service_sync_unittest.cc

Issue 2923013006: [Extensions Sync] Don't apply sync data for unsyncable extensions (Closed)
Patch Set: lazyboy's Created 3 years, 6 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/extensions/extension_service_sync_unittest.cc
diff --git a/chrome/browser/extensions/extension_service_sync_unittest.cc b/chrome/browser/extensions/extension_service_sync_unittest.cc
index 8d91faa87b5eb1c7562a79d2734f2967b68abf3c..37e5e11d8cee08342ad97eef45ca13e8a969f7f8 100644
--- a/chrome/browser/extensions/extension_service_sync_unittest.cc
+++ b/chrome/browser/extensions/extension_service_sync_unittest.cc
@@ -20,6 +20,7 @@
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/api/webstore_private/webstore_private_api.h"
+#include "chrome/browser/extensions/chrome_test_extension_loader.h"
#include "chrome/browser/extensions/component_loader.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_service_test_with_install.h"
@@ -94,6 +95,31 @@ const char page_action[] = "obcimlgaoabeegjmmpldobjndiealpln";
const char permissions_increase[] = "pgdpcfcocojkjfbgpiianjngphoopgmo";
const char theme2_crx[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
+ExtensionSyncData GetDisableSyncData(const Extension& extension,
+ int disable_reasons) {
+ bool enabled = false;
+ bool incognito_enabled = false;
+ bool remote_install = false;
+ bool installed_by_custodian = false;
+ ExtensionSyncData::OptionalBoolean has_all_urls =
+ ExtensionSyncData::BOOLEAN_UNSET;
+ return ExtensionSyncData(extension, enabled, disable_reasons,
+ incognito_enabled, remote_install, has_all_urls,
+ installed_by_custodian);
+}
+
+ExtensionSyncData GetEnableSyncData(const Extension& extension) {
+ bool enabled = true;
+ bool incognito_enabled = false;
+ bool remote_install = false;
+ bool installed_by_custodian = false;
+ ExtensionSyncData::OptionalBoolean has_all_urls =
+ ExtensionSyncData::BOOLEAN_UNSET;
+ return ExtensionSyncData(extension, enabled, Extension::DISABLE_NONE,
+ incognito_enabled, remote_install, has_all_urls,
+ installed_by_custodian);
+}
+
SyncChangeList MakeSyncChangeList(const std::string& id,
const sync_pb::EntitySpecifics& specifics,
SyncChange::SyncChangeType change_type) {
@@ -200,6 +226,22 @@ class ExtensionServiceSyncTest
base::MakeUnique<syncer::SyncErrorFactoryMock>());
}
+ void DisableExtensionFromSync(const Extension& extension,
+ int disable_reasons) {
+ ExtensionSyncData disable_extension =
+ GetDisableSyncData(extension, Extension::DISABLE_USER_ACTION);
+ SyncChangeList list(
+ 1, disable_extension.GetSyncChange(SyncChange::ACTION_UPDATE));
+ extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
+ }
+
+ void EnableExtensionFromSync(const Extension& extension) {
+ ExtensionSyncData enable_extension = GetEnableSyncData(extension);
+ SyncChangeList list(
+ 1, enable_extension.GetSyncChange(SyncChange::ACTION_UPDATE));
+ extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
+ }
+
protected:
// Paths to some of the fake extensions.
base::FilePath good0_path() {
@@ -340,6 +382,144 @@ TEST_F(ExtensionServiceSyncTest, DisableExtensionFromSync) {
ASSERT_FALSE(service()->IsExtensionEnabled(good0));
}
+// Test that sync can enable and disable installed extensions.
+TEST_F(ExtensionServiceSyncTest, ReenableDisabledExtensionFromSync) {
+ InitializeEmptyExtensionService();
+
+ // Enable sync.
+ browser_sync::ProfileSyncService* sync_service =
+ ProfileSyncServiceFactory::GetForProfile(profile());
+ sync_service->SetFirstSetupComplete();
+
+ service()->Init();
+
+ // Load up a simple extension.
+ extensions::ChromeTestExtensionLoader extension_loader(profile());
+ extension_loader.set_pack_extension(true);
+ scoped_refptr<const Extension> extension = extension_loader.LoadExtension(
+ data_dir().AppendASCII("simple_with_file"));
+ ASSERT_TRUE(extension);
+ const std::string kExtensionId = extension->id();
+ ASSERT_TRUE(registry()->enabled_extensions().GetByID(kExtensionId));
+
+ syncer::FakeSyncChangeProcessor* processor_raw = nullptr;
+ {
+ auto processor = base::MakeUnique<syncer::FakeSyncChangeProcessor>();
+ processor_raw = processor.get();
+ extension_sync_service()->MergeDataAndStartSyncing(
+ syncer::EXTENSIONS, syncer::SyncDataList(), std::move(processor),
+ base::MakeUnique<syncer::SyncErrorFactoryMock>());
+ }
+ processor_raw->changes().clear();
+
+ DisableExtensionFromSync(*extension, Extension::DISABLE_USER_ACTION);
+
+ // The extension should be disabled.
+ EXPECT_TRUE(registry()->disabled_extensions().GetByID(kExtensionId));
+ EXPECT_EQ(Extension::DISABLE_USER_ACTION,
+ ExtensionPrefs::Get(profile())->GetDisableReasons(kExtensionId));
+ EXPECT_TRUE(processor_raw->changes().empty());
+
+ // Enable the extension. Sync should push the new state.
+ service()->EnableExtension(kExtensionId);
+ {
+ ASSERT_EQ(1u, processor_raw->changes().size());
+ const SyncChange& change = processor_raw->changes()[0];
+ EXPECT_EQ(SyncChange::ACTION_UPDATE, change.change_type());
+ std::unique_ptr<ExtensionSyncData> data =
+ ExtensionSyncData::CreateFromSyncData(change.sync_data());
+ EXPECT_EQ(kExtensionId, data->id());
+ EXPECT_EQ(0, data->disable_reasons());
+ EXPECT_TRUE(data->enabled());
+ }
+
+ // Disable the extension again. Sync should push the new state.
+ processor_raw->changes().clear();
+ service()->DisableExtension(kExtensionId, Extension::DISABLE_USER_ACTION);
+ EXPECT_TRUE(registry()->disabled_extensions().GetByID(kExtensionId));
+ {
+ ASSERT_EQ(1u, processor_raw->changes().size());
+ const SyncChange& change = processor_raw->changes()[0];
+ EXPECT_EQ(SyncChange::ACTION_UPDATE, change.change_type());
+ std::unique_ptr<ExtensionSyncData> data =
+ ExtensionSyncData::CreateFromSyncData(change.sync_data());
+ EXPECT_EQ(kExtensionId, data->id());
+ EXPECT_EQ(Extension::DISABLE_USER_ACTION, data->disable_reasons());
+ EXPECT_FALSE(data->enabled());
+ }
+ processor_raw->changes().clear();
+
+ // Enable the extension via sync.
+ EnableExtensionFromSync(*extension);
+
+ // The extension should be enabled.
+ EXPECT_TRUE(registry()->enabled_extensions().GetByID(kExtensionId));
+ EXPECT_TRUE(processor_raw->changes().empty());
+}
+
+// Tests that default-installed extensions won't be affected by incoming sync
+// data. (It's feasible to have a sync entry for an extension that could be
+// default installed, since one installation may be default-installed while
+// another may not be).
+TEST_F(ExtensionServiceSyncTest,
+ DefaultInstalledExtensionsAreNotReenabledOrDisabledBySync) {
+ InitializeEmptyExtensionService();
+
+ // Enable sync.
+ browser_sync::ProfileSyncService* sync_service =
+ ProfileSyncServiceFactory::GetForProfile(profile());
+ sync_service->SetFirstSetupComplete();
+
+ service()->Init();
+
+ // Load up an extension that's considered default installed.
+ extensions::ChromeTestExtensionLoader extension_loader(profile());
+ extension_loader.set_pack_extension(true);
+ extension_loader.add_creation_flag(Extension::WAS_INSTALLED_BY_DEFAULT);
+ scoped_refptr<const Extension> extension = extension_loader.LoadExtension(
+ data_dir().AppendASCII("simple_with_file"));
+ ASSERT_TRUE(extension);
+
+ // The extension shouldn't sync.
+ EXPECT_FALSE(extensions::util::ShouldSync(extension.get(), profile()));
+ const std::string kExtensionId = extension->id();
+ ASSERT_TRUE(registry()->enabled_extensions().GetByID(kExtensionId));
+
+ syncer::FakeSyncChangeProcessor* processor_raw = nullptr;
+ {
+ auto processor = base::MakeUnique<syncer::FakeSyncChangeProcessor>();
+ processor_raw = processor.get();
+ extension_sync_service()->MergeDataAndStartSyncing(
+ syncer::EXTENSIONS, syncer::SyncDataList(), std::move(processor),
+ base::MakeUnique<syncer::SyncErrorFactoryMock>());
+ }
+ processor_raw->changes().clear();
+
+ // Sync state says the extension is disabled (e.g. on another machine).
+ DisableExtensionFromSync(*extension, Extension::DISABLE_USER_ACTION);
+
+ // The extension should still be enabled, since it's default-installed.
+ EXPECT_TRUE(registry()->enabled_extensions().GetByID(kExtensionId));
+ EXPECT_TRUE(processor_raw->changes().empty());
+
+ // Now disable the extension locally. Sync should *not* push new state.
+ service()->DisableExtension(kExtensionId, Extension::DISABLE_USER_ACTION);
+ EXPECT_TRUE(registry()->disabled_extensions().GetByID(kExtensionId));
+ EXPECT_TRUE(processor_raw->changes().empty());
+
+ // Sync state says the extension is enabled.
+ EnableExtensionFromSync(*extension);
+
+ // As above, the extension should not have been affected by sync.
+ EXPECT_TRUE(registry()->disabled_extensions().GetByID(kExtensionId));
+ EXPECT_TRUE(processor_raw->changes().empty());
+
+ // And re-enabling the extension should not push new state to sync.
+ service()->EnableExtension(kExtensionId);
+ EXPECT_TRUE(registry()->enabled_extensions().GetByID(kExtensionId));
+ EXPECT_TRUE(processor_raw->changes().empty());
+}
+
TEST_F(ExtensionServiceSyncTest, IgnoreSyncChangesWhenLocalStateIsMoreRecent) {
// Start the extension service with three extensions already installed.
base::FilePath source_install_dir =
@@ -1362,6 +1542,13 @@ TEST_F(ExtensionServiceSyncTest, ProcessSyncDataEnableDisable) {
}
TEST_F(ExtensionServiceSyncTest, ProcessSyncDataDeferredEnable) {
+ // The permissions_increase test extension has a different update URL.
+ // In order to make it syncable, we have to pretend it syncs from the
+ // webstore.
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kAppsGalleryUpdateURL,
+ "http://localhost/autoupdate/updates.xml");
+
InitializeEmptyExtensionService();
extension_sync_service()->MergeDataAndStartSyncing(
syncer::EXTENSIONS, syncer::SyncDataList(),
« no previous file with comments | « chrome/browser/extensions/chrome_test_extension_loader.cc ('k') | chrome/browser/extensions/extension_sync_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698