This source file includes following definitions.
- GetErrors
- AddPattern
- GetTemporaryFile
- WaitForCountNotificationsCallback
- visit_count_
- UpdateOrAddExtension
- RemoveExtension
- VisitRegisteredExtension
- HasExtension
- GetExtensionDetails
- IsReady
- ServiceShutdown
- visit_count
- set_visit_count
- expected_creation_flags_
- expected_creation_flags_
- Visit
- OnExternalExtensionFileFound
- OnExternalExtensionUpdateUrlFound
- OnExternalProviderReady
- profile_is_managed
- registry_
- InitializeExtensionService
- CreateTestingProfile
- InitializeExtensionServiceForProfile
- InitializeInstalledExtensionService
- InitializeGoodInstalledExtensionService
- InitializeEmptyExtensionService
- InitializeProcessManager
- InitializeExtensionServiceWithUpdater
- InitializeExtensionSyncService
- SetUpTestCase
- SetUp
- TearDown
- CreateDefaultInitParams
- CreateDefaultInitParamsInTempDir
- override_external_install_prompt_
- Observe
- AddMockExternalProvider
- MockSyncStartFlare
- good0_path
- good1_path
- good2_path
- PackCRX
- PackAndInstallCRX
- PackAndInstallCRX
- PackAndInstallCRX
- InstallCRX
- InstallCRX
- InstallCRX
- InstallCRXFromWebStore
- InstallCRXWithLocation
- VerifyCrxInstall
- VerifyCrxInstall
- BlackListWebGL
- IsCrxInstallerDone
- UpdateExtension
- TerminateExtension
- GetPrefKeyCount
- UninstallExtension
- ValidatePrefKeyCount
- ValidateBooleanPref
- IsPrefExist
- ValidateIntegerPref
- ValidateStringPref
- SetPref
- SetPrefInteg
- SetPrefBool
- ClearPref
- SetPrefStringSet
- InitPluginService
- InstallCRXInternal
- InstallCRXInternal
- expected_private_key_path_
- OnPackSuccess
- OnPackFailure
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- IsExtension
- TEST_F
- TEST_F
- IsTheme
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- weak_factory_
- SetCookieCallback
- GetAllCookiesCallback
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TestExternalProvider
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- set_ready
- ready
- Observe
- TEST
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- SetUp
- AddPendingExternalPrefUrl
- AddPendingExternalPrefFileInstall
- AddPendingSyncInstall
- AddPendingPolicyInstall
- GetPendingLocation
- GetPendingIsFromSync
- IsCrxPending
- IsCrxInstalled
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "chrome/browser/extensions/extension_service_unittest.h"
#include <algorithm>
#include <set>
#include <vector>
#include "base/at_exit.h"
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_enumerator.h"
#include "base/files/scoped_temp_dir.h"
#include "base/json/json_file_value_serializer.h"
#include "base/json/json_reader.h"
#include "base/json/json_string_value_serializer.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/prefs/scoped_user_pref_update.h"
#include "base/stl_util.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/version.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/app_sync_data.h"
#include "chrome/browser/extensions/blacklist.h"
#include "chrome/browser/extensions/chrome_app_sorting.h"
#include "chrome/browser/extensions/component_loader.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/default_apps.h"
#include "chrome/browser/extensions/extension_creator.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
#include "chrome/browser/extensions/extension_error_ui.h"
#include "chrome/browser/extensions/extension_notification_observer.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_special_storage_policy.h"
#include "chrome/browser/extensions/extension_sync_data.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/extensions/external_install_ui.h"
#include "chrome/browser/extensions/external_policy_loader.h"
#include "chrome/browser/extensions/external_pref_loader.h"
#include "chrome/browser/extensions/external_provider_impl.h"
#include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
#include "chrome/browser/extensions/install_observer.h"
#include "chrome/browser/extensions/install_tracker.h"
#include "chrome/browser/extensions/install_tracker_factory.h"
#include "chrome/browser/extensions/installed_loader.h"
#include "chrome/browser/extensions/pack_extension_job.h"
#include "chrome/browser/extensions/pending_extension_info.h"
#include "chrome/browser/extensions/pending_extension_manager.h"
#include "chrome/browser/extensions/test_blacklist.h"
#include "chrome/browser/extensions/test_extension_system.h"
#include "chrome/browser/extensions/unpacked_installer.h"
#include "chrome/browser/extensions/updater/extension_updater.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/prefs/pref_service_mock_factory.h"
#include "chrome/browser/prefs/pref_service_syncable.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/api/plugins/plugins_handler.h"
#include "chrome/common/extensions/extension_l10n_util.h"
#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "chrome/common/extensions/manifest_url_handler.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/scoped_browser_locale.h"
#include "chrome/test/base/testing_profile.h"
#include "components/user_prefs/pref_registry_syncable.h"
#include "content/public/browser/dom_storage_context.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/indexed_db_context.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_constants.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/external_provider_interface.h"
#include "extensions/browser/management_policy.h"
#include "extensions/browser/pref_names.h"
#include "extensions/browser/test_management_policy.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/extension_resource.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/manifest_handlers/background_info.h"
#include "extensions/common/permissions/permission_set.h"
#include "extensions/common/switches.h"
#include "extensions/common/url_pattern.h"
#include "extensions/common/value_builder.h"
#include "gpu/config/gpu_info.h"
#include "grit/browser_resources.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_monster.h"
#include "net/cookies/cookie_options.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "sync/api/fake_sync_change_processor.h"
#include "sync/api/string_ordinal.h"
#include "sync/api/sync_data.h"
#include "sync/api/sync_error_factory.h"
#include "sync/api/sync_error_factory_mock.h"
#include "sync/api/syncable_service.h"
#include "sync/protocol/app_specifics.pb.h"
#include "sync/protocol/extension_specifics.pb.h"
#include "sync/protocol/sync.pb.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
#include "url/gurl.h"
#include "webkit/browser/database/database_tracker.h"
#include "webkit/browser/quota/quota_manager.h"
#include "webkit/common/database/database_identifier.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/extensions/install_limiter.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/device_settings_service.h"
#endif
#if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING)
#define ENABLE_BLACKLIST_TESTS
#endif
using base::DictionaryValue;
using base::ListValue;
using base::Value;
using content::BrowserContext;
using content::BrowserThread;
using content::DOMStorageContext;
using content::IndexedDBContext;
using content::PluginService;
using extensions::APIPermission;
using extensions::APIPermissionSet;
using extensions::AppSorting;
using extensions::Blacklist;
using extensions::CrxInstaller;
using extensions::Extension;
using extensions::ExtensionCreator;
using extensions::ExtensionPrefs;
using extensions::ExtensionRegistry;
using extensions::ExtensionResource;
using extensions::ExtensionSystem;
using extensions::FakeSafeBrowsingDatabaseManager;
using extensions::FeatureSwitch;
using extensions::Manifest;
using extensions::PermissionSet;
using extensions::TestExtensionSystem;
using extensions::URLPatternSet;
namespace keys = extensions::manifest_keys;
namespace {
const char good0[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
const char good1[] = "hpiknbiabeeppbpihjehijgoemciehgk";
const char good2[] = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
const char all_zero[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
const char good2048[] = "nmgjhmhbleinmjpbdhgajfjkbijcmgbh";
const char good_crx[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
const char hosted_app[] = "kbmnembihfiondgfjekmnmcbddelicoi";
const char page_action[] = "obcimlgaoabeegjmmpldobjndiealpln";
const char theme_crx[] = "iamefpfkojoapidjnbafmgkgncegbkad";
const char theme2_crx[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
const char permissions_crx[] = "eagpmdpfmaekmmcejjbmjoecnejeiiin";
const char unpacked[] = "cbcdidchbppangcjoddlpdjlenngjldk";
const char updates_from_webstore[] = "akjooamlhcgeopfifcmlggaebeocgokj";
struct ExtensionsOrder {
bool operator()(const scoped_refptr<const Extension>& a,
const scoped_refptr<const Extension>& b) {
return a->name() < b->name();
}
};
static std::vector<base::string16> GetErrors() {
const std::vector<base::string16>* errors =
ExtensionErrorReporter::GetInstance()->GetErrors();
std::vector<base::string16> ret_val;
for (std::vector<base::string16>::const_iterator iter = errors->begin();
iter != errors->end(); ++iter) {
std::string utf8_error = base::UTF16ToUTF8(*iter);
if (utf8_error.find(".svn") == std::string::npos) {
ret_val.push_back(*iter);
}
}
std::stable_sort(ret_val.begin(), ret_val.end());
return ret_val;
}
static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
int schemes = URLPattern::SCHEME_ALL;
extent->AddPattern(URLPattern(schemes, pattern));
}
base::FilePath GetTemporaryFile() {
base::FilePath temp_file;
CHECK(base::CreateTemporaryFile(&temp_file));
return temp_file;
}
bool WaitForCountNotificationsCallback(int *count) {
return --(*count) == 0;
}
}
class MockExtensionProvider : public extensions::ExternalProviderInterface {
public:
MockExtensionProvider(
VisitorInterface* visitor,
Manifest::Location location)
: location_(location), visitor_(visitor), visit_count_(0) {
}
virtual ~MockExtensionProvider() {}
void UpdateOrAddExtension(const std::string& id,
const std::string& version,
const base::FilePath& path) {
extension_map_[id] = std::make_pair(version, path);
}
void RemoveExtension(const std::string& id) {
extension_map_.erase(id);
}
virtual void VisitRegisteredExtension() OVERRIDE {
visit_count_++;
for (DataMap::const_iterator i = extension_map_.begin();
i != extension_map_.end(); ++i) {
Version version(i->second.first);
visitor_->OnExternalExtensionFileFound(
i->first, &version, i->second.second, location_,
Extension::NO_FLAGS, false);
}
visitor_->OnExternalProviderReady(this);
}
virtual bool HasExtension(const std::string& id) const OVERRIDE {
return extension_map_.find(id) != extension_map_.end();
}
virtual bool GetExtensionDetails(
const std::string& id,
Manifest::Location* location,
scoped_ptr<Version>* version) const OVERRIDE {
DataMap::const_iterator it = extension_map_.find(id);
if (it == extension_map_.end())
return false;
if (version)
version->reset(new Version(it->second.first));
if (location)
*location = location_;
return true;
}
virtual bool IsReady() const OVERRIDE {
return true;
}
virtual void ServiceShutdown() OVERRIDE {
}
int visit_count() const { return visit_count_; }
void set_visit_count(int visit_count) {
visit_count_ = visit_count;
}
private:
typedef std::map< std::string, std::pair<std::string, base::FilePath> >
DataMap;
DataMap extension_map_;
Manifest::Location location_;
VisitorInterface* visitor_;
mutable int visit_count_;
DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider);
};
class MockProviderVisitor
: public extensions::ExternalProviderInterface::VisitorInterface {
public:
explicit MockProviderVisitor(base::FilePath fake_base_path)
: ids_found_(0),
fake_base_path_(fake_base_path),
expected_creation_flags_(Extension::NO_FLAGS) {
profile_.reset(new TestingProfile);
}
MockProviderVisitor(base::FilePath fake_base_path,
int expected_creation_flags)
: ids_found_(0),
fake_base_path_(fake_base_path),
expected_creation_flags_(expected_creation_flags) {
}
int Visit(const std::string& json_data) {
provider_.reset(new extensions::ExternalProviderImpl(
this,
new extensions::ExternalTestingLoader(json_data, fake_base_path_),
profile_.get(),
Manifest::EXTERNAL_PREF,
Manifest::EXTERNAL_PREF_DOWNLOAD,
Extension::NO_FLAGS));
JSONStringValueSerializer serializer(json_data);
base::Value* json_value = serializer.Deserialize(NULL, NULL);
if (!json_value || !json_value->IsType(base::Value::TYPE_DICTIONARY)) {
NOTREACHED() << "Unable to deserialize json data";
return -1;
} else {
base::DictionaryValue* external_extensions =
static_cast<base::DictionaryValue*>(json_value);
prefs_.reset(external_extensions);
}
ids_found_ = 0;
provider_->VisitRegisteredExtension();
return ids_found_;
}
virtual bool OnExternalExtensionFileFound(const std::string& id,
const Version* version,
const base::FilePath& path,
Manifest::Location unused,
int creation_flags,
bool mark_acknowledged) OVERRIDE {
EXPECT_EQ(expected_creation_flags_, creation_flags);
++ids_found_;
base::DictionaryValue* pref;
EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
<< "Got back ID (" << id.c_str() << ") we weren't expecting";
EXPECT_TRUE(path.IsAbsolute());
if (!fake_base_path_.empty())
EXPECT_TRUE(fake_base_path_.IsParent(path));
if (pref) {
EXPECT_TRUE(provider_->HasExtension(id));
Manifest::Location location = Manifest::INVALID_LOCATION;
scoped_ptr<Version> v1;
base::FilePath crx_path;
EXPECT_TRUE(provider_->GetExtensionDetails(id, NULL, &v1));
EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
scoped_ptr<Version> v2;
EXPECT_TRUE(provider_->GetExtensionDetails(id, &location, &v2));
EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
EXPECT_STREQ(version->GetString().c_str(), v2->GetString().c_str());
EXPECT_EQ(Manifest::EXTERNAL_PREF, location);
prefs_->Remove(id, NULL);
}
return true;
}
virtual bool OnExternalExtensionUpdateUrlFound(
const std::string& id,
const std::string& install_parameter,
const GURL& update_url,
Manifest::Location location,
int creation_flags,
bool mark_acknowledged) OVERRIDE {
++ids_found_;
base::DictionaryValue* pref;
EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
<< L"Got back ID (" << id.c_str() << ") we weren't expecting";
EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location);
if (pref) {
EXPECT_TRUE(provider_->HasExtension(id));
scoped_ptr<Version> v1;
Manifest::Location location1 = Manifest::INVALID_LOCATION;
EXPECT_TRUE(provider_->GetExtensionDetails(id, &location1, &v1));
EXPECT_FALSE(v1.get());
EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location1);
std::string parsed_install_parameter;
pref->GetString("install_parameter", &parsed_install_parameter);
EXPECT_EQ(parsed_install_parameter, install_parameter);
prefs_->Remove(id, NULL);
}
return true;
}
virtual void OnExternalProviderReady(
const extensions::ExternalProviderInterface* provider) OVERRIDE {
EXPECT_EQ(provider, provider_.get());
EXPECT_TRUE(provider->IsReady());
}
private:
int ids_found_;
base::FilePath fake_base_path_;
int expected_creation_flags_;
scoped_ptr<extensions::ExternalProviderImpl> provider_;
scoped_ptr<base::DictionaryValue> prefs_;
scoped_ptr<TestingProfile> profile_;
DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor);
};
ExtensionServiceTestBase::ExtensionServiceInitParams::
ExtensionServiceInitParams()
: autoupdate_enabled(false), is_first_run(true), profile_is_managed(false) {
}
ExtensionServiceTestBase::ExtensionServiceTestBase()
: thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
service_(NULL),
management_policy_(NULL),
expected_extensions_count_(0),
registry_(NULL) {
base::FilePath test_data_dir;
if (!PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)) {
ADD_FAILURE();
return;
}
data_dir_ = test_data_dir.AppendASCII("extensions");
}
ExtensionServiceTestBase::~ExtensionServiceTestBase() {
service_ = NULL;
}
void ExtensionServiceTestBase::InitializeExtensionService(
const ExtensionServiceTestBase::ExtensionServiceInitParams& params) {
profile_ = CreateTestingProfile(params);
service_ = InitializeExtensionServiceForProfile(params, profile_.get());
management_policy_ =
ExtensionSystem::Get(profile_.get())->management_policy();
extensions_install_dir_ = params.extensions_install_dir;
expected_extensions_count_ = 0;
registry_ = extensions::ExtensionRegistry::Get(profile_.get());
}
scoped_ptr<TestingProfile> ExtensionServiceTestBase::CreateTestingProfile(
const ExtensionServiceInitParams& params) {
TestingProfile::Builder profile_builder;
PrefServiceMockFactory factory;
if (!params.pref_file.empty()) {
factory.SetUserPrefsFile(params.pref_file,
base::MessageLoopProxy::current().get());
scoped_refptr<user_prefs::PrefRegistrySyncable> registry(
new user_prefs::PrefRegistrySyncable);
scoped_ptr<PrefServiceSyncable> prefs(
factory.CreateSyncable(registry.get()));
chrome::RegisterUserProfilePrefs(registry.get());
profile_builder.SetPrefService(prefs.Pass());
}
if (params.profile_is_managed)
profile_builder.SetManagedUserId("asdf");
profile_builder.SetPath(params.profile_path);
return profile_builder.Build();
}
ExtensionService*
ExtensionServiceTestBase::InitializeExtensionServiceForProfile(
const ExtensionServiceInitParams& params,
Profile* profile) {
TestExtensionSystem* system = static_cast<TestExtensionSystem*>(
ExtensionSystem::Get(profile));
if (!params.is_first_run) {
ExtensionPrefs* prefs = system->CreateExtensionPrefs(
CommandLine::ForCurrentProcess(),
params.extensions_install_dir);
prefs->SetAlertSystemFirstRun();
}
ExtensionService* service = system->CreateExtensionService(
CommandLine::ForCurrentProcess(),
params.extensions_install_dir,
params.autoupdate_enabled);
service->SetFileTaskRunnerForTesting(
base::MessageLoopProxy::current().get());
service->set_extensions_enabled(true);
service->set_show_extensions_prompts(false);
service->set_install_updates_when_idle_for_test(false);
service->ClearProvidersForTesting();
#if defined(OS_CHROMEOS)
extensions::InstallLimiter::Get(profile)->DisableForTest();
#endif
return service;
}
void ExtensionServiceTestBase::InitializeInstalledExtensionService(
const base::FilePath& prefs_file,
const base::FilePath& source_install_dir) {
EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
base::FilePath path = temp_dir_.path();
path = path.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
EXPECT_TRUE(base::DeleteFile(path, true));
base::File::Error error = base::File::FILE_OK;
EXPECT_TRUE(base::CreateDirectoryAndGetError(path, &error)) << error;
base::FilePath temp_prefs = path.Append(chrome::kPreferencesFilename);
EXPECT_TRUE(base::CopyFile(prefs_file, temp_prefs));
base::FilePath extensions_install_dir =
path.Append(FILE_PATH_LITERAL("Extensions"));
EXPECT_TRUE(base::DeleteFile(extensions_install_dir, true));
EXPECT_TRUE(
base::CopyDirectory(source_install_dir, extensions_install_dir, true));
ExtensionServiceInitParams params;
params.profile_path = path;
params.pref_file = temp_prefs;
params.extensions_install_dir = extensions_install_dir;
InitializeExtensionService(params);
}
void ExtensionServiceTestBase::InitializeGoodInstalledExtensionService() {
base::FilePath source_install_dir = data_dir_
.AppendASCII("good")
.AppendASCII("Extensions");
base::FilePath pref_path =
source_install_dir.DirName().Append(chrome::kPreferencesFilename);
InitializeInstalledExtensionService(pref_path, source_install_dir);
}
void ExtensionServiceTestBase::InitializeEmptyExtensionService() {
InitializeExtensionService(CreateDefaultInitParams());
}
void ExtensionServiceTestBase::InitializeProcessManager() {
static_cast<extensions::TestExtensionSystem*>(
ExtensionSystem::Get(profile_.get()))->
CreateProcessManager();
}
void ExtensionServiceTestBase::InitializeExtensionServiceWithUpdater() {
ExtensionServiceInitParams params = CreateDefaultInitParams();
params.autoupdate_enabled = true;
InitializeExtensionService(params);
service_->updater()->Start();
}
void ExtensionServiceTestBase::InitializeExtensionSyncService() {
extension_sync_service_.reset(new ExtensionSyncService(
profile_.get(), ExtensionPrefs::Get(profile_.get()), service_));
}
void ExtensionServiceTestBase::SetUpTestCase() {
ExtensionErrorReporter::Init(false);
}
void ExtensionServiceTestBase::SetUp() {
ExtensionErrorReporter::GetInstance()->ClearErrors();
}
void ExtensionServiceTestBase::TearDown() {
}
ExtensionServiceTestBase::ExtensionServiceInitParams
ExtensionServiceTestBase::CreateDefaultInitParams() {
return CreateDefaultInitParamsInTempDir(&temp_dir_);
}
ExtensionServiceTestBase::ExtensionServiceInitParams
ExtensionServiceTestBase::CreateDefaultInitParamsInTempDir(
base::ScopedTempDir* temp_dir) {
ExtensionServiceInitParams params;
EXPECT_TRUE(temp_dir->CreateUniqueTempDir());
base::FilePath path = temp_dir->path();
path = path.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
EXPECT_TRUE(base::DeleteFile(path, true));
base::File::Error error = base::File::FILE_OK;
EXPECT_TRUE(base::CreateDirectoryAndGetError(path, &error)) << error;
base::FilePath prefs_filename =
path.Append(FILE_PATH_LITERAL("TestPreferences"));
base::FilePath extensions_install_dir =
path.Append(FILE_PATH_LITERAL("Extensions"));
EXPECT_TRUE(base::DeleteFile(extensions_install_dir, true));
EXPECT_TRUE(base::CreateDirectoryAndGetError(extensions_install_dir,
&error)) << error;
params.profile_path = path;
params.pref_file = prefs_filename;
params.extensions_install_dir = extensions_install_dir;
return params;
}
class ExtensionServiceTest
: public ExtensionServiceTestBase, public content::NotificationObserver {
public:
ExtensionServiceTest()
: installed_(NULL),
was_update_(false),
override_external_install_prompt_(
FeatureSwitch::prompt_for_external_extensions(), false) {
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
content::NotificationService::AllSources());
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
content::NotificationService::AllSources());
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
content::NotificationService::AllSources());
}
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE {
switch (type) {
case chrome::NOTIFICATION_EXTENSION_LOADED: {
const Extension* extension =
content::Details<const Extension>(details).ptr();
loaded_.push_back(make_scoped_refptr(extension));
std::stable_sort(loaded_.begin(), loaded_.end(), ExtensionsOrder());
break;
}
case chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: {
const Extension* e =
content::Details<extensions::UnloadedExtensionInfo>(
details)->extension;
unloaded_id_ = e->id();
extensions::ExtensionList::iterator i =
std::find(loaded_.begin(), loaded_.end(), e);
if (i == loaded_.end())
return;
loaded_.erase(i);
break;
}
case chrome::NOTIFICATION_EXTENSION_INSTALLED: {
const extensions::InstalledExtensionInfo* installed_info =
content::Details<const extensions::InstalledExtensionInfo>(details)
.ptr();
installed_ = installed_info->extension;
was_update_ = installed_info->is_update;
old_name_ = installed_info->old_name;
break;
}
default:
DCHECK(false);
}
}
void AddMockExternalProvider(
extensions::ExternalProviderInterface* provider) {
service_->AddProviderForTesting(provider);
}
void MockSyncStartFlare(bool* was_called,
syncer::ModelType* model_type_passed_in,
syncer::ModelType model_type) {
*was_called = true;
*model_type_passed_in = model_type;
}
protected:
base::FilePath good0_path() {
return data_dir_.AppendASCII("good").AppendASCII("Extensions")
.AppendASCII(good0).AppendASCII("1.0.0.0");
}
base::FilePath good1_path() {
return data_dir_.AppendASCII("good").AppendASCII("Extensions")
.AppendASCII(good1).AppendASCII("2");
}
base::FilePath good2_path() {
return data_dir_.AppendASCII("good").AppendASCII("Extensions")
.AppendASCII(good2).AppendASCII("1.0");
}
void TestExternalProvider(MockExtensionProvider* provider,
Manifest::Location location);
void PackCRX(const base::FilePath& dir_path,
const base::FilePath& pem_path,
const base::FilePath& crx_path) {
base::FilePath pem_output_path;
if (pem_path.value().empty()) {
pem_output_path = crx_path.DirName().AppendASCII("temp.pem");
} else {
ASSERT_TRUE(base::PathExists(pem_path));
}
ASSERT_TRUE(base::DeleteFile(crx_path, false));
scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
ASSERT_TRUE(creator->Run(dir_path,
crx_path,
pem_path,
pem_output_path,
ExtensionCreator::kOverwriteCRX));
ASSERT_TRUE(base::PathExists(crx_path));
}
enum InstallState {
INSTALL_FAILED,
INSTALL_UPDATED,
INSTALL_NEW,
INSTALL_WITHOUT_LOAD,
};
const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
const base::FilePath& pem_path,
InstallState install_state,
int creation_flags) {
base::FilePath crx_path;
base::ScopedTempDir temp_dir;
EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
crx_path = temp_dir.path().AppendASCII("temp.crx");
PackCRX(dir_path, pem_path, crx_path);
return InstallCRX(crx_path, install_state, creation_flags);
}
const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
const base::FilePath& pem_path,
InstallState install_state) {
return PackAndInstallCRX(dir_path, pem_path, install_state,
Extension::NO_FLAGS);
}
const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
InstallState install_state) {
return PackAndInstallCRX(dir_path, base::FilePath(), install_state,
Extension::NO_FLAGS);
}
const Extension* InstallCRX(const base::FilePath& path,
InstallState install_state,
int creation_flags,
const std::string& expected_old_name) {
InstallCRXInternal(path, creation_flags);
return VerifyCrxInstall(path, install_state, expected_old_name);
}
const Extension* InstallCRX(const base::FilePath& path,
InstallState install_state,
int creation_flags) {
return InstallCRX(path, install_state, creation_flags, std::string());
}
const Extension* InstallCRX(const base::FilePath& path,
InstallState install_state) {
return InstallCRX(path, install_state, Extension::NO_FLAGS);
}
const Extension* InstallCRXFromWebStore(const base::FilePath& path,
InstallState install_state) {
InstallCRXInternal(path, Extension::FROM_WEBSTORE);
return VerifyCrxInstall(path, install_state);
}
const Extension* InstallCRXWithLocation(const base::FilePath& crx_path,
Manifest::Location install_location,
InstallState install_state) {
EXPECT_TRUE(base::PathExists(crx_path))
<< "Path does not exist: "<< crx_path.value().c_str();
scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service_));
installer->set_install_source(install_location);
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
installer->InstallCrx(crx_path);
observer.Wait();
return VerifyCrxInstall(crx_path, install_state);
}
const Extension* VerifyCrxInstall(const base::FilePath& path,
InstallState install_state) {
return VerifyCrxInstall(path, install_state, std::string());
}
const Extension* VerifyCrxInstall(const base::FilePath& path,
InstallState install_state,
const std::string& expected_old_name) {
std::vector<base::string16> errors = GetErrors();
const Extension* extension = NULL;
if (install_state != INSTALL_FAILED) {
if (install_state == INSTALL_NEW)
++expected_extensions_count_;
EXPECT_TRUE(installed_) << path.value();
EXPECT_EQ(install_state == INSTALL_UPDATED, was_update_)
<< path.value();
if (install_state == INSTALL_UPDATED && !expected_old_name.empty())
EXPECT_EQ(expected_old_name, old_name_);
EXPECT_EQ(0u, errors.size()) << path.value();
if (install_state == INSTALL_WITHOUT_LOAD) {
EXPECT_EQ(0u, loaded_.size()) << path.value();
} else {
EXPECT_EQ(1u, loaded_.size()) << path.value();
size_t actual_extension_count = registry_->enabled_extensions().size() +
registry_->disabled_extensions().size();
EXPECT_EQ(expected_extensions_count_, actual_extension_count) <<
path.value();
extension = loaded_[0].get();
EXPECT_TRUE(service_->GetExtensionById(extension->id(), false))
<< path.value();
}
for (std::vector<base::string16>::iterator err = errors.begin();
err != errors.end(); ++err) {
LOG(ERROR) << *err;
}
} else {
EXPECT_FALSE(installed_) << path.value();
EXPECT_EQ(0u, loaded_.size()) << path.value();
EXPECT_EQ(1u, errors.size()) << path.value();
}
installed_ = NULL;
was_update_ = false;
old_name_ = "";
loaded_.clear();
ExtensionErrorReporter::GetInstance()->ClearErrors();
return extension;
}
enum UpdateState {
FAILED_SILENTLY,
FAILED,
UPDATED,
INSTALLED,
ENABLED
};
void BlackListWebGL() {
static const std::string json_blacklist =
"{\n"
" \"name\": \"gpu blacklist\",\n"
" \"version\": \"1.0\",\n"
" \"entries\": [\n"
" {\n"
" \"id\": 1,\n"
" \"features\": [\"webgl\"]\n"
" }\n"
" ]\n"
"}";
gpu::GPUInfo gpu_info;
content::GpuDataManager::GetInstance()->InitializeForTesting(
json_blacklist, gpu_info);
}
static bool IsCrxInstallerDone(extensions::CrxInstaller** installer,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
return content::Source<extensions::CrxInstaller>(source).ptr() ==
*installer;
}
void UpdateExtension(const std::string& id,
const base::FilePath& in_path,
UpdateState expected_state) {
ASSERT_TRUE(base::PathExists(in_path));
base::FilePath path = temp_dir_.path();
path = path.Append(in_path.BaseName());
ASSERT_TRUE(base::CopyFile(in_path, path));
int previous_enabled_extension_count =
registry_->enabled_extensions().size();
int previous_installed_extension_count =
previous_enabled_extension_count +
registry_->disabled_extensions().size();
extensions::CrxInstaller* installer = NULL;
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
base::Bind(&IsCrxInstallerDone, &installer));
service_->UpdateExtension(id, path, true, GURL(), &installer);
if (installer)
observer.Wait();
else
base::RunLoop().RunUntilIdle();
std::vector<base::string16> errors = GetErrors();
int error_count = errors.size();
int enabled_extension_count = registry_->enabled_extensions().size();
int installed_extension_count =
enabled_extension_count + registry_->disabled_extensions().size();
int expected_error_count = (expected_state == FAILED) ? 1 : 0;
EXPECT_EQ(expected_error_count, error_count) << path.value();
if (expected_state <= FAILED) {
EXPECT_EQ(previous_enabled_extension_count,
enabled_extension_count);
EXPECT_EQ(previous_installed_extension_count,
installed_extension_count);
} else {
int expected_installed_extension_count =
(expected_state >= INSTALLED) ? 1 : 0;
int expected_enabled_extension_count =
(expected_state >= ENABLED) ? 1 : 0;
EXPECT_EQ(expected_installed_extension_count,
installed_extension_count);
EXPECT_EQ(expected_enabled_extension_count,
enabled_extension_count);
}
EXPECT_FALSE(base::PathExists(path));
}
void TerminateExtension(const std::string& id) {
const Extension* extension = service_->GetInstalledExtension(id);
if (!extension) {
ADD_FAILURE();
return;
}
service_->TrackTerminatedExtensionForTest(extension);
}
size_t GetPrefKeyCount() {
const base::DictionaryValue* dict =
profile_->GetPrefs()->GetDictionary("extensions.settings");
if (!dict) {
ADD_FAILURE();
return 0;
}
return dict->size();
}
void UninstallExtension(const std::string& id, bool use_helper) {
base::FilePath extension_path = extensions_install_dir_.AppendASCII(id);
EXPECT_TRUE(base::PathExists(extension_path));
size_t pref_key_count = GetPrefKeyCount();
EXPECT_GT(pref_key_count, 0u);
ValidateIntegerPref(id, "state", Extension::ENABLED);
if (use_helper) {
EXPECT_TRUE(ExtensionService::UninstallExtensionHelper(service_, id));
} else {
EXPECT_TRUE(service_->UninstallExtension(id, false, NULL));
}
--expected_extensions_count_;
EXPECT_FALSE(unloaded_id_.empty());
EXPECT_EQ(id, unloaded_id_);
size_t new_pref_key_count = GetPrefKeyCount();
if (new_pref_key_count == pref_key_count) {
ValidateIntegerPref(id, "location",
Extension::EXTERNAL_EXTENSION_UNINSTALLED);
} else {
EXPECT_EQ(new_pref_key_count, pref_key_count - 1);
}
EXPECT_FALSE(service_->GetInstalledExtension(id));
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(base::PathExists(extension_path));
}
void ValidatePrefKeyCount(size_t count) {
EXPECT_EQ(count, GetPrefKeyCount());
}
testing::AssertionResult ValidateBooleanPref(
const std::string& extension_id,
const std::string& pref_path,
bool expected_val) {
std::string msg = "while checking: ";
msg += extension_id;
msg += " ";
msg += pref_path;
msg += " == ";
msg += expected_val ? "true" : "false";
PrefService* prefs = profile_->GetPrefs();
const base::DictionaryValue* dict =
prefs->GetDictionary("extensions.settings");
if (!dict) {
return testing::AssertionFailure()
<< "extension.settings does not exist " << msg;
}
const base::DictionaryValue* pref = NULL;
if (!dict->GetDictionary(extension_id, &pref)) {
return testing::AssertionFailure()
<< "extension pref does not exist " << msg;
}
bool val;
if (!pref->GetBoolean(pref_path, &val)) {
return testing::AssertionFailure()
<< pref_path << " pref not found " << msg;
}
return expected_val == val
? testing::AssertionSuccess()
: testing::AssertionFailure() << "base::Value is incorrect " << msg;
}
bool IsPrefExist(const std::string& extension_id,
const std::string& pref_path) {
const base::DictionaryValue* dict =
profile_->GetPrefs()->GetDictionary("extensions.settings");
if (dict == NULL) return false;
const base::DictionaryValue* pref = NULL;
if (!dict->GetDictionary(extension_id, &pref)) {
return false;
}
if (pref == NULL) {
return false;
}
bool val;
if (!pref->GetBoolean(pref_path, &val)) {
return false;
}
return true;
}
void ValidateIntegerPref(const std::string& extension_id,
const std::string& pref_path,
int expected_val) {
std::string msg = " while checking: ";
msg += extension_id;
msg += " ";
msg += pref_path;
msg += " == ";
msg += base::IntToString(expected_val);
PrefService* prefs = profile_->GetPrefs();
const base::DictionaryValue* dict =
prefs->GetDictionary("extensions.settings");
ASSERT_TRUE(dict != NULL) << msg;
const base::DictionaryValue* pref = NULL;
ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
EXPECT_TRUE(pref != NULL) << msg;
int val;
ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg;
EXPECT_EQ(expected_val, val) << msg;
}
void ValidateStringPref(const std::string& extension_id,
const std::string& pref_path,
const std::string& expected_val) {
std::string msg = " while checking: ";
msg += extension_id;
msg += ".manifest.";
msg += pref_path;
msg += " == ";
msg += expected_val;
const base::DictionaryValue* dict =
profile_->GetPrefs()->GetDictionary("extensions.settings");
ASSERT_TRUE(dict != NULL) << msg;
const base::DictionaryValue* pref = NULL;
std::string manifest_path = extension_id + ".manifest";
ASSERT_TRUE(dict->GetDictionary(manifest_path, &pref)) << msg;
EXPECT_TRUE(pref != NULL) << msg;
std::string val;
ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg;
EXPECT_EQ(expected_val, val) << msg;
}
void SetPref(const std::string& extension_id,
const std::string& pref_path,
base::Value* value,
const std::string& msg) {
DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
base::DictionaryValue* dict = update.Get();
ASSERT_TRUE(dict != NULL) << msg;
base::DictionaryValue* pref = NULL;
ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
EXPECT_TRUE(pref != NULL) << msg;
pref->Set(pref_path, value);
}
void SetPrefInteg(const std::string& extension_id,
const std::string& pref_path,
int value) {
std::string msg = " while setting: ";
msg += extension_id;
msg += " ";
msg += pref_path;
msg += " = ";
msg += base::IntToString(value);
SetPref(extension_id, pref_path, new base::FundamentalValue(value), msg);
}
void SetPrefBool(const std::string& extension_id,
const std::string& pref_path,
bool value) {
std::string msg = " while setting: ";
msg += extension_id + " " + pref_path;
msg += " = ";
msg += (value ? "true" : "false");
SetPref(extension_id, pref_path, new base::FundamentalValue(value), msg);
}
void ClearPref(const std::string& extension_id,
const std::string& pref_path) {
std::string msg = " while clearing: ";
msg += extension_id + " " + pref_path;
DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
base::DictionaryValue* dict = update.Get();
ASSERT_TRUE(dict != NULL) << msg;
base::DictionaryValue* pref = NULL;
ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
EXPECT_TRUE(pref != NULL) << msg;
pref->Remove(pref_path, NULL);
}
void SetPrefStringSet(const std::string& extension_id,
const std::string& pref_path,
const std::set<std::string>& value) {
std::string msg = " while setting: ";
msg += extension_id + " " + pref_path;
base::ListValue* list_value = new base::ListValue();
for (std::set<std::string>::const_iterator iter = value.begin();
iter != value.end(); ++iter)
list_value->Append(new base::StringValue(*iter));
SetPref(extension_id, pref_path, list_value, msg);
}
void InitPluginService() {
#if defined(ENABLE_PLUGINS)
PluginService::GetInstance()->Init();
#endif
}
protected:
extensions::ExtensionList loaded_;
std::string unloaded_id_;
const Extension* installed_;
bool was_update_;
std::string old_name_;
FeatureSwitch::ScopedOverride override_external_install_prompt_;
private:
void InstallCRXInternal(const base::FilePath& crx_path) {
InstallCRXInternal(crx_path, Extension::NO_FLAGS);
}
void InstallCRXInternal(const base::FilePath& crx_path, int creation_flags) {
ASSERT_TRUE(base::PathExists(crx_path))
<< "Path does not exist: "<< crx_path.value().c_str();
scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service_));
installer->set_creation_flags(creation_flags);
if (!(creation_flags & Extension::WAS_INSTALLED_BY_DEFAULT))
installer->set_allow_silent_install(true);
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::Source<extensions::CrxInstaller>(installer));
installer->InstallCrx(crx_path);
observer.Wait();
}
content::NotificationRegistrar registrar_;
};
class PackExtensionTestClient : public extensions::PackExtensionJob::Client {
public:
PackExtensionTestClient(const base::FilePath& expected_crx_path,
const base::FilePath& expected_private_key_path);
virtual void OnPackSuccess(const base::FilePath& crx_path,
const base::FilePath& private_key_path) OVERRIDE;
virtual void OnPackFailure(const std::string& error_message,
ExtensionCreator::ErrorType type) OVERRIDE;
private:
const base::FilePath expected_crx_path_;
const base::FilePath expected_private_key_path_;
DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient);
};
PackExtensionTestClient::PackExtensionTestClient(
const base::FilePath& expected_crx_path,
const base::FilePath& expected_private_key_path)
: expected_crx_path_(expected_crx_path),
expected_private_key_path_(expected_private_key_path) {}
void PackExtensionTestClient::OnPackSuccess(
const base::FilePath& crx_path,
const base::FilePath& private_key_path) {
base::MessageLoop::current()->Quit();
EXPECT_EQ(expected_crx_path_.value(), crx_path.value());
EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value());
ASSERT_TRUE(base::PathExists(private_key_path));
}
void PackExtensionTestClient::OnPackFailure(const std::string& error_message,
ExtensionCreator::ErrorType type) {
if (type == ExtensionCreator::kCRXExists)
FAIL() << "Packing should not fail.";
else
FAIL() << "Existing CRX should have been overwritten.";
}
TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
InitPluginService();
InitializeGoodInstalledExtensionService();
service_->Init();
uint32 expected_num_extensions = 3u;
ASSERT_EQ(expected_num_extensions, loaded_.size());
EXPECT_EQ(std::string(good0), loaded_[0]->id());
EXPECT_EQ(std::string("My extension 1"),
loaded_[0]->name());
EXPECT_EQ(std::string("The first extension that I made."),
loaded_[0]->description());
EXPECT_EQ(Manifest::INTERNAL, loaded_[0]->location());
EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false));
EXPECT_EQ(expected_num_extensions, registry_->enabled_extensions().size());
ValidatePrefKeyCount(3);
ValidateIntegerPref(good0, "state", Extension::ENABLED);
ValidateIntegerPref(good0, "location", Manifest::INTERNAL);
ValidateIntegerPref(good1, "state", Extension::ENABLED);
ValidateIntegerPref(good1, "location", Manifest::INTERNAL);
ValidateIntegerPref(good2, "state", Extension::ENABLED);
ValidateIntegerPref(good2, "location", Manifest::INTERNAL);
URLPatternSet expected_patterns;
AddPattern(&expected_patterns, "file:///*");
AddPattern(&expected_patterns, "http://*.google.com/*");
AddPattern(&expected_patterns, "https://*.google.com/*");
const Extension* extension = loaded_[0].get();
const extensions::UserScriptList& scripts =
extensions::ContentScriptsInfo::GetContentScripts(extension);
ASSERT_EQ(2u, scripts.size());
EXPECT_EQ(expected_patterns, scripts[0].url_patterns());
EXPECT_EQ(2u, scripts[0].js_scripts().size());
ExtensionResource resource00(extension->id(),
scripts[0].js_scripts()[0].extension_root(),
scripts[0].js_scripts()[0].relative_path());
base::FilePath expected_path =
base::MakeAbsoluteFilePath(extension->path().AppendASCII("script1.js"));
EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path));
ExtensionResource resource01(extension->id(),
scripts[0].js_scripts()[1].extension_root(),
scripts[0].js_scripts()[1].relative_path());
expected_path =
base::MakeAbsoluteFilePath(extension->path().AppendASCII("script2.js"));
EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path));
EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(extension));
EXPECT_EQ(1u, scripts[1].url_patterns().patterns().size());
EXPECT_EQ("http://*.news.com/*",
scripts[1].url_patterns().begin()->GetAsString());
ExtensionResource resource10(extension->id(),
scripts[1].js_scripts()[0].extension_root(),
scripts[1].js_scripts()[0].relative_path());
expected_path =
extension->path().AppendASCII("js_files").AppendASCII("script3.js");
expected_path = base::MakeAbsoluteFilePath(expected_path);
EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path));
expected_patterns.ClearPatterns();
AddPattern(&expected_patterns, "http://*.google.com/*");
AddPattern(&expected_patterns, "https://*.google.com/*");
EXPECT_EQ(expected_patterns,
extension->GetActivePermissions()->explicit_hosts());
EXPECT_EQ(std::string(good1), loaded_[1]->id());
EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name());
EXPECT_EQ(std::string(), loaded_[1]->description());
EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
extensions::BackgroundInfo::GetBackgroundURL(loaded_[1].get()));
EXPECT_EQ(0u,
extensions::ContentScriptsInfo::GetContentScripts(loaded_[1].get())
.size());
#if defined(OS_CHROMEOS)
EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(loaded_[1].get()));
#else
ASSERT_TRUE(extensions::PluginInfo::HasPlugins(loaded_[1].get()));
const std::vector<extensions::PluginInfo>* plugins =
extensions::PluginInfo::GetPlugins(loaded_[1].get());
ASSERT_TRUE(plugins);
ASSERT_EQ(2u, plugins->size());
EXPECT_EQ(loaded_[1]->path().AppendASCII("content_plugin.dll").value(),
plugins->at(0).path.value());
EXPECT_TRUE(plugins->at(0).is_public);
EXPECT_EQ(loaded_[1]->path().AppendASCII("extension_plugin.dll").value(),
plugins->at(1).path.value());
EXPECT_FALSE(plugins->at(1).is_public);
#endif
EXPECT_EQ(Manifest::INTERNAL, loaded_[1]->location());
int index = expected_num_extensions - 1;
EXPECT_EQ(std::string(good2), loaded_[index]->id());
EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name());
EXPECT_EQ(std::string(), loaded_[index]->description());
EXPECT_EQ(0u,
extensions::ContentScriptsInfo::GetContentScripts(
loaded_[index].get()).size());
EXPECT_EQ(Manifest::INTERNAL, loaded_[index]->location());
};
TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) {
base::FilePath source_install_dir = data_dir_
.AppendASCII("bad")
.AppendASCII("Extensions");
base::FilePath pref_path =
source_install_dir.DirName().Append(chrome::kPreferencesFilename);
InitializeInstalledExtensionService(pref_path, source_install_dir);
service_->Init();
ASSERT_EQ(4u, GetErrors().size());
ASSERT_EQ(0u, loaded_.size());
EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[0]),
std::string("Could not load extension from '*'. ") +
extensions::manifest_errors::kManifestUnreadable)) <<
base::UTF16ToUTF8(GetErrors()[0]);
EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[1]),
std::string("Could not load extension from '*'. ") +
extensions::manifest_errors::kManifestUnreadable)) <<
base::UTF16ToUTF8(GetErrors()[1]);
EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[2]),
std::string("Could not load extension from '*'. ") +
extensions::manifest_errors::kMissingFile)) <<
base::UTF16ToUTF8(GetErrors()[2]);
EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[3]),
std::string("Could not load extension from '*'. ") +
extensions::manifest_errors::kManifestUnreadable)) <<
base::UTF16ToUTF8(GetErrors()[3]);
};
TEST_F(ExtensionServiceTest, PendingImports) {
InitPluginService();
base::FilePath source_install_dir = data_dir_
.AppendASCII("pending_updates_with_imports")
.AppendASCII("Extensions");
base::FilePath pref_path =
source_install_dir.DirName().Append(chrome::kPreferencesFilename);
InitializeInstalledExtensionService(pref_path, source_install_dir);
EXPECT_FALSE(service_->pending_extension_manager()->HasPendingExtensions());
service_->Init();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
"bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
"hpiknbiabeeppbpihjehijgoemciehgk/2")));
ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_.get());
EXPECT_FALSE(
prefs->GetDelayedInstallInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
EXPECT_FALSE(
prefs->GetInstalledExtensionInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
EXPECT_FALSE(
prefs->GetDelayedInstallInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
EXPECT_FALSE(
prefs->GetInstalledExtensionInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
EXPECT_FALSE(
prefs->GetDelayedInstallInfo("cccccccccccccccccccccccccccccccc"));
EXPECT_FALSE(
prefs->GetInstalledExtensionInfo("cccccccccccccccccccccccccccccccc"));
EXPECT_TRUE(
prefs->GetDelayedInstallInfo("behllobkkfkfnphdnhnkndlbkcpglgmj"));
EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
prefs->GetDelayedInstallReason("behllobkkfkfnphdnhnkndlbkcpglgmj"));
EXPECT_FALSE(base::PathExists(extensions_install_dir_.AppendASCII(
"behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0")));
EXPECT_TRUE(service_->pending_extension_manager()->HasPendingExtensions());
std::string pending_id("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(pending_id));
EXPECT_TRUE(service_->pending_extension_manager()->Remove(pending_id));
}
TEST_F(ExtensionServiceTest, InstallExtension) {
InitializeEmptyExtensionService();
set_extensions_enabled(false);
base::FilePath path = data_dir_.AppendASCII("good.crx");
InstallCRX(path, INSTALL_FAILED);
set_extensions_enabled(true);
ValidatePrefKeyCount(0);
path = data_dir_.AppendASCII("good.crx");
InstallCRX(path, INSTALL_NEW);
int pref_count = 0;
ValidatePrefKeyCount(++pref_count);
ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
path = data_dir_.AppendASCII("page_action.crx");
InstallCRX(path, INSTALL_NEW);
ValidatePrefKeyCount(++pref_count);
ValidateIntegerPref(page_action, "state", Extension::ENABLED);
ValidateIntegerPref(page_action, "location", Manifest::INTERNAL);
path = data_dir_.AppendASCII("bad_signature.crx");
InstallCRX(path, INSTALL_FAILED);
ValidatePrefKeyCount(pref_count);
path = data_dir_.AppendASCII("not_an_extension.crx");
InstallCRX(path, INSTALL_FAILED);
ValidatePrefKeyCount(pref_count);
path = data_dir_.AppendASCII("bad_magic.crx");
InstallCRX(path, INSTALL_FAILED);
ValidatePrefKeyCount(pref_count);
path = data_dir_.AppendASCII("bad_underscore.crx");
InstallCRX(path, INSTALL_NEW);
ValidatePrefKeyCount(++pref_count);
path = data_dir_.AppendASCII("good2048.crx");
InstallCRX(path, INSTALL_NEW);
ValidatePrefKeyCount(++pref_count);
ValidateIntegerPref(good2048, "state", Extension::ENABLED);
ValidateIntegerPref(good2048, "location", Manifest::INTERNAL);
}
struct MockInstallObserver : public extensions::InstallObserver {
MockInstallObserver() {
}
virtual ~MockInstallObserver() {
}
virtual void OnExtensionInstalled(const Extension* extension) OVERRIDE {
last_extension_installed = extension->id();
}
virtual void OnExtensionUninstalled(const Extension* extension) OVERRIDE {
last_extension_uninstalled = extension->id();
}
std::string last_extension_installed;
std::string last_extension_uninstalled;
};
TEST_F(ExtensionServiceTest, InstallObserverNotified) {
InitializeEmptyExtensionService();
extensions::InstallTracker* tracker(
extensions::InstallTrackerFactory::GetForProfile(profile_.get()));
MockInstallObserver observer;
tracker->AddObserver(&observer);
ASSERT_TRUE(observer.last_extension_installed.empty());
base::FilePath path = data_dir_.AppendASCII("good.crx");
InstallCRX(path, INSTALL_NEW);
ASSERT_EQ(good_crx, observer.last_extension_installed);
ASSERT_TRUE(observer.last_extension_uninstalled.empty());
UninstallExtension(good_crx, false);
ASSERT_EQ(good_crx, observer.last_extension_uninstalled);
tracker->RemoveObserver(&observer);
}
TEST_F(ExtensionServiceTest, InstallingExternalExtensionWithFlags) {
const char kPrefFromBookmark[] = "from_bookmark";
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
set_extensions_enabled(true);
Version version("1.0.0.0");
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
if (service_->OnExternalExtensionFileFound(
good_crx,
&version,
path,
Manifest::EXTERNAL_PREF,
Extension::FROM_BOOKMARK,
false )) {
observer.Wait();
}
const Extension* extension = service_->GetExtensionById(good_crx, false);
ASSERT_TRUE(extension);
ASSERT_TRUE(extension->from_bookmark());
ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
path = data_dir_.AppendASCII("good2.crx");
UpdateExtension(good_crx, path, ENABLED);
ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
extension = service_->GetExtensionById(good_crx, false);
ASSERT_TRUE(extension);
ASSERT_TRUE(extension->from_bookmark());
}
TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
set_extensions_enabled(true);
Version version("1.0.0.0");
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
if (service_->OnExternalExtensionFileFound(good_crx, &version,
path, Manifest::EXTERNAL_PREF,
Extension::NO_FLAGS, false)) {
observer.Wait();
}
ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
UninstallExtension(good_crx, false);
ValidateIntegerPref(good_crx, "location",
Extension::EXTERNAL_EXTENSION_UNINSTALLED);
service_->OnExternalExtensionFileFound(good_crx, &version,
path, Manifest::EXTERNAL_PREF,
Extension::NO_FLAGS, false);
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false));
ValidateIntegerPref(good_crx, "location",
Extension::EXTERNAL_EXTENSION_UNINSTALLED);
version = Version("1.0.0.1");
path = data_dir_.AppendASCII("good2.crx");
service_->OnExternalExtensionFileFound(good_crx, &version,
path, Manifest::EXTERNAL_PREF,
Extension::NO_FLAGS, false);
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false));
ValidateIntegerPref(good_crx, "location",
Extension::EXTERNAL_EXTENSION_UNINSTALLED);
ASSERT_FALSE(service_->pending_extension_manager()->AddFromExternalUpdateUrl(
good_crx,
std::string(),
GURL("http:://fake.update/url"),
Manifest::EXTERNAL_PREF_DOWNLOAD,
Extension::NO_FLAGS,
false));
ASSERT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
}
TEST_F(ExtensionServiceTest, UninstallingNotLoadedExtension) {
base::FilePath source_install_dir = data_dir_
.AppendASCII("good")
.AppendASCII("Extensions");
base::FilePath pref_path = source_install_dir
.DirName()
.AppendASCII("PreferencesExperimental");
InitializeInstalledExtensionService(pref_path, source_install_dir);
service_->Init();
MockExtensionProvider provider(NULL, Manifest::EXTERNAL_REGISTRY);
service_->OnExternalProviderReady(&provider);
}
TEST_F(ExtensionServiceTest, FailOnWrongId) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
set_extensions_enabled(true);
Version version("1.0.0.0");
const std::string wrong_id = all_zero;
const std::string correct_id = good_crx;
ASSERT_NE(correct_id, wrong_id);
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
service_->OnExternalExtensionFileFound(
wrong_id, &version, path, Manifest::EXTERNAL_PREF,
Extension::NO_FLAGS, false);
observer.Wait();
ASSERT_FALSE(service_->GetExtensionById(good_crx, false));
content::WindowedNotificationObserver observer2(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
if (service_->OnExternalExtensionFileFound(
correct_id, &version, path, Manifest::EXTERNAL_PREF,
Extension::NO_FLAGS, false)) {
observer2.Wait();
}
ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
}
TEST_F(ExtensionServiceTest, FailOnWrongVersion) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
set_extensions_enabled(true);
Version wrong_version("1.2.3.4");
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
service_->OnExternalExtensionFileFound(
good_crx, &wrong_version, path, Manifest::EXTERNAL_PREF,
Extension::NO_FLAGS, false);
observer.Wait();
ASSERT_FALSE(service_->GetExtensionById(good_crx, false));
service_->pending_extension_manager()->Remove(good_crx);
Version correct_version("1.0.0.0");
content::WindowedNotificationObserver observer2(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
if (service_->OnExternalExtensionFileFound(
good_crx, &correct_version, path, Manifest::EXTERNAL_PREF,
Extension::NO_FLAGS, false)) {
observer2.Wait();
}
ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
}
TEST_F(ExtensionServiceTest, InstallUserScript) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_
.AppendASCII("user_script_basic.user.js");
ASSERT_TRUE(base::PathExists(path));
scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service_));
installer->set_allow_silent_install(true);
installer->InstallUserScript(
path,
GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js"));
base::RunLoop().RunUntilIdle();
std::vector<base::string16> errors = GetErrors();
EXPECT_TRUE(installed_) << "Nothing was installed.";
EXPECT_FALSE(was_update_) << path.value();
ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded.";
EXPECT_EQ(0u, errors.size()) << "There were errors: "
<< JoinString(errors, ',');
EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false)) <<
path.value();
installed_ = NULL;
was_update_ = false;
loaded_.clear();
ExtensionErrorReporter::GetInstance()->ClearErrors();
}
TEST_F(ExtensionServiceTest, InstallExtensionDuringShutdown) {
InitializeEmptyExtensionService();
service_->set_browser_terminating_for_test(true);
base::FilePath path = data_dir_.AppendASCII("good.crx");
scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service_));
installer->set_allow_silent_install(true);
installer->InstallCrx(path);
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(installed_) << "Extension installed during shutdown.";
ASSERT_EQ(0u, loaded_.size()) << "Extension loaded during shutdown.";
}
TEST_F(ExtensionServiceTest, GrantedPermissions) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_
.AppendASCII("permissions");
base::FilePath pem_path = path.AppendASCII("unknown.pem");
path = path.AppendASCII("unknown");
ASSERT_TRUE(base::PathExists(pem_path));
ASSERT_TRUE(base::PathExists(path));
ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_.get());
APIPermissionSet expected_api_perms;
URLPatternSet expected_host_perms;
scoped_refptr<PermissionSet> known_perms(
prefs->GetGrantedPermissions(permissions_crx));
EXPECT_FALSE(known_perms.get());
const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
EXPECT_EQ(0u, GetErrors().size());
ASSERT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_EQ(permissions_crx, extension->id());
expected_api_perms.insert(APIPermission::kTab);
AddPattern(&expected_host_perms, "http://*.google.com/*");
AddPattern(&expected_host_perms, "https://*.google.com/*");
AddPattern(&expected_host_perms, "http://*.google.com.hk/*");
AddPattern(&expected_host_perms, "http://www.example.com/*");
known_perms = prefs->GetGrantedPermissions(extension->id());
EXPECT_TRUE(known_perms.get());
EXPECT_FALSE(known_perms->IsEmpty());
EXPECT_EQ(expected_api_perms, known_perms->apis());
EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
EXPECT_EQ(expected_host_perms, known_perms->effective_hosts());
}
#if !defined(OS_CHROMEOS)
TEST_F(ExtensionServiceTest, DefaultAppsGrantedPermissions) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_
.AppendASCII("permissions");
base::FilePath pem_path = path.AppendASCII("unknown.pem");
path = path.AppendASCII("unknown");
ASSERT_TRUE(base::PathExists(pem_path));
ASSERT_TRUE(base::PathExists(path));
ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_.get());
APIPermissionSet expected_api_perms;
URLPatternSet expected_host_perms;
scoped_refptr<PermissionSet> known_perms(
prefs->GetGrantedPermissions(permissions_crx));
EXPECT_FALSE(known_perms.get());
const Extension* extension = PackAndInstallCRX(
path, pem_path, INSTALL_NEW, Extension::WAS_INSTALLED_BY_DEFAULT);
EXPECT_EQ(0u, GetErrors().size());
ASSERT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_EQ(permissions_crx, extension->id());
expected_api_perms.insert(APIPermission::kTab);
known_perms = prefs->GetGrantedPermissions(extension->id());
EXPECT_TRUE(known_perms.get());
EXPECT_FALSE(known_perms->IsEmpty());
EXPECT_EQ(expected_api_perms, known_perms->apis());
EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
}
#endif
#if !defined(OS_CHROMEOS)
TEST_F(ExtensionServiceTest, GrantedFullAccessPermissions) {
InitPluginService();
InitializeEmptyExtensionService();
ASSERT_TRUE(base::PathExists(good1_path()));
const Extension* extension = PackAndInstallCRX(good1_path(), INSTALL_NEW);
EXPECT_EQ(0u, GetErrors().size());
EXPECT_EQ(1u, registry_->enabled_extensions().size());
ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_.get());
scoped_refptr<PermissionSet> permissions(
prefs->GetGrantedPermissions(extension->id()));
EXPECT_FALSE(permissions->IsEmpty());
EXPECT_TRUE(permissions->HasEffectiveFullAccess());
EXPECT_FALSE(permissions->apis().empty());
EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
}
#endif
TEST_F(ExtensionServiceTest, GrantedAPIAndHostPermissions) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_
.AppendASCII("permissions")
.AppendASCII("unknown");
ASSERT_TRUE(base::PathExists(path));
const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW);
EXPECT_EQ(0u, GetErrors().size());
EXPECT_EQ(1u, registry_->enabled_extensions().size());
std::string extension_id = extension->id();
ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_.get());
APIPermissionSet expected_api_permissions;
URLPatternSet expected_host_permissions;
expected_api_permissions.insert(APIPermission::kTab);
AddPattern(&expected_host_permissions, "http://*.google.com/*");
AddPattern(&expected_host_permissions, "https://*.google.com/*");
AddPattern(&expected_host_permissions, "http://*.google.com.hk/*");
AddPattern(&expected_host_permissions, "http://www.example.com/*");
std::set<std::string> host_permissions;
SetPref(extension_id, "granted_permissions.api",
new base::ListValue(), "granted_permissions.api");
service_->ReloadExtensionsForTest();
EXPECT_EQ(1u, registry_->disabled_extensions().size());
extension = registry_->disabled_extensions().begin()->get();
ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
ASSERT_FALSE(service_->IsExtensionEnabled(extension_id));
ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
service_->GrantPermissionsAndEnableExtension(extension);
ASSERT_FALSE(prefs->IsExtensionDisabled(extension_id));
ASSERT_TRUE(service_->IsExtensionEnabled(extension_id));
ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
scoped_refptr<PermissionSet> current_perms(
prefs->GetGrantedPermissions(extension_id));
ASSERT_TRUE(current_perms.get());
ASSERT_FALSE(current_perms->IsEmpty());
ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
ASSERT_EQ(expected_api_permissions, current_perms->apis());
ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
host_permissions.clear();
current_perms = NULL;
host_permissions.insert("http://*.google.com/*");
host_permissions.insert("https://*.google.com/*");
host_permissions.insert("http://*.google.com.hk/*");
base::ListValue* api_permissions = new base::ListValue();
api_permissions->Append(
new base::StringValue("tabs"));
SetPref(extension_id, "granted_permissions.api",
api_permissions, "granted_permissions.api");
SetPrefStringSet(
extension_id, "granted_permissions.scriptable_host", host_permissions);
service_->ReloadExtensionsForTest();
EXPECT_EQ(1u, registry_->disabled_extensions().size());
extension = registry_->disabled_extensions().begin()->get();
ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
ASSERT_FALSE(service_->IsExtensionEnabled(extension_id));
ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
service_->GrantPermissionsAndEnableExtension(extension);
ASSERT_TRUE(service_->IsExtensionEnabled(extension_id));
ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
current_perms = prefs->GetGrantedPermissions(extension_id);
ASSERT_TRUE(current_perms.get());
ASSERT_FALSE(current_perms->IsEmpty());
ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
ASSERT_EQ(expected_api_permissions, current_perms->apis());
ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
}
TEST_F(ExtensionServiceTest, PackExtension) {
InitializeEmptyExtensionService();
base::FilePath input_directory = data_dir_
.AppendASCII("good")
.AppendASCII("Extensions")
.AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
.AppendASCII("1.0.0.0");
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath output_directory = temp_dir.path();
base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
privkey_path, ExtensionCreator::kNoRunFlags));
ASSERT_TRUE(base::PathExists(crx_path));
ASSERT_TRUE(base::PathExists(privkey_path));
base::DeleteFile(privkey_path, false);
ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
privkey_path, ExtensionCreator::kNoRunFlags));
ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
privkey_path, ExtensionCreator::kOverwriteCRX));
ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
privkey_path, ExtensionCreator::kOverwriteCRX));
ASSERT_TRUE(base::PathExists(privkey_path));
InstallCRX(crx_path, INSTALL_NEW);
creator.reset(new ExtensionCreator());
ASSERT_FALSE(
creator->Run(base::FilePath(), base::FilePath(), base::FilePath(),
base::FilePath(), ExtensionCreator::kOverwriteCRX));
base::ScopedTempDir temp_dir2;
ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
creator.reset(new ExtensionCreator());
ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
base::FilePath(), ExtensionCreator::kOverwriteCRX));
std::string invalid_manifest_content = "I am not a manifest.";
ASSERT_TRUE(base::WriteFile(
temp_dir2.path().Append(extensions::kManifestFilename),
invalid_manifest_content.c_str(), invalid_manifest_content.size()));
creator.reset(new ExtensionCreator());
ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
base::FilePath(), ExtensionCreator::kOverwriteCRX));
base::FilePath bad_private_key_dir = data_dir_.AppendASCII("bad_private_key");
crx_path = output_directory.AppendASCII("bad_private_key.crx");
privkey_path = data_dir_.AppendASCII("bad_private_key.pem");
ASSERT_FALSE(creator->Run(bad_private_key_dir, crx_path, base::FilePath(),
privkey_path, ExtensionCreator::kOverwriteCRX));
}
TEST_F(ExtensionServiceTest, PackPunctuatedExtension) {
InitializeEmptyExtensionService();
base::FilePath input_directory = data_dir_
.AppendASCII("good")
.AppendASCII("Extensions")
.AppendASCII(good0)
.AppendASCII("1.0.0.0");
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
const base::FilePath punctuated_names[] = {
base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods")),
base::FilePath(FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod")),
base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")).
NormalizePathSeparators(),
};
const base::FilePath expected_crx_names[] = {
base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.crx")),
base::FilePath(
FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx")),
base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx")),
};
const base::FilePath expected_private_key_names[] = {
base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.pem")),
base::FilePath(
FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem")),
base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem")),
};
for (size_t i = 0; i < arraysize(punctuated_names); ++i) {
SCOPED_TRACE(punctuated_names[i].value().c_str());
base::FilePath output_dir = temp_dir.path().Append(punctuated_names[i]);
ASSERT_TRUE(base::CopyDirectory(input_directory, output_dir, true));
base::FilePath expected_crx_path =
temp_dir.path().Append(expected_crx_names[i]);
base::FilePath expected_private_key_path =
temp_dir.path().Append(expected_private_key_names[i]);
PackExtensionTestClient pack_client(expected_crx_path,
expected_private_key_path);
scoped_refptr<extensions::PackExtensionJob> packer(
new extensions::PackExtensionJob(&pack_client, output_dir,
base::FilePath(),
ExtensionCreator::kOverwriteCRX));
packer->Start();
base::MessageLoop::current()->Run();
if (HasFatalFailure())
return;
InstallCRX(expected_crx_path, INSTALL_NEW);
}
}
TEST_F(ExtensionServiceTest, PackExtensionContainingKeyFails) {
InitializeEmptyExtensionService();
base::ScopedTempDir extension_temp_dir;
ASSERT_TRUE(extension_temp_dir.CreateUniqueTempDir());
base::FilePath input_directory = extension_temp_dir.path().AppendASCII("ext");
ASSERT_TRUE(base::CopyDirectory(
data_dir_
.AppendASCII("good")
.AppendASCII("Extensions")
.AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
.AppendASCII("1.0.0.0"),
input_directory,
true));
base::ScopedTempDir output_temp_dir;
ASSERT_TRUE(output_temp_dir.CreateUniqueTempDir());
base::FilePath output_directory = output_temp_dir.path();
base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
privkey_path, ExtensionCreator::kNoRunFlags))
<< creator->error_message();
ASSERT_TRUE(base::PathExists(crx_path));
ASSERT_TRUE(base::PathExists(privkey_path));
base::DeleteFile(crx_path, false);
base::Move(privkey_path,
input_directory.AppendASCII("privkey.pem"));
EXPECT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
privkey_path, ExtensionCreator::kNoRunFlags));
EXPECT_THAT(creator->error_message(),
testing::ContainsRegex(
"extension includes the key file.*privkey.pem"));
}
TEST_F(ExtensionServiceTest, PackExtensionOpenSSLKey) {
InitializeEmptyExtensionService();
base::FilePath input_directory = data_dir_
.AppendASCII("good")
.AppendASCII("Extensions")
.AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
.AppendASCII("1.0.0.0");
base::FilePath privkey_path(data_dir_.AppendASCII(
"openssl_privkey_asn1.pem"));
ASSERT_TRUE(base::PathExists(privkey_path));
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath output_directory = temp_dir.path();
base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path,
base::FilePath(), ExtensionCreator::kOverwriteCRX));
InstallCRX(crx_path, INSTALL_NEW);
}
TEST_F(ExtensionServiceTest, InstallTheme) {
InitializeEmptyExtensionService();
service_->Init();
base::FilePath path = data_dir_.AppendASCII("theme.crx");
InstallCRX(path, INSTALL_NEW);
int pref_count = 0;
ValidatePrefKeyCount(++pref_count);
ValidateIntegerPref(theme_crx, "state", Extension::ENABLED);
ValidateIntegerPref(theme_crx, "location", Manifest::INTERNAL);
set_extensions_enabled(false);
path = data_dir_.AppendASCII("theme2.crx");
InstallCRX(path, INSTALL_NEW);
ValidatePrefKeyCount(++pref_count);
ValidateIntegerPref(theme2_crx, "state", Extension::ENABLED);
ValidateIntegerPref(theme2_crx, "location", Manifest::INTERNAL);
set_extensions_enabled(true);
{
path = data_dir_.AppendASCII("theme_with_extension.crx");
const Extension* extension = InstallCRX(path, INSTALL_NEW);
ValidatePrefKeyCount(++pref_count);
ASSERT_TRUE(extension);
EXPECT_TRUE(extension->is_theme());
EXPECT_EQ(
0u,
extensions::ContentScriptsInfo::GetContentScripts(extension).size());
}
path = data_dir_.AppendASCII("theme_missing_image.crx");
InstallCRX(path, INSTALL_FAILED);
ValidatePrefKeyCount(pref_count);
}
TEST_F(ExtensionServiceTest, LoadLocalizedTheme) {
InitializeEmptyExtensionService();
service_->Init();
base::FilePath extension_path = data_dir_
.AppendASCII("theme_i18n");
extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0u, GetErrors().size());
ASSERT_EQ(1u, loaded_.size());
EXPECT_EQ(1u, registry_->enabled_extensions().size());
const Extension* theme = registry_->enabled_extensions().begin()->get();
EXPECT_EQ("name", theme->name());
EXPECT_EQ("description", theme->description());
base::FilePath theme_file = extension_path.Append(chrome::kThemePackFilename);
ASSERT_TRUE(base::PathExists(theme_file));
ASSERT_TRUE(base::DeleteFile(theme_file, false));
}
TEST_F(ExtensionServiceTest, UnpackedExtensionCanChangeID) {
InitializeEmptyExtensionService();
base::ScopedTempDir temp;
ASSERT_TRUE(temp.CreateUniqueTempDir());
base::FilePath extension_path = temp.path();
base::FilePath manifest_path =
extension_path.Append(extensions::kManifestFilename);
base::FilePath manifest_no_key = data_dir_.
AppendASCII("unpacked").
AppendASCII("manifest_no_key.json");
base::FilePath manifest_with_key = data_dir_.
AppendASCII("unpacked").
AppendASCII("manifest_with_key.json");
ASSERT_TRUE(base::PathExists(manifest_no_key));
ASSERT_TRUE(base::PathExists(manifest_with_key));
base::CopyFile(manifest_no_key, manifest_path);
extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0u, GetErrors().size());
ASSERT_EQ(1u, loaded_.size());
EXPECT_EQ(1u, registry_->enabled_extensions().size());
base::CopyFile(manifest_with_key, manifest_path);
loaded_.clear();
service_->ReloadExtensionsForTest();
const Extension* extension = service_->GetExtensionById(unpacked, false);
EXPECT_EQ(unpacked, extension->id());
ASSERT_EQ(1u, loaded_.size());
}
#if defined(OS_POSIX)
TEST_F(ExtensionServiceTest, UnpackedExtensionMayContainSymlinkedFiles) {
base::FilePath source_data_dir = data_dir_.
AppendASCII("unpacked").
AppendASCII("symlinks_allowed");
base::FilePath source_manifest = source_data_dir.AppendASCII("manifest.json");
ASSERT_TRUE(base::PathExists(source_manifest));
base::FilePath source_icon = source_data_dir.AppendASCII("icon.png");
ASSERT_TRUE(base::PathExists(source_icon));
base::ScopedTempDir temp;
ASSERT_TRUE(temp.CreateUniqueTempDir());
base::FilePath extension_path = temp.path();
base::FilePath manifest = extension_path.Append(
extensions::kManifestFilename);
base::FilePath icon_symlink = extension_path.AppendASCII("icon.png");
base::CopyFile(source_manifest, manifest);
base::CreateSymbolicLink(source_icon, icon_symlink);
InitializeEmptyExtensionService();
extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(GetErrors().empty());
ASSERT_EQ(1u, loaded_.size());
EXPECT_EQ(1u, registry_->enabled_extensions().size());
}
#endif
TEST_F(ExtensionServiceTest, UnpackedExtensionMayNotHaveUnderscore) {
InitializeEmptyExtensionService();
base::FilePath extension_path = data_dir_
.AppendASCII("underscore_name");
extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, GetErrors().size());
EXPECT_EQ(0u, registry_->enabled_extensions().size());
}
TEST_F(ExtensionServiceTest, InstallLocalizedTheme) {
InitializeEmptyExtensionService();
service_->Init();
base::FilePath theme_path = data_dir_
.AppendASCII("theme_i18n");
const Extension* theme = PackAndInstallCRX(theme_path, INSTALL_NEW);
EXPECT_EQ(0u, GetErrors().size());
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_EQ("name", theme->name());
EXPECT_EQ("description", theme->description());
}
TEST_F(ExtensionServiceTest, InstallApps) {
InitializeEmptyExtensionService();
const Extension* app = PackAndInstallCRX(data_dir_.AppendASCII("app1"),
INSTALL_NEW);
int pref_count = 0;
ValidatePrefKeyCount(++pref_count);
ASSERT_EQ(1u, registry_->enabled_extensions().size());
ValidateIntegerPref(app->id(), "state", Extension::ENABLED);
ValidateIntegerPref(app->id(), "location", Manifest::INTERNAL);
PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
ValidatePrefKeyCount(++pref_count);
PackAndInstallCRX(data_dir_.AppendASCII("app3"), INSTALL_FAILED);
ValidatePrefKeyCount(pref_count);
}
TEST_F(ExtensionServiceTest, DefaultFileAccess) {
InitializeEmptyExtensionService();
const Extension* extension =
PackAndInstallCRX(data_dir_
.AppendASCII("permissions")
.AppendASCII("files"),
INSTALL_NEW);
EXPECT_EQ(0u, GetErrors().size());
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_FALSE(
ExtensionPrefs::Get(profile_.get())->AllowFileAccess(extension->id()));
}
TEST_F(ExtensionServiceTest, UpdateApps) {
InitializeEmptyExtensionService();
base::FilePath extensions_path = data_dir_.AppendASCII("app_update");
const Extension* extension =
InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
ASSERT_EQ(1u, registry_->enabled_extensions().size());
std::string id = extension->id();
ASSERT_EQ(std::string("1"), extension->version()->GetString());
UpdateExtension(id,
extensions_path.AppendASCII("v2.crx"),
ENABLED);
ASSERT_EQ(std::string("2"),
service_->GetExtensionById(id, false)->version()->GetString());
}
TEST_F(ExtensionServiceTest, UpdateAppsRetainOrdinals) {
InitializeEmptyExtensionService();
AppSorting* sorting = ExtensionPrefs::Get(profile_.get())->app_sorting();
base::FilePath extensions_path = data_dir_.AppendASCII("app_update");
const Extension* extension =
InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
ASSERT_EQ(1u, registry_->enabled_extensions().size());
std::string id = extension->id();
ASSERT_EQ(std::string("1"), extension->version()->GetString());
syncer::StringOrdinal new_page_ordinal =
sorting->GetPageOrdinal(id).CreateAfter();
syncer::StringOrdinal new_launch_ordinal =
sorting->GetAppLaunchOrdinal(id).CreateBefore();
sorting->SetPageOrdinal(id, new_page_ordinal);
sorting->SetAppLaunchOrdinal(id, new_launch_ordinal);
UpdateExtension(id, extensions_path.AppendASCII("v2.crx"), ENABLED);
ASSERT_EQ(std::string("2"),
service_->GetExtensionById(id, false)->version()->GetString());
ASSERT_TRUE(new_page_ordinal.Equals(sorting->GetPageOrdinal(id)));
ASSERT_TRUE(new_launch_ordinal.Equals(sorting->GetAppLaunchOrdinal(id)));
}
TEST_F(ExtensionServiceTest, EnsureCWSOrdinalsInitialized) {
InitializeEmptyExtensionService();
service_->component_loader()->Add(
IDR_WEBSTORE_MANIFEST, base::FilePath(FILE_PATH_LITERAL("web_store")));
service_->Init();
AppSorting* sorting = ExtensionPrefs::Get(profile_.get())->app_sorting();
EXPECT_TRUE(
sorting->GetPageOrdinal(extension_misc::kWebStoreAppId).IsValid());
EXPECT_TRUE(
sorting->GetAppLaunchOrdinal(extension_misc::kWebStoreAppId).IsValid());
}
TEST_F(ExtensionServiceTest, InstallAppsWithUnlimitedStorage) {
InitializeEmptyExtensionService();
EXPECT_TRUE(registry_->enabled_extensions().is_empty());
int pref_count = 0;
const Extension* extension =
PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
ValidatePrefKeyCount(++pref_count);
ASSERT_EQ(1u, registry_->enabled_extensions().size());
const std::string id1 = extension->id();
EXPECT_TRUE(extension->HasAPIPermission(
APIPermission::kUnlimitedStorage));
EXPECT_TRUE(extension->web_extent().MatchesURL(
extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
const GURL origin1(
extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
IsStorageUnlimited(origin1));
extension = PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
ValidatePrefKeyCount(++pref_count);
ASSERT_EQ(2u, registry_->enabled_extensions().size());
const std::string id2 = extension->id();
EXPECT_TRUE(extension->HasAPIPermission(
APIPermission::kUnlimitedStorage));
EXPECT_TRUE(extension->web_extent().MatchesURL(
extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
const GURL origin2(
extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
EXPECT_EQ(origin1, origin2);
EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
IsStorageUnlimited(origin2));
UninstallExtension(id1, false);
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
IsStorageUnlimited(origin1));
UninstallExtension(id2, false);
EXPECT_EQ(0u, registry_->enabled_extensions().size());
EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
IsStorageUnlimited(origin2));
}
TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
InitializeEmptyExtensionService();
EXPECT_TRUE(registry_->enabled_extensions().is_empty());
int pref_count = 0;
const Extension* extension =
PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
ValidatePrefKeyCount(++pref_count);
ASSERT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_TRUE(extension->is_app());
const std::string id1 = extension->id();
const GURL origin1(
extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
IsStorageProtected(origin1));
extension = PackAndInstallCRX(data_dir_.AppendASCII("app4"), INSTALL_NEW);
ValidatePrefKeyCount(++pref_count);
ASSERT_EQ(2u, registry_->enabled_extensions().size());
const std::string id2 = extension->id();
const GURL origin2(
extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
ASSERT_NE(origin1, origin2);
EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
IsStorageProtected(origin2));
UninstallExtension(id1, false);
EXPECT_EQ(1u, registry_->enabled_extensions().size());
UninstallExtension(id2, false);
EXPECT_TRUE(registry_->enabled_extensions().is_empty());
EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
IsStorageProtected(origin1));
EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
IsStorageProtected(origin2));
}
TEST_F(ExtensionServiceTest, Reinstall) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
InstallCRX(path, INSTALL_NEW);
ValidatePrefKeyCount(1);
ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
InstallCRX(path, INSTALL_UPDATED);
ValidatePrefKeyCount(1);
ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
}
TEST_F(ExtensionServiceTest, FromWebStore) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
const Extension* extension = InstallCRX(path, INSTALL_NEW);
std::string id = extension->id();
ValidatePrefKeyCount(1);
ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", false));
ASSERT_FALSE(extension->from_webstore());
InstallCRXFromWebStore(path, INSTALL_UPDATED);
ValidatePrefKeyCount(1);
ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
service_->ReloadExtensionsForTest();
extension = service_->GetExtensionById(id, false);
ASSERT_TRUE(extension->from_webstore());
path = data_dir_.AppendASCII("good2.crx");
UpdateExtension(good_crx, path, ENABLED);
ValidatePrefKeyCount(1);
ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
}
TEST_F(ExtensionServiceTest, UpgradeSignedGood) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
const Extension* extension = InstallCRX(path, INSTALL_NEW);
std::string id = extension->id();
ASSERT_EQ("1.0.0.0", extension->version()->GetString());
ASSERT_EQ(0u, GetErrors().size());
path = data_dir_.AppendASCII("good2.crx");
InstallCRX(path, INSTALL_UPDATED, Extension::NO_FLAGS, "My extension 1");
extension = service_->GetExtensionById(id, false);
ASSERT_EQ("1.0.0.1", extension->version()->GetString());
ASSERT_EQ("My updated extension 1", extension->name());
ASSERT_EQ(0u, GetErrors().size());
}
TEST_F(ExtensionServiceTest, UpgradeSignedBad) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
InstallCRX(path, INSTALL_NEW);
path = data_dir_.AppendASCII("bad_signature.crx");
InstallCRX(path, INSTALL_FAILED);
}
TEST_F(ExtensionServiceTest, UpdateExtension) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
const Extension* good = InstallCRX(path, INSTALL_NEW);
ASSERT_EQ("1.0.0.0", good->VersionString());
ASSERT_EQ(good_crx, good->id());
path = data_dir_.AppendASCII("good2.crx");
UpdateExtension(good_crx, path, ENABLED);
ASSERT_EQ("1.0.0.1",
service_->GetExtensionById(good_crx, false)->
version()->GetString());
}
TEST_F(ExtensionServiceTest, UpdateExtensionDuringShutdown) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
const Extension* good = InstallCRX(path, INSTALL_NEW);
ASSERT_EQ(good_crx, good->id());
service_->set_browser_terminating_for_test(true);
path = data_dir_.AppendASCII("good2.crx");
bool updated = service_->UpdateExtension(good_crx, path, true, GURL(), NULL);
ASSERT_FALSE(updated);
ASSERT_EQ("1.0.0.0",
service_->GetExtensionById(good_crx, false)->
version()->GetString());
}
TEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
UpdateExtension(good_crx, path, UPDATED);
base::RunLoop().RunUntilIdle();
ASSERT_EQ(0u, registry_->enabled_extensions().size());
ASSERT_FALSE(installed_);
ASSERT_EQ(0u, loaded_.size());
}
TEST_F(ExtensionServiceTest, UpdateWillNotDowngrade) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good2.crx");
const Extension* good = InstallCRX(path, INSTALL_NEW);
ASSERT_EQ("1.0.0.1", good->VersionString());
ASSERT_EQ(good_crx, good->id());
path = data_dir_.AppendASCII("good.crx");
UpdateExtension(good_crx, path, FAILED);
ASSERT_EQ("1.0.0.1",
service_->GetExtensionById(good_crx, false)->
version()->GetString());
}
TEST_F(ExtensionServiceTest, UpdateToSameVersionIsNoop) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
const Extension* good = InstallCRX(path, INSTALL_NEW);
ASSERT_EQ(good_crx, good->id());
UpdateExtension(good_crx, path, FAILED_SILENTLY);
}
TEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
const Extension* good = InstallCRX(path, INSTALL_NEW);
ASSERT_EQ("1.0.0.0", good->VersionString());
ASSERT_EQ(good_crx, good->id());
service_->DisableExtension(good->id(), Extension::DISABLE_USER_ACTION);
extensions::util::SetIsIncognitoEnabled(good->id(), profile_.get(), true);
ExtensionPrefs::Get(profile_.get())
->SetDidExtensionEscalatePermissions(good, true);
path = data_dir_.AppendASCII("good2.crx");
UpdateExtension(good_crx, path, INSTALLED);
ASSERT_EQ(1u, registry_->disabled_extensions().size());
const Extension* good2 = service_->GetExtensionById(good_crx, true);
ASSERT_EQ("1.0.0.1", good2->version()->GetString());
EXPECT_TRUE(extensions::util::IsIncognitoEnabled(
good2->id(), profile_.get()));
EXPECT_TRUE(ExtensionPrefs::Get(profile_.get())
->DidExtensionEscalatePermissions(good2->id()));
}
TEST_F(ExtensionServiceTest, UpdateExtensionPreservesLocation) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
const Extension* good =
InstallCRXWithLocation(path, Manifest::EXTERNAL_PREF, INSTALL_NEW);
ASSERT_EQ("1.0.0.0", good->VersionString());
ASSERT_EQ(good_crx, good->id());
path = data_dir_.AppendASCII("good2.crx");
UpdateExtension(good_crx, path, ENABLED);
const Extension* good2 = service_->GetExtensionById(good_crx, false);
ASSERT_EQ("1.0.0.1", good2->version()->GetString());
EXPECT_EQ(good2->location(), Manifest::EXTERNAL_PREF);
}
TEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) {
InitializeEmptyExtensionService();
base::ScopedTempDir temp;
ASSERT_TRUE(temp.CreateUniqueTempDir());
base::FilePath extension_path = temp.path();
base::FilePath manifest_path =
extension_path.Append(extensions::kManifestFilename);
ASSERT_FALSE(base::PathExists(manifest_path));
base::DictionaryValue manifest;
manifest.SetString("version", "2.0");
manifest.SetString("name", "LOAD Downgrade Test");
manifest.SetInteger("manifest_version", 2);
JSONFileValueSerializer serializer(manifest_path);
ASSERT_TRUE(serializer.Serialize(manifest));
extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0u, GetErrors().size());
ASSERT_EQ(1u, loaded_.size());
EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_EQ("2.0", loaded_[0]->VersionString());
manifest.SetString("version", "1.0");
ASSERT_TRUE(serializer.Serialize(manifest));
extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0u, GetErrors().size());
ASSERT_EQ(1u, loaded_.size());
EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_EQ("1.0", loaded_[0]->VersionString());
}
#if !defined(OS_CHROMEOS)
TEST_F(ExtensionServiceTest, LoadExtensionsWithPlugins) {
base::FilePath extension_with_plugin_path = good1_path();
base::FilePath extension_no_plugin_path = good2_path();
InitPluginService();
InitializeEmptyExtensionService();
InitializeProcessManager();
service_->set_show_extensions_prompts(true);
CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kAppsGalleryInstallAutoConfirmForTests,
"cancel");
extensions::UnpackedInstaller::Create(service_)->Load(
extension_with_plugin_path);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0u, GetErrors().size());
EXPECT_EQ(0u, loaded_.size());
EXPECT_EQ(0u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
ExtensionErrorReporter::GetInstance()->ClearErrors();
extensions::UnpackedInstaller::Create(service_)->Load(
extension_no_plugin_path);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0u, GetErrors().size());
EXPECT_EQ(1u, loaded_.size());
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
EXPECT_TRUE(registry_->enabled_extensions().Contains(good2));
CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kAppsGalleryInstallAutoConfirmForTests,
"accept");
ExtensionErrorReporter::GetInstance()->ClearErrors();
extensions::UnpackedInstaller::Create(service_)->Load(
extension_with_plugin_path);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0u, GetErrors().size());
EXPECT_EQ(2u, loaded_.size());
EXPECT_EQ(2u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
EXPECT_TRUE(registry_->enabled_extensions().Contains(good1));
EXPECT_TRUE(registry_->enabled_extensions().Contains(good2));
scoped_refptr<PermissionSet> permissions(
ExtensionPrefs::Get(profile_.get())->GetGrantedPermissions(good1));
EXPECT_FALSE(permissions->IsEmpty());
EXPECT_TRUE(permissions->HasEffectiveFullAccess());
EXPECT_FALSE(permissions->apis().empty());
EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
loaded_.clear();
CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kAppsGalleryInstallAutoConfirmForTests,
"cancel");
service_->ReloadExtension(good1);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, loaded_.size());
EXPECT_EQ(2u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
}
#endif
namespace {
bool IsExtension(const Extension* extension) {
return extension->GetType() == Manifest::TYPE_EXTENSION;
}
}
TEST_F(ExtensionServiceTest, AddPendingExtensionFromSync) {
InitializeEmptyExtensionService();
const std::string kFakeId(all_zero);
const GURL kFakeUpdateURL("http:://fake.update/url");
const bool kFakeInstallSilently(true);
EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
kFakeId, kFakeUpdateURL, &IsExtension,
kFakeInstallSilently));
const extensions::PendingExtensionInfo* pending_extension_info;
ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
GetById(kFakeId)));
EXPECT_EQ(kFakeUpdateURL, pending_extension_info->update_url());
EXPECT_EQ(&IsExtension, pending_extension_info->should_allow_install_);
EXPECT_EQ(kFakeInstallSilently, pending_extension_info->install_silently());
}
namespace {
const char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
const char kGoodUpdateURL[] = "http://good.update/url";
const bool kGoodIsFromSync = true;
const bool kGoodInstallSilently = true;
}
TEST_F(ExtensionServiceTest, UpdatePendingExtension) {
InitializeEmptyExtensionService();
EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
kGoodId, GURL(kGoodUpdateURL), &IsExtension,
kGoodInstallSilently));
EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(kGoodId));
base::FilePath path = data_dir_.AppendASCII("good.crx");
UpdateExtension(kGoodId, path, ENABLED);
EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
const Extension* extension = service_->GetExtensionById(kGoodId, true);
ASSERT_TRUE(extension);
}
namespace {
bool IsTheme(const Extension* extension) {
return extension->is_theme();
}
}
TEST_F(ExtensionServiceTest, DISABLED_UpdatePendingTheme) {
InitializeEmptyExtensionService();
EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
theme_crx, GURL(), &IsTheme, false));
EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
base::FilePath path = data_dir_.AppendASCII("theme.crx");
UpdateExtension(theme_crx, path, ENABLED);
EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
const Extension* extension = service_->GetExtensionById(theme_crx, true);
ASSERT_TRUE(extension);
EXPECT_FALSE(ExtensionPrefs::Get(profile_.get())
->IsExtensionDisabled(extension->id()));
EXPECT_TRUE(service_->IsExtensionEnabled(theme_crx));
}
#if defined(OS_CHROMEOS)
#define MAYBE_UpdatePendingExternalCrx DISABLED_UpdatePendingExternalCrx
#else
#define MAYBE_UpdatePendingExternalCrx UpdatePendingExternalCrx
#endif
TEST_F(ExtensionServiceTest, MAYBE_UpdatePendingExternalCrx) {
InitializeEmptyExtensionService();
EXPECT_TRUE(service_->pending_extension_manager()->AddFromExternalUpdateUrl(
theme_crx,
std::string(),
GURL(),
Manifest::EXTERNAL_PREF_DOWNLOAD,
Extension::NO_FLAGS,
false));
EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
base::FilePath path = data_dir_.AppendASCII("theme.crx");
UpdateExtension(theme_crx, path, ENABLED);
EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
const Extension* extension = service_->GetExtensionById(theme_crx, true);
ASSERT_TRUE(extension);
EXPECT_FALSE(ExtensionPrefs::Get(profile_.get())
->IsExtensionDisabled(extension->id()));
EXPECT_TRUE(service_->IsExtensionEnabled(extension->id()));
EXPECT_FALSE(extensions::util::IsIncognitoEnabled(extension->id(),
profile_.get()));
}
TEST_F(ExtensionServiceTest, UpdatePendingExternalCrxWinsOverSync) {
InitializeEmptyExtensionService();
EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
kGoodId, GURL(kGoodUpdateURL), &IsExtension,
kGoodInstallSilently));
const extensions::PendingExtensionInfo* pending_extension_info;
ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
GetById(kGoodId)));
EXPECT_TRUE(pending_extension_info->is_from_sync());
EXPECT_TRUE(service_->pending_extension_manager()->AddFromExternalUpdateUrl(
kGoodId,
std::string(),
GURL(kGoodUpdateURL),
Manifest::EXTERNAL_PREF_DOWNLOAD,
Extension::NO_FLAGS,
false));
ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
GetById(kGoodId)));
EXPECT_FALSE(pending_extension_info->is_from_sync());
EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
pending_extension_info->install_source());
EXPECT_FALSE(service_->pending_extension_manager()->AddFromSync(
kGoodId, GURL(kGoodUpdateURL), &IsExtension,
kGoodInstallSilently));
ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
GetById(kGoodId)));
EXPECT_FALSE(pending_extension_info->is_from_sync());
EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
pending_extension_info->install_source());
}
TEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) {
InitializeEmptyExtensionService();
EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
theme_crx, GURL(), &IsExtension, true));
EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
base::FilePath path = data_dir_.AppendASCII("theme.crx");
UpdateExtension(theme_crx, path, FAILED_SILENTLY);
EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
const Extension* extension = service_->GetExtensionById(theme_crx, true);
ASSERT_FALSE(extension);
}
TEST_F(ExtensionServiceTest, UpdatePendingExtensionFailedShouldInstallTest) {
InitializeEmptyExtensionService();
EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
kGoodId, GURL(kGoodUpdateURL), &IsTheme, kGoodInstallSilently));
EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(kGoodId));
base::FilePath path = data_dir_.AppendASCII("good.crx");
UpdateExtension(kGoodId, path, UPDATED);
EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
}
TEST_F(ExtensionServiceTest, UpdatePendingExtensionNotPending) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
UpdateExtension(kGoodId, path, UPDATED);
EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
}
TEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
const Extension* good = InstallCRX(path, INSTALL_NEW);
ASSERT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_FALSE(good->is_theme());
service_->pending_extension_manager()->AddExtensionImpl(
good->id(),
std::string(),
extensions::ManifestURL::GetUpdateURL(good),
Version(),
&IsExtension,
kGoodIsFromSync,
kGoodInstallSilently,
Manifest::INTERNAL,
Extension::NO_FLAGS,
false);
UpdateExtension(good->id(), path, ENABLED);
EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
}
#if defined(ENABLE_BLACKLIST_TESTS)
TEST_F(ExtensionServiceTest, SetUnsetBlacklistInPrefs) {
extensions::TestBlacklist test_blacklist;
InitializeGoodInstalledExtensionService();
test_blacklist.Attach(service_->blacklist_);
service_->Init();
const extensions::ExtensionSet& enabled_extensions =
registry_->enabled_extensions();
const extensions::ExtensionSet& blacklisted_extensions =
registry_->blacklisted_extensions();
EXPECT_TRUE(enabled_extensions.Contains(good0) &&
!blacklisted_extensions.Contains(good0));
EXPECT_TRUE(enabled_extensions.Contains(good1) &&
!blacklisted_extensions.Contains(good1));
EXPECT_TRUE(enabled_extensions.Contains(good2) &&
!blacklisted_extensions.Contains(good2));
EXPECT_FALSE(IsPrefExist(good0, "blacklist"));
EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
test_blacklist.SetBlacklistState(
good0, extensions::BLACKLISTED_MALWARE, true);
test_blacklist.SetBlacklistState(
good1, extensions::BLACKLISTED_MALWARE, true);
test_blacklist.SetBlacklistState(
"invalid_id", extensions::BLACKLISTED_MALWARE, true);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(!enabled_extensions.Contains(good0) &&
blacklisted_extensions.Contains(good0));
EXPECT_TRUE(!enabled_extensions.Contains(good1) &&
blacklisted_extensions.Contains(good1));
EXPECT_TRUE(enabled_extensions.Contains(good2) &&
!blacklisted_extensions.Contains(good2));
EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
EXPECT_TRUE(ValidateBooleanPref(good1, "blacklist", true));
EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
test_blacklist.Clear(false);
test_blacklist.SetBlacklistState(
good0, extensions::BLACKLISTED_MALWARE, true);
test_blacklist.SetBlacklistState(
good2, extensions::BLACKLISTED_MALWARE, true);
test_blacklist.SetBlacklistState(
"invalid_id", extensions::BLACKLISTED_MALWARE, true);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(!enabled_extensions.Contains(good0) &&
blacklisted_extensions.Contains(good0));
EXPECT_TRUE(enabled_extensions.Contains(good1) &&
!blacklisted_extensions.Contains(good1));
EXPECT_TRUE(!enabled_extensions.Contains(good2) &&
blacklisted_extensions.Contains(good2));
EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
EXPECT_TRUE(ValidateBooleanPref(good2, "blacklist", true));
EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
}
#endif
#if defined(ENABLE_BLACKLIST_TESTS)
TEST_F(ExtensionServiceTest, BlacklistedExtensionWillNotInstall) {
scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
new FakeSafeBrowsingDatabaseManager(true));
Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
InitializeEmptyExtensionService();
service_->Init();
blacklist_db->SetUnsafe(good_crx).NotifyUpdate();
base::RunLoop().RunUntilIdle();
base::FilePath path = data_dir_.AppendASCII("good.crx");
InstallCRX(path, INSTALL_FAILED, Extension::WAS_INSTALLED_BY_DEFAULT);
EXPECT_EQ(0u, registry_->enabled_extensions().size());
}
#endif
#if defined(ENABLE_BLACKLIST_TESTS)
TEST_F(ExtensionServiceTest, UnloadBlacklistedExtensionPolicy) {
extensions::TestBlacklist test_blacklist;
InitializeEmptyExtensionService();
test_blacklist.Attach(service_->blacklist_);
base::FilePath path = data_dir_.AppendASCII("good.crx");
const Extension* good = InstallCRX(path, INSTALL_NEW);
EXPECT_EQ(good_crx, good->id());
UpdateExtension(good_crx, path, FAILED_SILENTLY);
EXPECT_EQ(1u, registry_->enabled_extensions().size());
base::ListValue whitelist;
PrefService* prefs = ExtensionPrefs::Get(profile_.get())->pref_service();
whitelist.Append(new base::StringValue(good_crx));
prefs->Set(extensions::pref_names::kInstallAllowList, whitelist);
test_blacklist.SetBlacklistState(
good_crx, extensions::BLACKLISTED_MALWARE, true);
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(ValidateBooleanPref(good_crx, "blacklist", true));
EXPECT_EQ(0u, registry_->enabled_extensions().size());
}
#endif
#if defined(ENABLE_BLACKLIST_TESTS)
TEST_F(ExtensionServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
extensions::TestBlacklist test_blacklist;
InitializeGoodInstalledExtensionService();
test_blacklist.Attach(service_->blacklist_);
test_blacklist.SetBlacklistState(
good1, extensions::BLACKLISTED_MALWARE, false);
service_->Init();
ASSERT_EQ(3u, loaded_.size());
base::RunLoop().RunUntilIdle();
ASSERT_EQ(1u, registry_->blacklisted_extensions().size());
ASSERT_EQ(2u, registry_->enabled_extensions().size());
ASSERT_TRUE(registry_->enabled_extensions().Contains(good0));
ASSERT_TRUE(registry_->blacklisted_extensions().Contains(good1));
ASSERT_TRUE(registry_->enabled_extensions().Contains(good2));
}
#endif
#if defined(ENABLE_BLACKLIST_TESTS)
TEST_F(ExtensionServiceTest, BlacklistedInPrefsFromStartup) {
extensions::TestBlacklist test_blacklist;
InitializeGoodInstalledExtensionService();
test_blacklist.Attach(service_->blacklist_);
ExtensionPrefs::Get(profile_.get())->SetExtensionBlacklisted(good0, true);
ExtensionPrefs::Get(profile_.get())->SetExtensionBlacklisted(good1, true);
test_blacklist.SetBlacklistState(
good1, extensions::BLACKLISTED_MALWARE, false);
service_->Init();
ASSERT_EQ(2u, registry_->blacklisted_extensions().size());
ASSERT_EQ(1u, registry_->enabled_extensions().size());
ASSERT_TRUE(registry_->blacklisted_extensions().Contains(good0));
ASSERT_TRUE(registry_->blacklisted_extensions().Contains(good1));
ASSERT_TRUE(registry_->enabled_extensions().Contains(good2));
base::RunLoop().RunUntilIdle();
ASSERT_EQ(1u, registry_->blacklisted_extensions().size());
ASSERT_EQ(2u, registry_->enabled_extensions().size());
ASSERT_TRUE(registry_->enabled_extensions().Contains(good0));
ASSERT_TRUE(registry_->blacklisted_extensions().Contains(good1));
ASSERT_TRUE(registry_->enabled_extensions().Contains(good2));
}
#endif
#if defined(ENABLE_BLACKLIST_TESTS)
TEST_F(ExtensionServiceTest, GreylistedExtensionDisabled) {
extensions::TestBlacklist test_blacklist;
InitializeGoodInstalledExtensionService();
test_blacklist.Attach(service_->blacklist_);
service_->Init();
const extensions::ExtensionSet& enabled_extensions =
registry_->enabled_extensions();
const extensions::ExtensionSet& disabled_extensions =
registry_->disabled_extensions();
EXPECT_TRUE(enabled_extensions.Contains(good0));
EXPECT_TRUE(enabled_extensions.Contains(good1));
EXPECT_TRUE(enabled_extensions.Contains(good2));
test_blacklist.SetBlacklistState(
good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
test_blacklist.SetBlacklistState(
good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
test_blacklist.SetBlacklistState(
"invalid_id", extensions::BLACKLISTED_MALWARE, true);
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(enabled_extensions.Contains(good0));
EXPECT_TRUE(disabled_extensions.Contains(good0));
EXPECT_FALSE(enabled_extensions.Contains(good1));
EXPECT_TRUE(disabled_extensions.Contains(good1));
EXPECT_TRUE(enabled_extensions.Contains(good2));
EXPECT_FALSE(disabled_extensions.Contains(good2));
ValidateIntegerPref(
good0, "blacklist_state", extensions::BLACKLISTED_CWS_POLICY_VIOLATION);
ValidateIntegerPref(
good1, "blacklist_state", extensions::BLACKLISTED_POTENTIALLY_UNWANTED);
service_->EnableExtension(good0);
EXPECT_TRUE(enabled_extensions.Contains(good0));
EXPECT_FALSE(disabled_extensions.Contains(good0));
EXPECT_FALSE(enabled_extensions.Contains(good1));
EXPECT_TRUE(disabled_extensions.Contains(good1));
test_blacklist.SetBlacklistState(
good0, extensions::NOT_BLACKLISTED, true);
test_blacklist.SetBlacklistState(
good1, extensions::NOT_BLACKLISTED, true);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(enabled_extensions.Contains(good0));
EXPECT_FALSE(disabled_extensions.Contains(good0));
EXPECT_TRUE(enabled_extensions.Contains(good1));
EXPECT_FALSE(disabled_extensions.Contains(good1));
EXPECT_TRUE(enabled_extensions.Contains(good2));
EXPECT_FALSE(disabled_extensions.Contains(good2));
}
#endif
#if defined(ENABLE_BLACKLIST_TESTS)
TEST_F(ExtensionServiceTest, GreylistDontEnableManuallyDisabled) {
extensions::TestBlacklist test_blacklist;
InitializeGoodInstalledExtensionService();
test_blacklist.Attach(service_->blacklist_);
service_->Init();
const extensions::ExtensionSet& enabled_extensions =
registry_->enabled_extensions();
const extensions::ExtensionSet& disabled_extensions =
registry_->disabled_extensions();
service_->DisableExtension(good0, extensions::Extension::DISABLE_USER_ACTION);
test_blacklist.SetBlacklistState(
good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
test_blacklist.SetBlacklistState(
good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
test_blacklist.SetBlacklistState(
good2, extensions::BLACKLISTED_SECURITY_VULNERABILITY, true);
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(enabled_extensions.Contains(good0));
EXPECT_TRUE(disabled_extensions.Contains(good0));
EXPECT_FALSE(enabled_extensions.Contains(good1));
EXPECT_TRUE(disabled_extensions.Contains(good1));
EXPECT_FALSE(enabled_extensions.Contains(good2));
EXPECT_TRUE(disabled_extensions.Contains(good2));
service_->EnableExtension(good1);
EXPECT_TRUE(enabled_extensions.Contains(good1));
EXPECT_FALSE(disabled_extensions.Contains(good1));
service_->DisableExtension(good1, extensions::Extension::DISABLE_USER_ACTION);
EXPECT_FALSE(enabled_extensions.Contains(good1));
EXPECT_TRUE(disabled_extensions.Contains(good1));
test_blacklist.SetBlacklistState(
good0, extensions::NOT_BLACKLISTED, true);
test_blacklist.SetBlacklistState(
good1, extensions::NOT_BLACKLISTED, true);
test_blacklist.SetBlacklistState(
good2, extensions::NOT_BLACKLISTED, true);
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(enabled_extensions.Contains(good0));
EXPECT_TRUE(disabled_extensions.Contains(good0));
EXPECT_FALSE(enabled_extensions.Contains(good1));
EXPECT_TRUE(disabled_extensions.Contains(good1));
EXPECT_TRUE(enabled_extensions.Contains(good2));
EXPECT_FALSE(disabled_extensions.Contains(good2));
}
#endif
#if defined(ENABLE_BLACKLIST_TESTS)
TEST_F(ExtensionServiceTest, GreylistUnknownDontChange) {
extensions::TestBlacklist test_blacklist;
InitializeGoodInstalledExtensionService();
test_blacklist.Attach(service_->blacklist_);
service_->Init();
const extensions::ExtensionSet& enabled_extensions =
registry_->enabled_extensions();
const extensions::ExtensionSet& disabled_extensions =
registry_->disabled_extensions();
test_blacklist.SetBlacklistState(
good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
test_blacklist.SetBlacklistState(
good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(enabled_extensions.Contains(good0));
EXPECT_TRUE(disabled_extensions.Contains(good0));
EXPECT_FALSE(enabled_extensions.Contains(good1));
EXPECT_TRUE(disabled_extensions.Contains(good1));
EXPECT_TRUE(enabled_extensions.Contains(good2));
EXPECT_FALSE(disabled_extensions.Contains(good2));
test_blacklist.SetBlacklistState(
good0, extensions::NOT_BLACKLISTED, true);
test_blacklist.SetBlacklistState(
good1, extensions::BLACKLISTED_UNKNOWN, true);
test_blacklist.SetBlacklistState(
good2, extensions::BLACKLISTED_UNKNOWN, true);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(enabled_extensions.Contains(good0));
EXPECT_FALSE(disabled_extensions.Contains(good0));
EXPECT_FALSE(enabled_extensions.Contains(good1));
EXPECT_TRUE(disabled_extensions.Contains(good1));
EXPECT_TRUE(enabled_extensions.Contains(good2));
EXPECT_FALSE(disabled_extensions.Contains(good2));
}
#endif
TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) {
InitializeEmptyExtensionService();
{
ListPrefUpdate update(profile_->GetPrefs(),
extensions::pref_names::kInstallDenyList);
base::ListValue* blacklist = update.Get();
blacklist->Append(new base::StringValue("*"));
}
base::FilePath path = data_dir_.AppendASCII("good.crx");
InstallCRX(path, INSTALL_FAILED);
EXPECT_EQ(0u, registry_->enabled_extensions().size());
{
ListPrefUpdate update(profile_->GetPrefs(),
extensions::pref_names::kInstallAllowList);
base::ListValue* whitelist = update.Get();
whitelist->Append(new base::StringValue(good_crx));
}
InstallCRX(path, INSTALL_NEW);
EXPECT_EQ(1u, registry_->enabled_extensions().size());
}
TEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
InstallCRX(path, INSTALL_NEW);
EXPECT_EQ(1u, registry_->enabled_extensions().size());
{
PrefService* prefs = profile_->GetPrefs();
ListPrefUpdate update(prefs, extensions::pref_names::kInstallDenyList);
base::ListValue* blacklist = update.Get();
ASSERT_TRUE(blacklist != NULL);
blacklist->Append(new base::StringValue(good_crx));
}
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0u, registry_->enabled_extensions().size());
}
TEST_F(ExtensionServiceTest, ComponentExtensionWhitelisted) {
InitializeEmptyExtensionService();
{
ListPrefUpdate update(profile_->GetPrefs(),
extensions::pref_names::kInstallDenyList);
base::ListValue* blacklist = update.Get();
blacklist->Append(new base::StringValue("*"));
}
base::FilePath path = data_dir_
.AppendASCII("good")
.AppendASCII("Extensions")
.AppendASCII(good0)
.AppendASCII("1.0.0.0");
std::string manifest;
ASSERT_TRUE(base::ReadFileToString(
path.Append(extensions::kManifestFilename), &manifest));
service_->component_loader()->Add(manifest, path);
service_->Init();
ASSERT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_TRUE(service_->GetExtensionById(good0, false));
service_->CheckForExternalUpdates();
ASSERT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_TRUE(service_->GetExtensionById(good0, false));
{
ListPrefUpdate update(profile_->GetPrefs(),
extensions::pref_names::kInstallDenyList);
base::ListValue* blacklist = update.Get();
blacklist->Append(new base::StringValue(good0));
}
base::RunLoop().RunUntilIdle();
ASSERT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_TRUE(service_->GetExtensionById(good0, false));
}
TEST_F(ExtensionServiceTest, PolicyInstalledExtensionsWhitelisted) {
InitializeEmptyExtensionService();
{
ListPrefUpdate blacklist_update(
profile_->GetPrefs(), extensions::pref_names::kInstallDenyList);
base::ListValue* blacklist = blacklist_update.Get();
blacklist->AppendString("*");
DictionaryPrefUpdate forcelist_update(
profile_->GetPrefs(),
extensions::pref_names::kInstallForceList);
extensions::ExternalPolicyLoader::AddExtension(
forcelist_update.Get(), good_crx, "http://example.com/update_url");
}
MockExtensionProvider* provider =
new MockExtensionProvider(service_,
Manifest::EXTERNAL_POLICY_DOWNLOAD);
AddMockExternalProvider(provider);
provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
data_dir_.AppendASCII("good.crx"));
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
service_->CheckForExternalUpdates();
observer.Wait();
ASSERT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
{
ListPrefUpdate update(profile_->GetPrefs(),
extensions::pref_names::kInstallDenyList);
base::ListValue* blacklist = update.Get();
blacklist->Append(new base::StringValue(good0));
}
base::RunLoop().RunUntilIdle();
ASSERT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
}
TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsInstall) {
InitializeEmptyExtensionService();
management_policy_->UnregisterAllProviders();
extensions::TestManagementPolicyProvider provider_(
extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
management_policy_->RegisterProvider(&provider_);
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_FAILED);
EXPECT_EQ(0u, registry_->enabled_extensions().size());
}
TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsLoadFromPrefs) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("management")
.AppendASCII("simple_extension");
base::DictionaryValue manifest;
manifest.SetString(keys::kName, "simple_extension");
manifest.SetString(keys::kVersion, "1");
extensions::ExtensionInfo extension_info(
&manifest, std::string(), path, Manifest::UNPACKED);
management_policy_->UnregisterAllProviders();
EXPECT_EQ(0u, registry_->enabled_extensions().size());
extensions::InstalledLoader(service_).Load(extension_info, false);
EXPECT_EQ(1u, registry_->enabled_extensions().size());
const Extension* extension = (registry_->enabled_extensions().begin())->get();
EXPECT_TRUE(service_->UninstallExtension(extension->id(), false, NULL));
EXPECT_EQ(0u, registry_->enabled_extensions().size());
extensions::TestManagementPolicyProvider provider_(
extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
management_policy_->RegisterProvider(&provider_);
extensions::InstalledLoader(service_).Load(extension_info, false);
EXPECT_EQ(0u, registry_->enabled_extensions().size());
}
TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsDisable) {
InitializeEmptyExtensionService();
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
management_policy_->UnregisterAllProviders();
extensions::TestManagementPolicyProvider provider(
extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
management_policy_->RegisterProvider(&provider);
service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
EXPECT_EQ(0u, registry_->disabled_extensions().size());
}
TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsUninstall) {
InitializeEmptyExtensionService();
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
management_policy_->UnregisterAllProviders();
extensions::TestManagementPolicyProvider provider(
extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
management_policy_->RegisterProvider(&provider);
EXPECT_FALSE(service_->UninstallExtension(good_crx, false, NULL));
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
}
TEST_F(ExtensionServiceTest, ManagementPolicyUnloadsAllProhibited) {
InitializeEmptyExtensionService();
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
InstallCRX(data_dir_.AppendASCII("page_action.crx"), INSTALL_NEW);
EXPECT_EQ(2u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
management_policy_->UnregisterAllProviders();
extensions::TestManagementPolicyProvider provider(
extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
management_policy_->RegisterProvider(&provider);
service_->CheckManagementPolicy();
EXPECT_EQ(0u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
}
TEST_F(ExtensionServiceTest, ManagementPolicyRequiresEnable) {
InitializeEmptyExtensionService();
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
EXPECT_EQ(1u, registry_->enabled_extensions().size());
service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
EXPECT_EQ(1u, registry_->disabled_extensions().size());
management_policy_->UnregisterAllProviders();
extensions::TestManagementPolicyProvider provider(
extensions::TestManagementPolicyProvider::MUST_REMAIN_ENABLED);
management_policy_->RegisterProvider(&provider);
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_UPDATED);
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
}
#if defined(OS_WIN)
#define MAYBE_ExternalExtensionAutoAcknowledgement DISABLED_ExternalExtensionAutoAcknowledgement
#else
#define MAYBE_ExternalExtensionAutoAcknowledgement ExternalExtensionAutoAcknowledgement
#endif
TEST_F(ExtensionServiceTest, MAYBE_ExternalExtensionAutoAcknowledgement) {
InitializeEmptyExtensionService();
set_extensions_enabled(true);
{
MockExtensionProvider* provider =
new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
AddMockExternalProvider(provider);
provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
data_dir_.AppendASCII("good.crx"));
}
{
MockExtensionProvider* provider =
new MockExtensionProvider(service_,
Manifest::EXTERNAL_POLICY_DOWNLOAD);
AddMockExternalProvider(provider);
provider->UpdateOrAddExtension(page_action, "1.0.0.0",
data_dir_.AppendASCII("page_action.crx"));
}
int count = 2;
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
base::Bind(&WaitForCountNotificationsCallback, &count));
service_->CheckForExternalUpdates();
observer.Wait();
ASSERT_EQ(2u, registry_->enabled_extensions().size());
EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
EXPECT_TRUE(service_->GetExtensionById(page_action, false));
ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_.get());
ASSERT_TRUE(!prefs->IsExternalExtensionAcknowledged(good_crx));
ASSERT_TRUE(prefs->IsExternalExtensionAcknowledged(page_action));
}
#if !defined(OS_CHROMEOS)
TEST_F(ExtensionServiceTest, DefaultAppsInstall) {
InitializeEmptyExtensionService();
set_extensions_enabled(true);
{
std::string json_data =
"{"
" \"ldnnhddmnhbkjipkidpdiheffobcpfmf\" : {"
" \"external_crx\": \"good.crx\","
" \"external_version\": \"1.0.0.0\","
" \"is_bookmark_app\": false"
" }"
"}";
default_apps::Provider* provider =
new default_apps::Provider(
profile_.get(),
service_,
new extensions::ExternalTestingLoader(json_data, data_dir_),
Manifest::INTERNAL,
Manifest::INVALID_LOCATION,
Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
AddMockExternalProvider(provider);
}
ASSERT_EQ(0u, registry_->enabled_extensions().size());
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
service_->CheckForExternalUpdates();
observer.Wait();
ASSERT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
const Extension* extension = service_->GetExtensionById(good_crx, false);
EXPECT_TRUE(extension->from_webstore());
EXPECT_TRUE(extension->was_installed_by_default());
}
#endif
TEST_F(ExtensionServiceTest, DisableExtension) {
InitializeEmptyExtensionService();
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
EXPECT_EQ(0u, registry_->terminated_extensions().size());
EXPECT_EQ(0u, registry_->blacklisted_extensions().size());
service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
EXPECT_FALSE(service_->GetExtensionById(good_crx, false));
EXPECT_EQ(0u, registry_->enabled_extensions().size());
EXPECT_EQ(1u, registry_->disabled_extensions().size());
EXPECT_EQ(0u, registry_->terminated_extensions().size());
EXPECT_EQ(0u, registry_->blacklisted_extensions().size());
}
TEST_F(ExtensionServiceTest, TerminateExtension) {
InitializeEmptyExtensionService();
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
EXPECT_EQ(0u, registry_->terminated_extensions().size());
EXPECT_EQ(0u, registry_->blacklisted_extensions().size());
TerminateExtension(good_crx);
EXPECT_EQ(0u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
EXPECT_EQ(1u, registry_->terminated_extensions().size());
EXPECT_EQ(0u, registry_->blacklisted_extensions().size());
}
TEST_F(ExtensionServiceTest, DisableTerminatedExtension) {
InitializeEmptyExtensionService();
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
TerminateExtension(good_crx);
EXPECT_TRUE(registry_->GetExtensionById(
good_crx, extensions::ExtensionRegistry::TERMINATED));
service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
EXPECT_FALSE(registry_->GetExtensionById(
good_crx, extensions::ExtensionRegistry::TERMINATED));
EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
EXPECT_EQ(0u, registry_->enabled_extensions().size());
EXPECT_EQ(1u, registry_->disabled_extensions().size());
EXPECT_EQ(0u, registry_->terminated_extensions().size());
EXPECT_EQ(0u, registry_->blacklisted_extensions().size());
}
TEST_F(ExtensionServiceTest, DisableAllExtensions) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
InstallCRX(path, INSTALL_NEW);
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
service_->set_extensions_enabled(false);
service_->ReloadExtensionsForTest();
EXPECT_EQ(0u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
service_->EnableExtension(good_crx);
service_->ReloadExtensionsForTest();
EXPECT_EQ(0u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
service_->set_extensions_enabled(true);
service_->ReloadExtensionsForTest();
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
}
TEST_F(ExtensionServiceTest, ReloadExtensions) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
InstallCRX(path, INSTALL_NEW,
Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
const char* extension_id = good_crx;
service_->DisableExtension(extension_id, Extension::DISABLE_USER_ACTION);
EXPECT_EQ(0u, registry_->enabled_extensions().size());
EXPECT_EQ(1u, registry_->disabled_extensions().size());
service_->ReloadExtensionsForTest();
const Extension* extension = service_->GetExtensionById(good_crx, true);
EXPECT_TRUE(extension->from_webstore());
EXPECT_TRUE(extension->was_installed_by_default());
EXPECT_FALSE(extension->from_bookmark());
EXPECT_EQ(0u, registry_->enabled_extensions().size());
EXPECT_EQ(1u, registry_->disabled_extensions().size());
service_->EnableExtension(extension_id);
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
loaded_.clear();
service_->ReloadExtensionsForTest();
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
}
TEST_F(ExtensionServiceTest, ReloadExtension) {
InitializeEmptyExtensionService();
InitializeProcessManager();
const char* extension_id = "behllobkkfkfnphdnhnkndlbkcpglgmj";
base::FilePath ext = data_dir_
.AppendASCII("good")
.AppendASCII("Extensions")
.AppendASCII(extension_id)
.AppendASCII("1.0.0.0");
extensions::UnpackedInstaller::Create(service_)->Load(ext);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
service_->ReloadExtension(extension_id);
EXPECT_EQ(0u, registry_->enabled_extensions().size());
EXPECT_EQ(1u, registry_->disabled_extensions().size());
EXPECT_EQ(
Extension::DISABLE_RELOAD,
ExtensionPrefs::Get(profile_.get())->GetDisableReasons(extension_id));
service_->ReloadExtension(extension_id);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_EQ(0u, registry_->disabled_extensions().size());
}
TEST_F(ExtensionServiceTest, UninstallExtension) {
InitializeEmptyExtensionService();
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
EXPECT_EQ(1u, registry_->enabled_extensions().size());
UninstallExtension(good_crx, false);
EXPECT_EQ(0u, registry_->enabled_extensions().size());
}
TEST_F(ExtensionServiceTest, UninstallTerminatedExtension) {
InitializeEmptyExtensionService();
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
TerminateExtension(good_crx);
UninstallExtension(good_crx, false);
}
TEST_F(ExtensionServiceTest, UninstallExtensionHelper) {
InitializeEmptyExtensionService();
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
UninstallExtension(good_crx, true);
}
TEST_F(ExtensionServiceTest, UninstallExtensionHelperTerminated) {
InitializeEmptyExtensionService();
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
TerminateExtension(good_crx);
UninstallExtension(good_crx, true);
}
TEST_F(ExtensionServiceTest, UpgradingRequirementsEnabled) {
InitializeEmptyExtensionService();
BlackListWebGL();
base::FilePath path = data_dir_.AppendASCII("requirements");
base::FilePath pem_path = data_dir_.AppendASCII("requirements")
.AppendASCII("v1_good.pem");
const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
pem_path,
INSTALL_NEW);
std::string id = extension_v1->id();
EXPECT_TRUE(service_->IsExtensionEnabled(id));
base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
PackCRX(path.AppendASCII("v2_bad_requirements"),
pem_path,
v2_bad_requirements_crx);
UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
EXPECT_FALSE(service_->IsExtensionEnabled(id));
base::FilePath v3_good_crx = GetTemporaryFile();
PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
UpdateExtension(id, v3_good_crx, ENABLED);
EXPECT_TRUE(service_->IsExtensionEnabled(id));
}
TEST_F(ExtensionServiceTest, UpgradingRequirementsDisabled) {
InitializeEmptyExtensionService();
BlackListWebGL();
base::FilePath path = data_dir_.AppendASCII("requirements");
base::FilePath pem_path = data_dir_.AppendASCII("requirements")
.AppendASCII("v1_good.pem");
const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
pem_path,
INSTALL_NEW);
std::string id = extension_v1->id();
service_->DisableExtension(id, Extension::DISABLE_USER_ACTION);
EXPECT_FALSE(service_->IsExtensionEnabled(id));
base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
PackCRX(path.AppendASCII("v2_bad_requirements"),
pem_path,
v2_bad_requirements_crx);
UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
EXPECT_FALSE(service_->IsExtensionEnabled(id));
base::FilePath v3_good_crx = GetTemporaryFile();
PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
UpdateExtension(id, v3_good_crx, INSTALLED);
EXPECT_FALSE(service_->IsExtensionEnabled(id));
}
TEST_F(ExtensionServiceTest, UpgradingRequirementsPermissions) {
InitializeEmptyExtensionService();
BlackListWebGL();
base::FilePath path = data_dir_.AppendASCII("requirements");
base::FilePath pem_path = data_dir_.AppendASCII("requirements")
.AppendASCII("v1_good.pem");
const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
pem_path,
INSTALL_NEW);
std::string id = extension_v1->id();
EXPECT_TRUE(service_->IsExtensionEnabled(id));
base::FilePath v2_bad_requirements_and_permissions_crx = GetTemporaryFile();
PackCRX(path.AppendASCII("v2_bad_requirements_and_permissions"),
pem_path,
v2_bad_requirements_and_permissions_crx);
UpdateExtension(id, v2_bad_requirements_and_permissions_crx, INSTALLED);
EXPECT_FALSE(service_->IsExtensionEnabled(id));
base::FilePath v3_bad_permissions_crx = GetTemporaryFile();
PackCRX(path.AppendASCII("v3_bad_permissions"),
pem_path,
v3_bad_permissions_crx);
UpdateExtension(id, v3_bad_permissions_crx, INSTALLED);
EXPECT_FALSE(service_->IsExtensionEnabled(id));
}
TEST_F(ExtensionServiceTest, UnpackedRequirements) {
InitializeEmptyExtensionService();
BlackListWebGL();
base::FilePath path = data_dir_.AppendASCII("requirements")
.AppendASCII("v2_bad_requirements");
extensions::UnpackedInstaller::Create(service_)->Load(path);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, GetErrors().size());
EXPECT_EQ(0u, registry_->enabled_extensions().size());
}
class ExtensionCookieCallback {
public:
ExtensionCookieCallback()
: result_(false),
weak_factory_(base::MessageLoop::current()) {}
void SetCookieCallback(bool result) {
base::MessageLoop::current()->PostTask(FROM_HERE,
base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr()));
result_ = result;
}
void GetAllCookiesCallback(const net::CookieList& list) {
base::MessageLoop::current()->PostTask(FROM_HERE,
base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr()));
list_ = list;
}
net::CookieList list_;
bool result_;
base::WeakPtrFactory<base::MessageLoop> weak_factory_;
};
TEST_F(ExtensionServiceTest, ClearExtensionData) {
InitializeEmptyExtensionService();
ExtensionCookieCallback callback;
base::FilePath path = data_dir_;
path = path.AppendASCII("good.crx");
const Extension* extension = InstallCRX(path, INSTALL_NEW);
ASSERT_TRUE(extension);
GURL ext_url(extension->url());
std::string origin_id = webkit_database::GetIdentifierFromOrigin(ext_url);
net::CookieMonster* cookie_monster =
profile_->GetRequestContextForExtensions()->GetURLRequestContext()->
cookie_store()->GetCookieMonster();
ASSERT_TRUE(cookie_monster);
net::CookieOptions options;
cookie_monster->SetCookieWithOptionsAsync(
ext_url, "dummy=value", options,
base::Bind(&ExtensionCookieCallback::SetCookieCallback,
base::Unretained(&callback)));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(callback.result_);
cookie_monster->GetAllCookiesForURLAsync(
ext_url,
base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
base::Unretained(&callback)));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1U, callback.list_.size());
webkit_database::DatabaseTracker* db_tracker =
BrowserContext::GetDefaultStoragePartition(profile_.get())->
GetDatabaseTracker();
base::string16 db_name = base::UTF8ToUTF16("db");
base::string16 description = base::UTF8ToUTF16("db_description");
int64 size;
db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
db_tracker->DatabaseClosed(origin_id, db_name);
std::vector<webkit_database::OriginInfo> origins;
db_tracker->GetAllOriginsInfo(&origins);
EXPECT_EQ(1U, origins.size());
EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
base::FilePath lso_dir_path =
profile_->GetPath().AppendASCII("Local Storage");
base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
.AddExtension(FILE_PATH_LITERAL(".localstorage"));
EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
EXPECT_EQ(0, base::WriteFile(lso_file_path, NULL, 0));
EXPECT_TRUE(base::PathExists(lso_file_path));
IndexedDBContext* idb_context =
BrowserContext::GetDefaultStoragePartition(profile_.get())->
GetIndexedDBContext();
idb_context->SetTaskRunnerForTesting(
base::MessageLoop::current()->message_loop_proxy().get());
base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
EXPECT_TRUE(base::CreateDirectory(idb_path));
EXPECT_TRUE(base::DirectoryExists(idb_path));
service_->UninstallExtension(good_crx, false, NULL);
base::RunLoop().RunUntilIdle();
cookie_monster->GetAllCookiesForURLAsync(
ext_url,
base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
base::Unretained(&callback)));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0U, callback.list_.size());
origins.clear();
db_tracker->GetAllOriginsInfo(&origins);
EXPECT_EQ(0U, origins.size());
EXPECT_FALSE(base::PathExists(lso_file_path));
EXPECT_FALSE(base::DirectoryExists(idb_path));
}
TEST_F(ExtensionServiceTest, ClearAppData) {
InitializeEmptyExtensionService();
ExtensionCookieCallback callback;
int pref_count = 0;
const Extension* extension =
PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
ValidatePrefKeyCount(++pref_count);
ASSERT_EQ(1u, registry_->enabled_extensions().size());
const std::string id1 = extension->id();
EXPECT_TRUE(extension->HasAPIPermission(
APIPermission::kUnlimitedStorage));
const GURL origin1(
extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
IsStorageUnlimited(origin1));
std::string origin_id = webkit_database::GetIdentifierFromOrigin(origin1);
extension = PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
ValidatePrefKeyCount(++pref_count);
ASSERT_EQ(2u, registry_->enabled_extensions().size());
const std::string id2 = extension->id();
EXPECT_TRUE(extension->HasAPIPermission(
APIPermission::kUnlimitedStorage));
EXPECT_TRUE(extension->web_extent().MatchesURL(
extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
const GURL origin2(
extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
EXPECT_EQ(origin1, origin2);
EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
IsStorageUnlimited(origin2));
net::CookieMonster* cookie_monster =
profile_->GetRequestContext()->GetURLRequestContext()->
cookie_store()->GetCookieMonster();
ASSERT_TRUE(cookie_monster);
net::CookieOptions options;
cookie_monster->SetCookieWithOptionsAsync(
origin1, "dummy=value", options,
base::Bind(&ExtensionCookieCallback::SetCookieCallback,
base::Unretained(&callback)));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(callback.result_);
cookie_monster->GetAllCookiesForURLAsync(
origin1,
base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
base::Unretained(&callback)));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1U, callback.list_.size());
webkit_database::DatabaseTracker* db_tracker =
BrowserContext::GetDefaultStoragePartition(profile_.get())->
GetDatabaseTracker();
base::string16 db_name = base::UTF8ToUTF16("db");
base::string16 description = base::UTF8ToUTF16("db_description");
int64 size;
db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
db_tracker->DatabaseClosed(origin_id, db_name);
std::vector<webkit_database::OriginInfo> origins;
db_tracker->GetAllOriginsInfo(&origins);
EXPECT_EQ(1U, origins.size());
EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
base::FilePath lso_dir_path =
profile_->GetPath().AppendASCII("Local Storage");
base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
.AddExtension(FILE_PATH_LITERAL(".localstorage"));
EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
EXPECT_EQ(0, base::WriteFile(lso_file_path, NULL, 0));
EXPECT_TRUE(base::PathExists(lso_file_path));
IndexedDBContext* idb_context =
BrowserContext::GetDefaultStoragePartition(profile_.get())->
GetIndexedDBContext();
idb_context->SetTaskRunnerForTesting(
base::MessageLoop::current()->message_loop_proxy().get());
base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
EXPECT_TRUE(base::CreateDirectory(idb_path));
EXPECT_TRUE(base::DirectoryExists(idb_path));
UninstallExtension(id1, false);
EXPECT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
IsStorageUnlimited(origin1));
cookie_monster->GetAllCookiesForURLAsync(
origin1,
base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
base::Unretained(&callback)));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1U, callback.list_.size());
UninstallExtension(id2, false);
EXPECT_EQ(0u, registry_->enabled_extensions().size());
EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
IsStorageUnlimited(origin1));
cookie_monster->GetAllCookiesForURLAsync(
origin1,
base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
base::Unretained(&callback)));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0U, callback.list_.size());
origins.clear();
db_tracker->GetAllOriginsInfo(&origins);
EXPECT_EQ(0U, origins.size());
EXPECT_FALSE(base::PathExists(lso_file_path));
EXPECT_FALSE(base::DirectoryExists(idb_path));
}
TEST_F(ExtensionServiceTest, DISABLED_LoadExtension) {
InitializeEmptyExtensionService();
base::FilePath ext1 = data_dir_
.AppendASCII("good")
.AppendASCII("Extensions")
.AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
.AppendASCII("1.0.0.0");
extensions::UnpackedInstaller::Create(service_)->Load(ext1);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0u, GetErrors().size());
ASSERT_EQ(1u, loaded_.size());
EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
EXPECT_EQ(1u, registry_->enabled_extensions().size());
ValidatePrefKeyCount(1);
base::FilePath no_manifest = data_dir_
.AppendASCII("bad")
.AppendASCII("cccccccccccccccccccccccccccccccc")
.AppendASCII("1");
extensions::UnpackedInstaller::Create(service_)->Load(no_manifest);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, GetErrors().size());
ASSERT_EQ(1u, loaded_.size());
EXPECT_EQ(1u, registry_->enabled_extensions().size());
std::string id = loaded_[0]->id();
EXPECT_FALSE(unloaded_id_.length());
service_->UninstallExtension(id, false, NULL);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(id, unloaded_id_);
ASSERT_EQ(0u, loaded_.size());
EXPECT_EQ(0u, registry_->enabled_extensions().size());
}
TEST_F(ExtensionServiceTest, GenerateID) {
InitializeEmptyExtensionService();
base::FilePath no_id_ext = data_dir_.AppendASCII("no_id");
extensions::UnpackedInstaller::Create(service_)->Load(no_id_ext);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0u, GetErrors().size());
ASSERT_EQ(1u, loaded_.size());
ASSERT_TRUE(Extension::IdIsValid(loaded_[0]->id()));
EXPECT_EQ(loaded_[0]->location(), Manifest::UNPACKED);
ValidatePrefKeyCount(1);
std::string previous_id = loaded_[0]->id();
extensions::UnpackedInstaller::Create(service_)->Load(no_id_ext);
base::RunLoop().RunUntilIdle();
ASSERT_EQ(1u, loaded_.size());
ASSERT_EQ(previous_id, loaded_[0]->id());
}
TEST_F(ExtensionServiceTest, UnpackedValidatesLocales) {
InitializeEmptyExtensionService();
base::FilePath bad_locale = data_dir_.AppendASCII("unpacked").
AppendASCII("bad_messages_file");
extensions::UnpackedInstaller::Create(service_)->Load(bad_locale);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, GetErrors().size());
base::FilePath ms_messages_file = bad_locale.AppendASCII("_locales")
.AppendASCII("ms")
.AppendASCII("messages.json");
EXPECT_THAT(base::UTF16ToUTF8(GetErrors()[0]), testing::AllOf(
testing::HasSubstr(
base::UTF16ToUTF8(ms_messages_file.LossyDisplayName())),
testing::HasSubstr("Dictionary keys must be quoted.")));
ASSERT_EQ(0u, loaded_.size());
}
void ExtensionServiceTest::TestExternalProvider(
MockExtensionProvider* provider, Manifest::Location location) {
service_->Init();
ASSERT_EQ(0u, loaded_.size());
provider->set_visit_count(0);
base::FilePath source_path = data_dir_.AppendASCII("good.crx");
provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
service_->CheckForExternalUpdates();
observer.Wait();
ASSERT_EQ(0u, GetErrors().size());
ASSERT_EQ(1u, loaded_.size());
ASSERT_EQ(location, loaded_[0]->location());
ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
ValidatePrefKeyCount(1);
ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
ValidateIntegerPref(good_crx, "location", location);
loaded_.clear();
service_->ReloadExtensionsForTest();
base::RunLoop().RunUntilIdle();
ASSERT_EQ(0u, GetErrors().size());
ASSERT_EQ(1u, loaded_.size());
ValidatePrefKeyCount(1);
ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
ValidateIntegerPref(good_crx, "location", location);
source_path = source_path.DirName().AppendASCII("good2.crx");
provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
loaded_.clear();
content::WindowedNotificationObserver observer_2(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
service_->CheckForExternalUpdates();
observer_2.Wait();
ASSERT_EQ(0u, GetErrors().size());
ASSERT_EQ(1u, loaded_.size());
ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
ValidatePrefKeyCount(1);
ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
ValidateIntegerPref(good_crx, "location", location);
std::string id = loaded_[0]->id();
bool no_uninstall =
management_policy_->MustRemainEnabled(loaded_[0].get(), NULL);
service_->UninstallExtension(id, false, NULL);
base::RunLoop().RunUntilIdle();
base::FilePath install_path = extensions_install_dir_.AppendASCII(id);
if (no_uninstall) {
ASSERT_TRUE(base::PathExists(install_path));
} else {
ASSERT_FALSE(base::PathExists(install_path));
loaded_.clear();
service_->CheckForExternalUpdates();
base::RunLoop().RunUntilIdle();
ASSERT_EQ(0u, loaded_.size());
ValidatePrefKeyCount(1);
ValidateIntegerPref(good_crx, "state",
Extension::EXTERNAL_EXTENSION_UNINSTALLED);
ValidateIntegerPref(good_crx, "location", location);
SetPrefInteg(good_crx, "state", Extension::ENABLED);
loaded_.clear();
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
service_->CheckForExternalUpdates();
observer.Wait();
ASSERT_EQ(1u, loaded_.size());
}
ValidatePrefKeyCount(1);
ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
ValidateIntegerPref(good_crx, "location", location);
if (management_policy_->MustRemainEnabled(loaded_[0].get(), NULL)) {
EXPECT_EQ(2, provider->visit_count());
} else {
provider->RemoveExtension(good_crx);
loaded_.clear();
service_->OnExternalProviderReady(provider);
base::RunLoop().RunUntilIdle();
ASSERT_EQ(0u, loaded_.size());
ValidatePrefKeyCount(0);
ASSERT_FALSE(base::PathExists(install_path));
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
service_->CheckForExternalUpdates();
observer.Wait();
ASSERT_EQ(1u, loaded_.size());
ASSERT_EQ(0u, GetErrors().size());
loaded_.clear();
service_->UninstallExtension(id, false, NULL);
base::RunLoop().RunUntilIdle();
ASSERT_EQ(0u, loaded_.size());
provider->RemoveExtension(good_crx);
loaded_.clear();
extensions::InstalledLoader(service_).LoadAllExtensions();
base::RunLoop().RunUntilIdle();
ASSERT_EQ(0u, loaded_.size());
ValidatePrefKeyCount(1);
EXPECT_EQ(5, provider->visit_count());
}
}
#if defined(OS_WIN)
TEST_F(ExtensionServiceTest, ExternalInstallRegistry) {
InitializeEmptyExtensionService();
set_extensions_enabled(false);
MockExtensionProvider* reg_provider =
new MockExtensionProvider(service_, Manifest::EXTERNAL_REGISTRY);
AddMockExternalProvider(reg_provider);
TestExternalProvider(reg_provider, Manifest::EXTERNAL_REGISTRY);
}
#endif
TEST_F(ExtensionServiceTest, ExternalInstallPref) {
InitializeEmptyExtensionService();
MockExtensionProvider* pref_provider =
new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
AddMockExternalProvider(pref_provider);
TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF);
}
TEST_F(ExtensionServiceTest, ExternalInstallPrefUpdateUrl) {
InitializeEmptyExtensionService();
set_extensions_enabled(false);
MockExtensionProvider* pref_provider =
new MockExtensionProvider(service_,
Manifest::EXTERNAL_PREF_DOWNLOAD);
AddMockExternalProvider(pref_provider);
TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF_DOWNLOAD);
}
TEST_F(ExtensionServiceTest, ExternalInstallPolicyUpdateUrl) {
InitializeEmptyExtensionService();
set_extensions_enabled(false);
MockExtensionProvider* pref_provider =
new MockExtensionProvider(service_,
Manifest::EXTERNAL_POLICY_DOWNLOAD);
AddMockExternalProvider(pref_provider);
TestExternalProvider(pref_provider, Manifest::EXTERNAL_POLICY_DOWNLOAD);
}
TEST_F(ExtensionServiceTest, ExternalUninstall) {
base::FilePath source_install_dir = data_dir_
.AppendASCII("good")
.AppendASCII("Extensions");
base::FilePath pref_path = source_install_dir
.DirName()
.AppendASCII("PreferencesExternal");
InitializeInstalledExtensionService(pref_path, source_install_dir);
set_extensions_enabled(false);
service_->Init();
ASSERT_EQ(0u, GetErrors().size());
ASSERT_EQ(0u, loaded_.size());
set_extensions_enabled(true);
service_->ReloadExtensionsForTest();
base::RunLoop().RunUntilIdle();
ASSERT_EQ(0u, GetErrors().size());
ASSERT_EQ(0u, loaded_.size());
}
TEST_F(ExtensionServiceTest, MultipleExternalUpdateCheck) {
InitializeEmptyExtensionService();
MockExtensionProvider* provider =
new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
AddMockExternalProvider(provider);
service_->Init();
ASSERT_EQ(0u, loaded_.size());
provider->set_visit_count(0);
service_->CheckForExternalUpdates();
service_->CheckForExternalUpdates();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(2, provider->visit_count());
EXPECT_EQ(0u, GetErrors().size());
EXPECT_EQ(0u, loaded_.size());
base::FilePath source_path = data_dir_.AppendASCII("good.crx");
provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
provider->set_visit_count(0);
service_->CheckForExternalUpdates();
service_->CheckForExternalUpdates();
observer.Wait();
EXPECT_EQ(2, provider->visit_count());
ASSERT_EQ(0u, GetErrors().size());
ASSERT_EQ(1u, loaded_.size());
ASSERT_EQ(Manifest::EXTERNAL_PREF, loaded_[0]->location());
ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
ValidatePrefKeyCount(1);
ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
ValidateIntegerPref(good_crx, "location", Manifest::EXTERNAL_PREF);
provider->RemoveExtension(good_crx);
provider->set_visit_count(0);
service_->CheckForExternalUpdates();
service_->CheckForExternalUpdates();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(2, provider->visit_count());
EXPECT_EQ(0u, GetErrors().size());
EXPECT_EQ(0u, loaded_.size());
}
TEST_F(ExtensionServiceTest, ExternalPrefProvider) {
InitializeEmptyExtensionService();
base::FilePath base_path(FILE_PATH_LITERAL("//base/path"));
ASSERT_TRUE(base_path.IsAbsolute());
MockProviderVisitor visitor(base_path);
std::string json_data =
"{"
" \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
" \"external_crx\": \"RandomExtension.crx\","
" \"external_version\": \"1.0\""
" },"
" \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
" \"external_crx\": \"RandomExtension2.crx\","
" \"external_version\": \"2.0\""
" },"
" \"cccccccccccccccccccccccccccccccc\": {"
" \"external_update_url\": \"http:\\\\foo.com/update\","
" \"install_parameter\": \"id\""
" }"
"}";
EXPECT_EQ(3, visitor.Visit(json_data));
json_data =
"{"
" \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
" \"external_version\": \"1.0\""
" },"
" \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
" \"external_crx\": \"RandomExtension.crx\""
" },"
" \"cccccccccccccccccccccccccccccccc\": {"
" \"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
" \"external_version\": \"2.0\""
" },"
" \"dddddddddddddddddddddddddddddddd\": {"
" \"external_crx\": \"RandomExtension2.crx\","
" \"external_version\": \"2.0\","
" \"external_update_url\": \"http:\\\\foo.com/update\""
" },"
" \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
" },"
" \"ffffffffffffffffffffffffffffffff\": {"
" \"external_update_url\": \"This string is not a valid URL\""
" },"
" \"gggggggggggggggggggggggggggggggg\": {"
" \"external_crx\": \"RandomExtension3.crx\","
" \"external_version\": \"This is not a valid version!\""
" },"
" \"This is not a valid id!\": {},"
" \"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\": true,"
" \"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\": {"
" \"external_crx\": \"RandomExtension4.crx\","
" \"external_version\": 1.0"
" },"
" \"pppppppppppppppppppppppppppppppp\": {"
" \"external_crx\": \"RandomValidExtension.crx\","
" \"external_version\": \"1.0\""
" }"
"}";
EXPECT_EQ(1, visitor.Visit(json_data));
base::FilePath empty;
MockProviderVisitor visitor_no_relative_paths(empty);
json_data =
"{"
" \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
" \"external_crx\": \"//RandomExtension1.crx\","
" \"external_version\": \"3.0\""
" },"
" \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
" \"external_crx\": \"//path/to/RandomExtension2.crx\","
" \"external_version\": \"3.0\""
" }"
"}";
EXPECT_EQ(2, visitor_no_relative_paths.Visit(json_data));
json_data =
"{"
" \"cccccccccccccccccccccccccccccccc\": {"
" \"external_crx\": \"RandomExtension2.crx\","
" \"external_version\": \"3.0\""
" }"
"}";
EXPECT_EQ(0, visitor_no_relative_paths.Visit(json_data));
json_data =
"{"
" \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
" \"external_crx\": \"RandomExtension.crx\","
" \"external_version\": \"1.0\","
" \"supported_locales\": [ \"en\" ]"
" },"
" \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
" \"external_crx\": \"RandomExtension2.crx\","
" \"external_version\": \"2.0\","
" \"supported_locales\": [ \"en-GB\" ]"
" },"
" \"cccccccccccccccccccccccccccccccc\": {"
" \"external_crx\": \"RandomExtension2.crx\","
" \"external_version\": \"3.0\","
" \"supported_locales\": [ \"en_US\", \"fr\" ]"
" }"
"}";
{
ScopedBrowserLocale guard("en-US");
EXPECT_EQ(2, visitor.Visit(json_data));
}
json_data =
"{"
" \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
" \"external_crx\": \"RandomExtension.crx\","
" \"external_version\": \"1.0\","
" \"keep_if_present\": true"
" }"
"}";
{
EXPECT_EQ(0, visitor.Visit(json_data));
}
MockProviderVisitor from_bookmark_visitor(
base_path, Extension::FROM_BOOKMARK);
json_data =
"{"
" \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
" \"external_crx\": \"RandomExtension.crx\","
" \"external_version\": \"1.0\","
" \"is_bookmark_app\": true"
" }"
"}";
EXPECT_EQ(1, from_bookmark_visitor.Visit(json_data));
MockProviderVisitor from_webstore_visitor(
base_path, Extension::FROM_WEBSTORE);
json_data =
"{"
" \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
" \"external_crx\": \"RandomExtension.crx\","
" \"external_version\": \"1.0\","
" \"is_from_webstore\": true"
" }"
"}";
EXPECT_EQ(1, from_webstore_visitor.Visit(json_data));
}
TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) {
extension_l10n_util::ScopedLocaleForTest testLocale("en");
base::FilePath source_install_dir = data_dir_
.AppendASCII("l10n");
base::FilePath pref_path =
source_install_dir.Append(chrome::kPreferencesFilename);
InitializeInstalledExtensionService(pref_path, source_install_dir);
service_->Init();
ASSERT_EQ(3u, loaded_.size());
ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en");
ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en");
EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale));
EXPECT_EQ("My name is simple.", loaded_[0]->name());
EXPECT_EQ("My name is simple.", loaded_[1]->name());
EXPECT_EQ("no l10n", loaded_[2]->name());
}
class ExtensionsReadyRecorder : public content::NotificationObserver {
public:
ExtensionsReadyRecorder() : ready_(false) {
registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY,
content::NotificationService::AllSources());
}
void set_ready(bool value) { ready_ = value; }
bool ready() { return ready_; }
private:
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE {
switch (type) {
case chrome::NOTIFICATION_EXTENSIONS_READY:
ready_ = true;
break;
default:
NOTREACHED();
}
}
content::NotificationRegistrar registrar_;
bool ready_;
};
TEST(ExtensionServiceTestSimple, Enabledness) {
base::ShadowingAtExitManager at_exit_manager;
#if defined(ENABLE_PLUGINS)
content::PluginService::GetInstance()->Init();
content::PluginService::GetInstance()->DisablePluginsDiscoveryForTesting();
#endif
ExtensionErrorReporter::Init(false);
ExtensionsReadyRecorder recorder;
scoped_ptr<TestingProfile> profile(new TestingProfile());
content::TestBrowserThreadBundle thread_bundle_;
#if defined OS_CHROMEOS
chromeos::ScopedTestDeviceSettingsService device_settings_service;
chromeos::ScopedTestCrosSettings cros_settings;
scoped_ptr<chromeos::ScopedTestUserManager> user_manager(
new chromeos::ScopedTestUserManager);
#endif
scoped_ptr<CommandLine> command_line;
base::FilePath install_dir = profile->GetPath()
.AppendASCII(extensions::kInstallDirectoryName);
command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
ExtensionService* service = static_cast<extensions::TestExtensionSystem*>(
ExtensionSystem::Get(profile.get()))->
CreateExtensionService(
command_line.get(),
install_dir,
false);
EXPECT_TRUE(service->extensions_enabled());
service->Init();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(recorder.ready());
#if defined OS_CHROMEOS
user_manager.reset();
#endif
recorder.set_ready(false);
profile.reset(new TestingProfile());
command_line->AppendSwitch(switches::kDisableExtensions);
service = static_cast<extensions::TestExtensionSystem*>(
ExtensionSystem::Get(profile.get()))->
CreateExtensionService(
command_line.get(),
install_dir,
false);
EXPECT_FALSE(service->extensions_enabled());
service->Init();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(recorder.ready());
recorder.set_ready(false);
profile.reset(new TestingProfile());
profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
service = static_cast<extensions::TestExtensionSystem*>(
ExtensionSystem::Get(profile.get()))->
CreateExtensionService(
command_line.get(),
install_dir,
false);
EXPECT_FALSE(service->extensions_enabled());
service->Init();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(recorder.ready());
recorder.set_ready(false);
profile.reset(new TestingProfile());
profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
service = static_cast<extensions::TestExtensionSystem*>(
ExtensionSystem::Get(profile.get()))->
CreateExtensionService(
command_line.get(),
install_dir,
false);
EXPECT_FALSE(service->extensions_enabled());
service->Init();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(recorder.ready());
profile.reset();
service = NULL;
base::RunLoop().RunUntilIdle();
}
TEST_F(ExtensionServiceTest, StorageQuota) {
InitializeEmptyExtensionService();
base::FilePath extensions_path = data_dir_
.AppendASCII("storage_quota");
base::FilePath limited_quota_ext =
extensions_path.AppendASCII("limited_quota")
.AppendASCII("1.0");
base::FilePath unlimited_quota_ext =
extensions_path.AppendASCII("unlimited_quota")
.AppendASCII("1.0");
base::FilePath unlimited_quota_ext2 =
extensions_path.AppendASCII("unlimited_quota")
.AppendASCII("2.0");
extensions::UnpackedInstaller::Create(service_)->Load(limited_quota_ext);
extensions::UnpackedInstaller::Create(service_)->Load(unlimited_quota_ext);
extensions::UnpackedInstaller::Create(service_)->Load(unlimited_quota_ext2);
base::RunLoop().RunUntilIdle();
ASSERT_EQ(3u, loaded_.size());
EXPECT_TRUE(profile_.get());
EXPECT_FALSE(profile_->IsOffTheRecord());
EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
loaded_[0]->url()));
EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
loaded_[1]->url()));
EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
loaded_[2]->url()));
}
TEST_F(ExtensionServiceTest, ComponentExtensions) {
InitializeEmptyExtensionService();
set_extensions_enabled(false);
base::FilePath path = data_dir_
.AppendASCII("good")
.AppendASCII("Extensions")
.AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
.AppendASCII("1.0.0.0");
std::string manifest;
ASSERT_TRUE(base::ReadFileToString(
path.Append(extensions::kManifestFilename), &manifest));
service_->component_loader()->Add(manifest, path);
service_->Init();
EXPECT_EQ(0u, GetErrors().size());
ASSERT_EQ(1u, loaded_.size());
EXPECT_EQ(Manifest::COMPONENT, loaded_[0]->location());
EXPECT_EQ(1u, registry_->enabled_extensions().size());
ValidatePrefKeyCount(1);
std::string extension_id = (*registry_->enabled_extensions().begin())->id();
loaded_.clear();
service_->ReloadExtensionsForTest();
ASSERT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_EQ(extension_id, (*registry_->enabled_extensions().begin())->id());
}
TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledComponent) {
InitializeEmptyExtensionService();
InitializeExtensionSyncService();
bool flare_was_called = false;
syncer::ModelType triggered_type(syncer::UNSPECIFIED);
base::WeakPtrFactory<ExtensionServiceTest> factory(this);
extension_sync_service_->SetSyncStartFlare(
base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
factory.GetWeakPtr(),
&flare_was_called,
&triggered_type));
std::string manifest;
ASSERT_TRUE(base::ReadFileToString(
good0_path().Append(extensions::kManifestFilename), &manifest));
service_->component_loader()->Add(manifest, good0_path());
ASSERT_FALSE(service_->is_ready());
service_->Init();
ASSERT_TRUE(service_->is_ready());
EXPECT_FALSE(flare_was_called);
ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
}
TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledNormal) {
InitializeGoodInstalledExtensionService();
InitializeExtensionSyncService();
bool flare_was_called = false;
syncer::ModelType triggered_type(syncer::UNSPECIFIED);
base::WeakPtrFactory<ExtensionServiceTest> factory(this);
extension_sync_service_->SetSyncStartFlare(
base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
factory.GetWeakPtr(),
&flare_was_called,
&triggered_type));
ASSERT_FALSE(service_->is_ready());
service_->Init();
ASSERT_EQ(3u, loaded_.size());
ASSERT_TRUE(service_->is_ready());
EXPECT_FALSE(flare_was_called);
ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
}
TEST_F(ExtensionServiceTest, DeferredSyncStartupOnInstall) {
InitializeEmptyExtensionService();
InitializeExtensionSyncService();
service_->Init();
ASSERT_TRUE(service_->is_ready());
bool flare_was_called = false;
syncer::ModelType triggered_type(syncer::UNSPECIFIED);
base::WeakPtrFactory<ExtensionServiceTest> factory(this);
extension_sync_service_->SetSyncStartFlare(
base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
factory.GetWeakPtr(),
&flare_was_called,
&triggered_type));
base::FilePath path = data_dir_.AppendASCII("good.crx");
InstallCRX(path, INSTALL_NEW);
EXPECT_TRUE(flare_was_called);
EXPECT_EQ(syncer::EXTENSIONS, triggered_type);
flare_was_called = false;
triggered_type = syncer::UNSPECIFIED;
extension_sync_service_->MergeDataAndStartSyncing(
syncer::EXTENSIONS,
syncer::SyncDataList(),
scoped_ptr<syncer::SyncChangeProcessor>(
new syncer::FakeSyncChangeProcessor),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
path = data_dir_.AppendASCII("page_action.crx");
InstallCRX(path, INSTALL_NEW);
EXPECT_FALSE(flare_was_called);
ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
}
TEST_F(ExtensionServiceTest, DisableExtensionFromSync) {
base::FilePath source_install_dir = data_dir_
.AppendASCII("good")
.AppendASCII("Extensions");
base::FilePath pref_path =
source_install_dir.DirName().Append(chrome::kPreferencesFilename);
InitializeInstalledExtensionService(pref_path, source_install_dir);
InitializeExtensionSyncService();
ProfileSyncService* sync_service =
ProfileSyncServiceFactory::GetForProfile(profile_.get());
sync_service->SetSyncSetupCompleted();
service_->Init();
ASSERT_TRUE(service_->is_ready());
ASSERT_EQ(3u, loaded_.size());
const Extension* extension = service_->GetExtensionById(good0, true);
ASSERT_TRUE(extension);
ASSERT_TRUE(service_->IsExtensionEnabled(good0));
extensions::ExtensionSyncData disable_good_crx(*extension, false, false);
syncer::SyncDataList sync_data;
sync_data.push_back(disable_good_crx.GetSyncData());
extension_sync_service_->MergeDataAndStartSyncing(
syncer::EXTENSIONS,
sync_data,
scoped_ptr<syncer::SyncChangeProcessor>(
new syncer::FakeSyncChangeProcessor),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
ASSERT_FALSE(service_->IsExtensionEnabled(good0));
}
TEST_F(ExtensionServiceTest, DontDisableExtensionWithPendingEnableFromSync) {
base::FilePath source_install_dir = data_dir_
.AppendASCII("good")
.AppendASCII("Extensions");
base::FilePath pref_path =
source_install_dir.DirName().Append(chrome::kPreferencesFilename);
InitializeInstalledExtensionService(pref_path, source_install_dir);
InitializeExtensionSyncService();
ProfileSyncService* sync_service =
ProfileSyncServiceFactory::GetForProfile(profile_.get());
sync_service->SetSyncSetupCompleted();
service_->Init();
ASSERT_TRUE(service_->is_ready());
ASSERT_EQ(3u, loaded_.size());
const Extension* extension = service_->GetExtensionById(good0, true);
ASSERT_TRUE(service_->IsExtensionEnabled(good0));
service_->DisableExtension(good0, Extension::DISABLE_USER_ACTION);
ASSERT_FALSE(service_->IsExtensionEnabled(good0));
service_->EnableExtension(good0);
ASSERT_TRUE(service_->IsExtensionEnabled(good0));
extensions::ExtensionSyncData disable_good_crx(*extension, false, false);
syncer::SyncDataList sync_data;
sync_data.push_back(disable_good_crx.GetSyncData());
extension_sync_service_->MergeDataAndStartSyncing(
syncer::EXTENSIONS,
sync_data,
scoped_ptr<syncer::SyncChangeProcessor>(
new syncer::FakeSyncChangeProcessor),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
ASSERT_TRUE(service_->IsExtensionEnabled(good0));
}
TEST_F(ExtensionServiceTest, GetSyncData) {
InitializeEmptyExtensionService();
InitializeExtensionSyncService();
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
const Extension* extension = service_->GetInstalledExtension(good_crx);
ASSERT_TRUE(extension);
extension_sync_service_->MergeDataAndStartSyncing(
syncer::EXTENSIONS,
syncer::SyncDataList(),
scoped_ptr<syncer::SyncChangeProcessor>(
new syncer::FakeSyncChangeProcessor),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
syncer::EXTENSIONS);
ASSERT_EQ(list.size(), 1U);
extensions::ExtensionSyncData data(list[0]);
EXPECT_EQ(extension->id(), data.id());
EXPECT_FALSE(data.uninstalled());
EXPECT_EQ(service_->IsExtensionEnabled(good_crx), data.enabled());
EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile_.get()),
data.incognito_enabled());
EXPECT_TRUE(data.version().Equals(*extension->version()));
EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
data.update_url());
EXPECT_EQ(extension->name(), data.name());
}
TEST_F(ExtensionServiceTest, GetSyncDataTerminated) {
InitializeEmptyExtensionService();
InitializeExtensionSyncService();
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
TerminateExtension(good_crx);
const Extension* extension = service_->GetInstalledExtension(good_crx);
ASSERT_TRUE(extension);
syncer::FakeSyncChangeProcessor processor;
extension_sync_service_->MergeDataAndStartSyncing(
syncer::EXTENSIONS,
syncer::SyncDataList(),
scoped_ptr<syncer::SyncChangeProcessor>(
new syncer::FakeSyncChangeProcessor),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
syncer::EXTENSIONS);
ASSERT_EQ(list.size(), 1U);
extensions::ExtensionSyncData data(list[0]);
EXPECT_EQ(extension->id(), data.id());
EXPECT_FALSE(data.uninstalled());
EXPECT_EQ(service_->IsExtensionEnabled(good_crx), data.enabled());
EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile_.get()),
data.incognito_enabled());
EXPECT_TRUE(data.version().Equals(*extension->version()));
EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
data.update_url());
EXPECT_EQ(extension->name(), data.name());
}
TEST_F(ExtensionServiceTest, GetSyncDataFilter) {
InitializeEmptyExtensionService();
InitializeExtensionSyncService();
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
const Extension* extension = service_->GetInstalledExtension(good_crx);
ASSERT_TRUE(extension);
syncer::FakeSyncChangeProcessor processor;
extension_sync_service_->MergeDataAndStartSyncing(
syncer::APPS,
syncer::SyncDataList(),
scoped_ptr<syncer::SyncChangeProcessor>(
new syncer::FakeSyncChangeProcessor),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
syncer::EXTENSIONS);
ASSERT_EQ(list.size(), 0U);
}
TEST_F(ExtensionServiceTest, GetSyncExtensionDataUserSettings) {
InitializeEmptyExtensionService();
InitializeProcessManager();
InitializeExtensionSyncService();
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
const Extension* extension = service_->GetInstalledExtension(good_crx);
ASSERT_TRUE(extension);
syncer::FakeSyncChangeProcessor processor;
extension_sync_service_->MergeDataAndStartSyncing(
syncer::EXTENSIONS,
syncer::SyncDataList(),
scoped_ptr<syncer::SyncChangeProcessor>(
new syncer::FakeSyncChangeProcessor),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
{
syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
syncer::EXTENSIONS);
ASSERT_EQ(list.size(), 1U);
extensions::ExtensionSyncData data(list[0]);
EXPECT_TRUE(data.enabled());
EXPECT_FALSE(data.incognito_enabled());
}
service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
{
syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
syncer::EXTENSIONS);
ASSERT_EQ(list.size(), 1U);
extensions::ExtensionSyncData data(list[0]);
EXPECT_FALSE(data.enabled());
EXPECT_FALSE(data.incognito_enabled());
}
extensions::util::SetIsIncognitoEnabled(good_crx, profile_.get(), true);
{
syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
syncer::EXTENSIONS);
ASSERT_EQ(list.size(), 1U);
extensions::ExtensionSyncData data(list[0]);
EXPECT_FALSE(data.enabled());
EXPECT_TRUE(data.incognito_enabled());
}
service_->EnableExtension(good_crx);
{
syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
syncer::EXTENSIONS);
ASSERT_EQ(list.size(), 1U);
extensions::ExtensionSyncData data(list[0]);
EXPECT_TRUE(data.enabled());
EXPECT_TRUE(data.incognito_enabled());
}
}
TEST_F(ExtensionServiceTest, SyncForUninstalledExternalExtension) {
InitializeEmptyExtensionService();
InitializeExtensionSyncService();
InstallCRXWithLocation(data_dir_.AppendASCII("good.crx"),
Manifest::EXTERNAL_PREF, INSTALL_NEW);
const Extension* extension = service_->GetInstalledExtension(good_crx);
ASSERT_TRUE(extension);
syncer::FakeSyncChangeProcessor processor;
extension_sync_service_->MergeDataAndStartSyncing(
syncer::EXTENSIONS,
syncer::SyncDataList(),
scoped_ptr<syncer::SyncChangeProcessor>(
new syncer::FakeSyncChangeProcessor),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
UninstallExtension(good_crx, false);
EXPECT_TRUE(ExtensionPrefs::Get(profile_.get())
->IsExternalExtensionUninstalled(good_crx));
sync_pb::EntitySpecifics specifics;
sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
sync_pb::ExtensionSpecifics* extension_specifics =
app_specifics->mutable_extension();
extension_specifics->set_id(good_crx);
extension_specifics->set_version("1.0");
extension_specifics->set_enabled(true);
syncer::SyncData sync_data =
syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
syncer::SyncChange sync_change(FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
sync_data);
syncer::SyncChangeList list(1);
list[0] = sync_change;
extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
EXPECT_TRUE(ExtensionPrefs::Get(profile_.get())
->IsExternalExtensionUninstalled(good_crx));
}
TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettings) {
InitializeEmptyExtensionService();
InitializeExtensionSyncService();
const Extension* app =
PackAndInstallCRX(data_dir_.AppendASCII("app"), INSTALL_NEW);
ASSERT_TRUE(app);
ASSERT_TRUE(app->is_app());
syncer::FakeSyncChangeProcessor processor;
extension_sync_service_->MergeDataAndStartSyncing(
syncer::APPS,
syncer::SyncDataList(),
scoped_ptr<syncer::SyncChangeProcessor>(
new syncer::FakeSyncChangeProcessor),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
syncer::StringOrdinal initial_ordinal =
syncer::StringOrdinal::CreateInitialOrdinal();
{
syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
syncer::APPS);
ASSERT_EQ(list.size(), 1U);
extensions::AppSyncData app_sync_data(list[0]);
EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.app_launch_ordinal()));
EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.page_ordinal()));
}
AppSorting* sorting = ExtensionPrefs::Get(profile_.get())->app_sorting();
sorting->SetAppLaunchOrdinal(app->id(), initial_ordinal.CreateAfter());
{
syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
syncer::APPS);
ASSERT_EQ(list.size(), 1U);
extensions::AppSyncData app_sync_data(list[0]);
EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.app_launch_ordinal()));
EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.page_ordinal()));
}
sorting->SetPageOrdinal(app->id(), initial_ordinal.CreateAfter());
{
syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
syncer::APPS);
ASSERT_EQ(list.size(), 1U);
extensions::AppSyncData app_sync_data(list[0]);
EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.app_launch_ordinal()));
EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.page_ordinal()));
}
}
TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettingsOnExtensionMoved) {
InitializeEmptyExtensionService();
InitializeExtensionSyncService();
const size_t kAppCount = 3;
const Extension* apps[kAppCount];
apps[0] = PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
apps[1] = PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
apps[2] = PackAndInstallCRX(data_dir_.AppendASCII("app4"), INSTALL_NEW);
for (size_t i = 0; i < kAppCount; ++i) {
ASSERT_TRUE(apps[i]);
ASSERT_TRUE(apps[i]->is_app());
}
syncer::FakeSyncChangeProcessor processor;
extension_sync_service_->MergeDataAndStartSyncing(
syncer::APPS,
syncer::SyncDataList(),
scoped_ptr<syncer::SyncChangeProcessor>(
new syncer::FakeSyncChangeProcessor),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
ExtensionPrefs::Get(service_->GetBrowserContext())
->app_sorting()
->OnExtensionMoved(apps[0]->id(), apps[1]->id(), apps[2]->id());
{
syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
syncer::APPS);
ASSERT_EQ(list.size(), 3U);
extensions::AppSyncData data[kAppCount];
for (size_t i = 0; i < kAppCount; ++i) {
data[i] = extensions::AppSyncData(list[i]);
}
syncer::StringOrdinal app_launch_ordinals[kAppCount];
for (size_t i = 0; i < kAppCount; ++i) {
for (size_t j = 0; j < kAppCount; ++j) {
if (apps[i]->id() == data[j].id())
app_launch_ordinals[i] = data[j].app_launch_ordinal();
}
}
EXPECT_TRUE(app_launch_ordinals[1].LessThan(app_launch_ordinals[0]));
EXPECT_TRUE(app_launch_ordinals[0].LessThan(app_launch_ordinals[2]));
}
}
TEST_F(ExtensionServiceTest, GetSyncDataList) {
InitializeEmptyExtensionService();
InitializeExtensionSyncService();
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
InstallCRX(data_dir_.AppendASCII("page_action.crx"), INSTALL_NEW);
InstallCRX(data_dir_.AppendASCII("theme.crx"), INSTALL_NEW);
InstallCRX(data_dir_.AppendASCII("theme2.crx"), INSTALL_NEW);
syncer::FakeSyncChangeProcessor processor;
extension_sync_service_->MergeDataAndStartSyncing(
syncer::APPS,
syncer::SyncDataList(),
scoped_ptr<syncer::SyncChangeProcessor>(
new syncer::FakeSyncChangeProcessor),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
extension_sync_service_->MergeDataAndStartSyncing(
syncer::EXTENSIONS,
syncer::SyncDataList(),
scoped_ptr<syncer::SyncChangeProcessor>(
new syncer::FakeSyncChangeProcessor),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
service_->DisableExtension(page_action, Extension::DISABLE_USER_ACTION);
TerminateExtension(theme2_crx);
EXPECT_EQ(0u, extension_sync_service_->GetAllSyncData(syncer::APPS).size());
EXPECT_EQ(2u, extension_sync_service_->
GetAllSyncData(syncer::EXTENSIONS).size());
}
TEST_F(ExtensionServiceTest, ProcessSyncDataUninstall) {
InitializeEmptyExtensionService();
InitializeExtensionSyncService();
syncer::FakeSyncChangeProcessor processor;
extension_sync_service_->MergeDataAndStartSyncing(
syncer::EXTENSIONS,
syncer::SyncDataList(),
scoped_ptr<syncer::SyncChangeProcessor>(
new syncer::FakeSyncChangeProcessor),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
sync_pb::EntitySpecifics specifics;
sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
ext_specifics->set_id(good_crx);
ext_specifics->set_version("1.0");
syncer::SyncData sync_data =
syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
syncer::SyncChange sync_change(FROM_HERE,
syncer::SyncChange::ACTION_DELETE,
sync_data);
syncer::SyncChangeList list(1);
list[0] = sync_change;
extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
EXPECT_FALSE(service_->GetExtensionById(good_crx, true));
base::FilePath extension_path = data_dir_.AppendASCII("good.crx");
InstallCRX(extension_path, INSTALL_NEW);
EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
EXPECT_FALSE(service_->GetExtensionById(good_crx, true));
extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
EXPECT_FALSE(service_->GetExtensionById(good_crx, true));
}
TEST_F(ExtensionServiceTest, ProcessSyncDataWrongType) {
InitializeEmptyExtensionService();
InitializeExtensionSyncService();
base::FilePath extension_path = data_dir_.AppendASCII("good.crx");
InstallCRX(extension_path, INSTALL_NEW);
EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
sync_pb::EntitySpecifics specifics;
sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
sync_pb::ExtensionSpecifics* extension_specifics =
app_specifics->mutable_extension();
extension_specifics->set_id(good_crx);
extension_specifics->set_version(
service_->GetInstalledExtension(good_crx)->version()->GetString());
{
extension_specifics->set_enabled(true);
syncer::SyncData sync_data =
syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
syncer::SyncChange sync_change(FROM_HERE,
syncer::SyncChange::ACTION_DELETE,
sync_data);
syncer::SyncChangeList list(1);
list[0] = sync_change;
extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
}
{
extension_specifics->set_enabled(false);
syncer::SyncData sync_data =
syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
syncer::SyncChange sync_change(FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
sync_data);
syncer::SyncChangeList list(1);
list[0] = sync_change;
extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
}
}
TEST_F(ExtensionServiceTest, ProcessSyncDataSettings) {
InitializeEmptyExtensionService();
InitializeProcessManager();
InitializeExtensionSyncService();
syncer::FakeSyncChangeProcessor processor;
extension_sync_service_->MergeDataAndStartSyncing(
syncer::EXTENSIONS,
syncer::SyncDataList(),
scoped_ptr<syncer::SyncChangeProcessor>(
new syncer::FakeSyncChangeProcessor),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile_.get()));
sync_pb::EntitySpecifics specifics;
sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
ext_specifics->set_id(good_crx);
ext_specifics->set_version(
service_->GetInstalledExtension(good_crx)->version()->GetString());
ext_specifics->set_enabled(false);
{
syncer::SyncData sync_data =
syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
syncer::SyncChange sync_change(FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
sync_data);
syncer::SyncChangeList list(1);
list[0] = sync_change;
extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
EXPECT_FALSE(
extensions::util::IsIncognitoEnabled(good_crx, profile_.get()));
}
{
ext_specifics->set_enabled(true);
ext_specifics->set_incognito_enabled(true);
syncer::SyncData sync_data =
syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
syncer::SyncChange sync_change(FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
sync_data);
syncer::SyncChangeList list(1);
list[0] = sync_change;
extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile_.get()));
}
{
ext_specifics->set_enabled(false);
ext_specifics->set_incognito_enabled(true);
syncer::SyncData sync_data =
syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
syncer::SyncChange sync_change(FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
sync_data);
syncer::SyncChangeList list(1);
list[0] = sync_change;
extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile_.get()));
}
EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
}
TEST_F(ExtensionServiceTest, ProcessSyncDataTerminatedExtension) {
InitializeExtensionServiceWithUpdater();
InitializeExtensionSyncService();
syncer::FakeSyncChangeProcessor processor;
extension_sync_service_->MergeDataAndStartSyncing(
syncer::EXTENSIONS,
syncer::SyncDataList(),
scoped_ptr<syncer::SyncChangeProcessor>(
new syncer::FakeSyncChangeProcessor),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
TerminateExtension(good_crx);
EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile_.get()));
sync_pb::EntitySpecifics specifics;
sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
ext_specifics->set_id(good_crx);
ext_specifics->set_version(
service_->GetInstalledExtension(good_crx)->version()->GetString());
ext_specifics->set_enabled(false);
ext_specifics->set_incognito_enabled(true);
syncer::SyncData sync_data =
syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
syncer::SyncChange sync_change(FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
sync_data);
syncer::SyncChangeList list(1);
list[0] = sync_change;
extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile_.get()));
EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
}
TEST_F(ExtensionServiceTest, ProcessSyncDataVersionCheck) {
InitializeExtensionServiceWithUpdater();
InitializeExtensionSyncService();
syncer::FakeSyncChangeProcessor processor;
extension_sync_service_->MergeDataAndStartSyncing(
syncer::EXTENSIONS,
syncer::SyncDataList(),
scoped_ptr<syncer::SyncChangeProcessor>(
new syncer::FakeSyncChangeProcessor),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile_.get()));
sync_pb::EntitySpecifics specifics;
sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
ext_specifics->set_id(good_crx);
ext_specifics->set_enabled(true);
{
ext_specifics->set_version(
service_->GetInstalledExtension(good_crx)->version()->GetString());
syncer::SyncData sync_data =
syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
syncer::SyncChange sync_change(FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
sync_data);
syncer::SyncChangeList list(1);
list[0] = sync_change;
extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
EXPECT_FALSE(service_->updater()->WillCheckSoon());
}
{
ext_specifics->set_version("0.0.0.0");
syncer::SyncData sync_data =
syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
syncer::SyncChange sync_change(FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
sync_data);
syncer::SyncChangeList list(1);
list[0] = sync_change;
extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
EXPECT_FALSE(service_->updater()->WillCheckSoon());
}
{
ext_specifics->set_version("9.9.9.9");
syncer::SyncData sync_data =
syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
syncer::SyncChange sync_change(FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
sync_data);
syncer::SyncChangeList list(1);
list[0] = sync_change;
extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
EXPECT_TRUE(service_->updater()->WillCheckSoon());
}
EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
}
TEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) {
InitializeExtensionServiceWithUpdater();
InitializeExtensionSyncService();
syncer::FakeSyncChangeProcessor processor;
extension_sync_service_->MergeDataAndStartSyncing(
syncer::EXTENSIONS,
syncer::SyncDataList(),
scoped_ptr<syncer::SyncChangeProcessor>(
new syncer::FakeSyncChangeProcessor),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
sync_pb::EntitySpecifics specifics;
sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
ext_specifics->set_id(good_crx);
ext_specifics->set_enabled(false);
ext_specifics->set_incognito_enabled(true);
ext_specifics->set_update_url("http://www.google.com/");
ext_specifics->set_version("1.2.3.4");
syncer::SyncData sync_data =
syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
syncer::SyncChange sync_change(FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
sync_data);
syncer::SyncChangeList list(1);
list[0] = sync_change;
EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile_.get()));
extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
EXPECT_TRUE(service_->updater()->WillCheckSoon());
EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile_.get()));
const extensions::PendingExtensionInfo* info;
EXPECT_TRUE((info = service_->pending_extension_manager()->
GetById(good_crx)));
EXPECT_EQ(ext_specifics->update_url(), info->update_url().spec());
EXPECT_TRUE(info->is_from_sync());
EXPECT_TRUE(info->install_silently());
EXPECT_EQ(Manifest::INTERNAL, info->install_source());
}
TEST_F(ExtensionServiceTest, InstallPriorityExternalUpdateUrl) {
InitializeEmptyExtensionService();
base::FilePath path = data_dir_.AppendASCII("good.crx");
InstallCRX(path, INSTALL_NEW);
ValidatePrefKeyCount(1u);
ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
extensions::PendingExtensionManager* pending =
service_->pending_extension_manager();
EXPECT_FALSE(pending->IsIdPending(kGoodId));
EXPECT_FALSE(service_->OnExternalExtensionUpdateUrlFound(kGoodId,
std::string(),
GURL(kGoodUpdateURL),
Manifest::INTERNAL,
Extension::NO_FLAGS,
false));
EXPECT_FALSE(pending->IsIdPending(kGoodId));
EXPECT_TRUE(service_->OnExternalExtensionUpdateUrlFound(
kGoodId,
std::string(),
GURL(kGoodUpdateURL),
Manifest::EXTERNAL_POLICY_DOWNLOAD,
Extension::NO_FLAGS,
false));
EXPECT_TRUE(pending->IsIdPending(kGoodId));
EXPECT_FALSE(service_->OnExternalExtensionUpdateUrlFound(
kGoodId,
std::string(),
GURL(kGoodUpdateURL),
Manifest::EXTERNAL_PREF_DOWNLOAD,
Extension::NO_FLAGS,
false));
EXPECT_TRUE(pending->IsIdPending(kGoodId));
pending->Remove(kGoodId);
EXPECT_FALSE(service_->OnExternalExtensionUpdateUrlFound(kGoodId,
std::string(),
GURL(kGoodUpdateURL),
Manifest::INTERNAL,
Extension::NO_FLAGS,
false));
EXPECT_FALSE(pending->IsIdPending(kGoodId));
}
TEST_F(ExtensionServiceTest, InstallPriorityExternalLocalFile) {
Version older_version("0.1.0.0");
Version newer_version("2.0.0.0");
const base::FilePath kInvalidPathToCrx = base::FilePath();
const int kCreationFlags = 0;
const bool kDontMarkAcknowledged = false;
InitializeEmptyExtensionService();
ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
Manifest::EXTERNAL_PREF));
ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
Manifest::INTERNAL));
ASSERT_EQ(Manifest::EXTERNAL_PREF,
Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_PREF,
Manifest::INTERNAL));
extensions::PendingExtensionManager* pending =
service_->pending_extension_manager();
EXPECT_FALSE(pending->IsIdPending(kGoodId));
{
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
EXPECT_TRUE(
service_->OnExternalExtensionFileFound(
kGoodId, &older_version, kInvalidPathToCrx,
Manifest::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
EXPECT_TRUE(pending->IsIdPending(kGoodId));
observer.Wait();
VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
}
{
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
EXPECT_TRUE(
service_->OnExternalExtensionFileFound(
kGoodId, &older_version, kInvalidPathToCrx,
Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
EXPECT_TRUE(pending->IsIdPending(kGoodId));
observer.Wait();
VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
}
EXPECT_FALSE(
service_->OnExternalExtensionFileFound(
kGoodId, &older_version, kInvalidPathToCrx,
Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
EXPECT_TRUE(pending->IsIdPending(kGoodId));
EXPECT_FALSE(
service_->OnExternalExtensionFileFound(
kGoodId, &older_version, kInvalidPathToCrx,
Manifest::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
EXPECT_TRUE(pending->IsIdPending(kGoodId));
{
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
EXPECT_TRUE(
service_->OnExternalExtensionFileFound(kGoodId,
&older_version,
kInvalidPathToCrx,
Manifest::EXTERNAL_REGISTRY,
kCreationFlags,
kDontMarkAcknowledged));
EXPECT_TRUE(pending->IsIdPending(kGoodId));
observer.Wait();
VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
}
EXPECT_FALSE(
service_->OnExternalExtensionFileFound(
kGoodId, &older_version, kInvalidPathToCrx,
Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
EXPECT_TRUE(pending->IsIdPending(kGoodId));
EXPECT_FALSE(
service_->OnExternalExtensionFileFound(
kGoodId, &older_version, kInvalidPathToCrx,
Manifest::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
EXPECT_TRUE(pending->IsIdPending(kGoodId));
pending->Remove(kGoodId);
base::FilePath path = data_dir_.AppendASCII("good.crx");
const Extension* ext = InstallCRX(path, INSTALL_NEW);
ValidatePrefKeyCount(1u);
ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
ASSERT_TRUE(older_version.IsOlderThan(ext->VersionString()));
ASSERT_TRUE(ext->version()->IsOlderThan(newer_version.GetString()));
EXPECT_FALSE(
service_->OnExternalExtensionFileFound(
kGoodId, &older_version, kInvalidPathToCrx,
Manifest::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
EXPECT_FALSE(pending->IsIdPending(kGoodId));
EXPECT_FALSE(
service_->OnExternalExtensionFileFound(
kGoodId, ext->version(), kInvalidPathToCrx,
Manifest::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
EXPECT_FALSE(pending->IsIdPending(kGoodId));
EXPECT_TRUE(
service_->OnExternalExtensionFileFound(
kGoodId, &newer_version, kInvalidPathToCrx,
Manifest::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
EXPECT_TRUE(pending->IsIdPending(kGoodId));
EXPECT_FALSE(
service_->OnExternalExtensionFileFound(
kGoodId, &older_version, kInvalidPathToCrx,
Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
EXPECT_TRUE(pending->IsIdPending(kGoodId));
EXPECT_TRUE(
service_->OnExternalExtensionFileFound(
kGoodId, &newer_version, kInvalidPathToCrx,
Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
EXPECT_TRUE(pending->IsIdPending(kGoodId));
EXPECT_TRUE(
service_->OnExternalExtensionFileFound(
kGoodId, &newer_version, kInvalidPathToCrx,
Manifest::EXTERNAL_REGISTRY, kCreationFlags, kDontMarkAcknowledged));
EXPECT_TRUE(pending->IsIdPending(kGoodId));
EXPECT_FALSE(
service_->OnExternalExtensionFileFound(
kGoodId, &newer_version, kInvalidPathToCrx,
Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
EXPECT_TRUE(pending->IsIdPending(kGoodId));
}
TEST_F(ExtensionServiceTest, ConcurrentExternalLocalFile) {
Version kVersion123("1.2.3");
Version kVersion124("1.2.4");
Version kVersion125("1.2.5");
const base::FilePath kInvalidPathToCrx = base::FilePath();
const int kCreationFlags = 0;
const bool kDontMarkAcknowledged = false;
InitializeEmptyExtensionService();
extensions::PendingExtensionManager* pending =
service_->pending_extension_manager();
EXPECT_FALSE(pending->IsIdPending(kGoodId));
EXPECT_TRUE(
service_->OnExternalExtensionFileFound(
kGoodId, &kVersion123, kInvalidPathToCrx,
Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
const extensions::PendingExtensionInfo* info;
EXPECT_TRUE((info = pending->GetById(kGoodId)));
EXPECT_TRUE(info->version().IsValid());
EXPECT_TRUE(info->version().Equals(kVersion123));
EXPECT_TRUE(
service_->OnExternalExtensionFileFound(
kGoodId, &kVersion124, kInvalidPathToCrx,
Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
EXPECT_TRUE((info = pending->GetById(kGoodId)));
EXPECT_TRUE(info->version().IsValid());
EXPECT_TRUE(info->version().Equals(kVersion124));
EXPECT_FALSE(
service_->OnExternalExtensionFileFound(
kGoodId, &kVersion123, kInvalidPathToCrx,
Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
EXPECT_TRUE((info = pending->GetById(kGoodId)));
EXPECT_TRUE(info->version().IsValid());
EXPECT_TRUE(info->version().Equals(kVersion124));
EXPECT_FALSE(
service_->OnExternalExtensionFileFound(
kGoodId, &kVersion123, kInvalidPathToCrx,
Manifest::EXTERNAL_REGISTRY, kCreationFlags, kDontMarkAcknowledged));
EXPECT_TRUE((info = pending->GetById(kGoodId)));
EXPECT_TRUE(info->version().IsValid());
EXPECT_TRUE(info->version().Equals(kVersion124));
GURL kUpdateUrl("http://example.com/update");
EXPECT_TRUE(service_->OnExternalExtensionUpdateUrlFound(
kGoodId,
std::string(),
kUpdateUrl,
Manifest::EXTERNAL_POLICY_DOWNLOAD,
Extension::NO_FLAGS,
false));
EXPECT_TRUE((info = pending->GetById(kGoodId)));
EXPECT_FALSE(info->version().IsValid());
}
TEST_F(ExtensionServiceTest, InstallWhitelistedExtension) {
std::string test_id = "hdkklepkcpckhnpgjnmbdfhehckloojk";
CommandLine::ForCurrentProcess()->AppendSwitchASCII(
extensions::switches::kWhitelistedExtensionID, test_id);
InitializeEmptyExtensionService();
base::FilePath path = data_dir_
.AppendASCII("permissions");
base::FilePath pem_path = path
.AppendASCII("whitelist.pem");
path = path
.AppendASCII("whitelist");
const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
EXPECT_EQ(0u, GetErrors().size());
ASSERT_EQ(1u, registry_->enabled_extensions().size());
EXPECT_EQ(test_id, extension->id());
}
class ExtensionSourcePriorityTest : public ExtensionServiceTest {
public:
virtual void SetUp() {
ExtensionServiceTest::SetUp();
crx_id_ = kGoodId;
crx_path_ = data_dir_.AppendASCII("good.crx");
}
bool AddPendingExternalPrefUrl() {
return service_->pending_extension_manager()->AddFromExternalUpdateUrl(
crx_id_,
std::string(),
GURL(),
Manifest::EXTERNAL_PREF_DOWNLOAD,
Extension::NO_FLAGS,
false);
}
bool AddPendingExternalPrefFileInstall() {
Version version("1.0.0.0");
return service_->OnExternalExtensionFileFound(
crx_id_, &version, crx_path_, Manifest::EXTERNAL_PREF,
Extension::NO_FLAGS, false);
}
bool AddPendingSyncInstall() {
return service_->pending_extension_manager()->AddFromSync(
crx_id_, GURL(kGoodUpdateURL), &IsExtension, kGoodInstallSilently);
}
bool AddPendingPolicyInstall() {
return service_->OnExternalExtensionUpdateUrlFound(
crx_id_,
std::string(),
GURL(),
Manifest::EXTERNAL_POLICY_DOWNLOAD,
Extension::NO_FLAGS,
false);
}
Manifest::Location GetPendingLocation() {
const extensions::PendingExtensionInfo* info;
EXPECT_TRUE((info = service_->pending_extension_manager()->
GetById(crx_id_)));
return info->install_source();
}
bool GetPendingIsFromSync() {
const extensions::PendingExtensionInfo* info;
EXPECT_TRUE((info = service_->pending_extension_manager()->
GetById(crx_id_)));
return info->is_from_sync();
}
bool IsCrxPending() {
return service_->pending_extension_manager()->IsIdPending(crx_id_);
}
bool IsCrxInstalled() {
return (service_->GetExtensionById(crx_id_, true) != NULL);
}
protected:
std::string crx_id_;
base::FilePath crx_path_;
};
TEST_F(ExtensionSourcePriorityTest, PendingExternalFileOverSync) {
InitializeEmptyExtensionService();
ASSERT_FALSE(IsCrxInstalled());
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
EXPECT_TRUE(AddPendingSyncInstall());
ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
EXPECT_TRUE(GetPendingIsFromSync());
ASSERT_FALSE(IsCrxInstalled());
AddPendingExternalPrefFileInstall();
ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
ASSERT_FALSE(IsCrxInstalled());
EXPECT_FALSE(AddPendingSyncInstall());
ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
ASSERT_FALSE(IsCrxInstalled());
observer.Wait();
VerifyCrxInstall(crx_path_, INSTALL_NEW);
ASSERT_TRUE(IsCrxInstalled());
}
TEST_F(ExtensionSourcePriorityTest, PendingExternalUrlOverSync) {
InitializeEmptyExtensionService();
ASSERT_FALSE(IsCrxInstalled());
EXPECT_TRUE(AddPendingSyncInstall());
ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
EXPECT_TRUE(GetPendingIsFromSync());
ASSERT_FALSE(IsCrxInstalled());
ASSERT_TRUE(AddPendingExternalPrefUrl());
ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
EXPECT_FALSE(GetPendingIsFromSync());
ASSERT_FALSE(IsCrxInstalled());
EXPECT_FALSE(AddPendingSyncInstall());
ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
EXPECT_FALSE(GetPendingIsFromSync());
ASSERT_FALSE(IsCrxInstalled());
}
TEST_F(ExtensionSourcePriorityTest, InstallExternalBlocksSyncRequest) {
InitializeEmptyExtensionService();
ASSERT_FALSE(IsCrxInstalled());
AddPendingExternalPrefFileInstall();
ASSERT_FALSE(IsCrxInstalled());
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
ASSERT_FALSE(AddPendingSyncInstall());
observer.Wait();
VerifyCrxInstall(crx_path_, INSTALL_NEW);
ASSERT_TRUE(IsCrxInstalled());
ASSERT_FALSE(AddPendingSyncInstall());
}
TEST_F(ExtensionServiceTest, ExternalInstallGlobalError) {
FeatureSwitch::ScopedOverride prompt(
FeatureSwitch::prompt_for_external_extensions(), true);
InitializeEmptyExtensionService();
MockExtensionProvider* provider =
new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
AddMockExternalProvider(provider);
service_->UpdateExternalExtensionAlert();
EXPECT_FALSE(extensions::HasExternalInstallError(service_));
set_extensions_enabled(true);
base::FilePath path = data_dir_.AppendASCII("good.crx");
InstallCRX(path, INSTALL_NEW);
service_->CheckForExternalUpdates();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(extensions::HasExternalInstallError(service_));
provider->UpdateOrAddExtension(hosted_app, "1.0.0.0",
data_dir_.AppendASCII("hosted_app.crx"));
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
service_->CheckForExternalUpdates();
observer.Wait();
EXPECT_FALSE(extensions::HasExternalInstallError(service_));
provider->UpdateOrAddExtension(page_action, "1.0.0.0",
data_dir_.AppendASCII("page_action.crx"));
content::WindowedNotificationObserver observer2(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
service_->CheckForExternalUpdates();
observer2.Wait();
EXPECT_TRUE(extensions::HasExternalInstallError(service_));
}
TEST_F(ExtensionServiceTest, ExternalInstallInitiallyDisabled) {
FeatureSwitch::ScopedOverride prompt(
FeatureSwitch::prompt_for_external_extensions(), true);
InitializeEmptyExtensionService();
MockExtensionProvider* provider =
new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
AddMockExternalProvider(provider);
provider->UpdateOrAddExtension(page_action, "1.0.0.0",
data_dir_.AppendASCII("page_action.crx"));
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
service_->CheckForExternalUpdates();
observer.Wait();
EXPECT_TRUE(extensions::HasExternalInstallError(service_));
EXPECT_FALSE(service_->IsExtensionEnabled(page_action));
const Extension* extension =
registry_->disabled_extensions().GetByID(page_action);
EXPECT_TRUE(extension);
EXPECT_EQ(page_action, extension->id());
service_->EnableExtension(page_action);
EXPECT_FALSE(extensions::HasExternalInstallError(service_));
EXPECT_TRUE(service_->IsExtensionEnabled(page_action));
}
#if defined(OS_WIN)
#define MAYBE_ExternalInstallMultiple DISABLED_ExternalInstallMultiple
#else
#define MAYBE_ExternalInstallMultiple ExternalInstallMultiple
#endif
TEST_F(ExtensionServiceTest, MAYBE_ExternalInstallMultiple) {
FeatureSwitch::ScopedOverride prompt(
FeatureSwitch::prompt_for_external_extensions(), true);
InitializeEmptyExtensionService();
MockExtensionProvider* provider =
new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
AddMockExternalProvider(provider);
provider->UpdateOrAddExtension(page_action, "1.0.0.0",
data_dir_.AppendASCII("page_action.crx"));
provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
data_dir_.AppendASCII("good.crx"));
provider->UpdateOrAddExtension(theme_crx, "2.0",
data_dir_.AppendASCII("theme.crx"));
int count = 3;
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
base::Bind(&WaitForCountNotificationsCallback, &count));
service_->CheckForExternalUpdates();
observer.Wait();
EXPECT_TRUE(extensions::HasExternalInstallError(service_));
EXPECT_FALSE(service_->IsExtensionEnabled(page_action));
EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
EXPECT_FALSE(service_->IsExtensionEnabled(theme_crx));
service_->EnableExtension(page_action);
EXPECT_TRUE(extensions::HasExternalInstallError(service_));
EXPECT_FALSE(extensions::HasExternalInstallBubble(service_));
service_->EnableExtension(theme_crx);
EXPECT_TRUE(extensions::HasExternalInstallError(service_));
EXPECT_FALSE(extensions::HasExternalInstallBubble(service_));
service_->EnableExtension(good_crx);
EXPECT_FALSE(extensions::HasExternalInstallError(service_));
EXPECT_FALSE(extensions::HasExternalInstallBubble(service_));
}
TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreOldProfile) {
FeatureSwitch::ScopedOverride prompt(
FeatureSwitch::prompt_for_external_extensions(), true);
ExtensionServiceInitParams params = CreateDefaultInitParams();
params.is_first_run = false;
InitializeExtensionService(params);
base::FilePath crx_path = temp_dir_.path().AppendASCII("webstore.crx");
PackCRX(data_dir_.AppendASCII("update_from_webstore"),
data_dir_.AppendASCII("update_from_webstore.pem"),
crx_path);
MockExtensionProvider* provider =
new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
AddMockExternalProvider(provider);
provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
service_->CheckForExternalUpdates();
observer.Wait();
EXPECT_TRUE(extensions::HasExternalInstallError(service_));
EXPECT_TRUE(extensions::HasExternalInstallBubble(service_));
EXPECT_FALSE(service_->IsExtensionEnabled(updates_from_webstore));
}
TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreNewProfile) {
FeatureSwitch::ScopedOverride prompt(
FeatureSwitch::prompt_for_external_extensions(), true);
InitializeEmptyExtensionService();
base::FilePath crx_path = temp_dir_.path().AppendASCII("webstore.crx");
PackCRX(data_dir_.AppendASCII("update_from_webstore"),
data_dir_.AppendASCII("update_from_webstore.pem"),
crx_path);
MockExtensionProvider* provider =
new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
AddMockExternalProvider(provider);
provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::NotificationService::AllSources());
service_->CheckForExternalUpdates();
observer.Wait();
EXPECT_TRUE(extensions::HasExternalInstallError(service_));
EXPECT_FALSE(extensions::HasExternalInstallBubble(service_));
EXPECT_FALSE(service_->IsExtensionEnabled(updates_from_webstore));
}
TEST_F(ExtensionServiceTest, InstallBlacklistedExtension) {
InitializeEmptyExtensionService();
scoped_refptr<Extension> extension = extensions::ExtensionBuilder()
.SetManifest(extensions::DictionaryBuilder()
.Set("name", "extension")
.Set("version", "1.0")
.Set("manifest_version", 2).Build())
.Build();
ASSERT_TRUE(extension.get());
const std::string& id = extension->id();
std::set<std::string> id_set;
id_set.insert(id);
extensions::ExtensionNotificationObserver notifications(
content::NotificationService::AllSources(), id_set);
service_->OnExtensionInstalled(
extension.get(),
syncer::StringOrdinal(),
false ,
extensions::BLACKLISTED_MALWARE,
false );
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(notifications.CheckNotifications(
chrome::NOTIFICATION_EXTENSION_INSTALLED));
EXPECT_TRUE(service_->GetInstalledExtension(id));
EXPECT_FALSE(registry_->enabled_extensions().Contains(id));
EXPECT_TRUE(registry_->blacklisted_extensions().Contains(id));
EXPECT_TRUE(ExtensionPrefs::Get(profile_.get())->IsExtensionBlacklisted(id));
EXPECT_TRUE(ExtensionPrefs::Get(profile_.get())
->IsBlacklistedExtensionAcknowledged(id));
}
TEST_F(ExtensionServiceTest, ReconcileKnownDisabledNoneDisabled) {
InitializeGoodInstalledExtensionService();
service_->Init();
extensions::ExtensionIdSet expected_extensions;
expected_extensions.insert(good0);
expected_extensions.insert(good1);
expected_extensions.insert(good2);
extensions::ExtensionIdSet expected_disabled_extensions;
EXPECT_EQ(expected_extensions, registry_->enabled_extensions().GetIDs());
EXPECT_EQ(expected_disabled_extensions,
registry_->disabled_extensions().GetIDs());
}
TEST_F(ExtensionServiceTest, ReconcileKnownDisabledWithSideEnable) {
InitializeGoodInstalledExtensionService();
ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(profile_.get());
extension_prefs->SetExtensionState(good1, Extension::DISABLED);
extensions::ExtensionIdSet known_disabled;
known_disabled.insert(good1);
known_disabled.insert(good2);
extension_prefs->SetKnownDisabled(known_disabled);
service_->Init();
extensions::ExtensionIdSet expected_extensions;
expected_extensions.insert(good0);
extensions::ExtensionIdSet expected_disabled_extensions;
expected_disabled_extensions.insert(good1);
expected_disabled_extensions.insert(good2);
EXPECT_EQ(expected_extensions, registry_->enabled_extensions().GetIDs());
EXPECT_EQ(expected_disabled_extensions,
registry_->disabled_extensions().GetIDs());
service_->EnableExtension(good2);
service_->ReconcileKnownDisabled();
expected_extensions.insert(good2);
expected_disabled_extensions.erase(good2);
EXPECT_EQ(expected_extensions, registry_->enabled_extensions().GetIDs());
EXPECT_EQ(expected_disabled_extensions,
registry_->disabled_extensions().GetIDs());
}