| Index: chrome/browser/extensions/update_install_gate_unittest.cc
|
| diff --git a/chrome/browser/extensions/update_install_gate_unittest.cc b/chrome/browser/extensions/update_install_gate_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a42ee1651297d35c80930f3b50f016cff7844b87
|
| --- /dev/null
|
| +++ b/chrome/browser/extensions/update_install_gate_unittest.cc
|
| @@ -0,0 +1,279 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/browser/extensions/update_install_gate.h"
|
| +
|
| +#include <memory>
|
| +
|
| +#include "base/command_line.h"
|
| +#include "base/memory/ptr_util.h"
|
| +#include "base/run_loop.h"
|
| +#include "chrome/browser/extensions/extension_service.h"
|
| +#include "chrome/browser/extensions/test_extension_system.h"
|
| +#include "chrome/test/base/testing_browser_process.h"
|
| +#include "chrome/test/base/testing_profile.h"
|
| +#include "chrome/test/base/testing_profile_manager.h"
|
| +#include "content/public/test/test_browser_thread_bundle.h"
|
| +#include "content/public/test/test_renderer_host.h"
|
| +#include "extensions/browser/event_router.h"
|
| +#include "extensions/browser/event_router_factory.h"
|
| +#include "extensions/browser/extension_host.h"
|
| +#include "extensions/browser/extension_prefs.h"
|
| +#include "extensions/browser/extension_registry.h"
|
| +#include "extensions/common/extension_builder.h"
|
| +#include "extensions/common/manifest_handlers/background_info.h"
|
| +#include "extensions/common/value_builder.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +#if defined(OS_CHROMEOS)
|
| +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
|
| +#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
|
| +#include "chrome/browser/chromeos/settings/cros_settings.h"
|
| +#include "chrome/browser/chromeos/settings/device_settings_service.h"
|
| +#endif
|
| +
|
| +namespace extensions {
|
| +
|
| +namespace {
|
| +
|
| +const char kAppId[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
| +const char kPersistentExtensionId[] = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
|
| +const char kNonPersistentExtensionId[] = "cccccccccccccccccccccccccccccccc";
|
| +
|
| +std::unique_ptr<KeyedService> BuildEventRouter(
|
| + content::BrowserContext* profile) {
|
| + return base::WrapUnique(new extensions::EventRouter(profile, nullptr));
|
| +}
|
| +
|
| +scoped_refptr<Extension> CreateApp(const std::string& extension_id,
|
| + const std::string& version) {
|
| + scoped_refptr<Extension> app =
|
| + ExtensionBuilder()
|
| + .SetManifest(
|
| + DictionaryBuilder()
|
| + .Set("name", "Test app")
|
| + .Set("version", version)
|
| + .Set("manifest_version", 2)
|
| + .Set("app",
|
| + DictionaryBuilder()
|
| + .Set("background",
|
| + DictionaryBuilder()
|
| + .Set("scripts", ListBuilder()
|
| + .Append("background.js")
|
| + .Build())
|
| + .Build())
|
| + .Build())
|
| + .Build())
|
| + .SetID(extension_id)
|
| + .Build();
|
| + return app;
|
| +}
|
| +
|
| +scoped_refptr<Extension> CreateExtension(const std::string& extension_id,
|
| + const std::string& version,
|
| + bool persistent) {
|
| + scoped_refptr<Extension> extension =
|
| + ExtensionBuilder()
|
| + .SetManifest(
|
| + DictionaryBuilder()
|
| + .Set("name", "Test extension")
|
| + .Set("version", version)
|
| + .Set("manifest_version", 2)
|
| + .Set("background", DictionaryBuilder()
|
| + .Set("page", "background.html")
|
| + .SetBoolean("persistent", persistent)
|
| + .Build())
|
| + .Build())
|
| + .SetID(extension_id)
|
| + .Build();
|
| + return extension;
|
| +}
|
| +
|
| +ExtensionHost* CreateHost(Profile* profile, const Extension* app) {
|
| + ProcessManager::Get(profile)->CreateBackgroundHost(
|
| + app, BackgroundInfo::GetBackgroundURL(app));
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + return ProcessManager::Get(profile)->GetBackgroundHostForExtension(app->id());
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +class UpdateInstallGateTest : public testing::Test {
|
| + public:
|
| + UpdateInstallGateTest() {
|
| + profile_manager_.reset(
|
| + new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
|
| + }
|
| +
|
| + // testing::Test
|
| + void SetUp() override {
|
| + // Must be called from ::testing::Test::SetUp.
|
| + ASSERT_TRUE(profile_manager_->SetUp());
|
| +
|
| + const char kUserProfile[] = "profile1@example.com";
|
| +#if defined(OS_CHROMEOS)
|
| + const AccountId account_id(AccountId::FromUserEmail(kUserProfile));
|
| + // Needed to allow ChromeProcessManagerDelegate to allow background pages.
|
| + fake_user_manager_ = new chromeos::FakeChromeUserManager();
|
| + // Takes ownership of fake_user_manager_.
|
| + scoped_user_manager_enabler_.reset(
|
| + new chromeos::ScopedUserManagerEnabler(fake_user_manager_));
|
| + fake_user_manager_->AddUser(account_id);
|
| + fake_user_manager_->LoginUser(account_id);
|
| +#endif
|
| + profile_ = profile_manager_->CreateTestingProfile(kUserProfile);
|
| + profile_manager_->SetLoggedIn(true);
|
| +
|
| + TestExtensionSystem* test_extension_system =
|
| + static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile_));
|
| + service_ = test_extension_system->CreateExtensionService(
|
| + base::CommandLine::ForCurrentProcess(),
|
| + base::FilePath() /* install_directory */,
|
| + false /* autoupdate_enabled */);
|
| + registry_ = ExtensionRegistry::Get(profile_);
|
| +
|
| + event_router_ = static_cast<EventRouter*>(
|
| + EventRouterFactory::GetInstance()->SetTestingFactoryAndUse(
|
| + profile_, &BuildEventRouter));
|
| +
|
| + delayer_.reset(new UpdateInstallGate(service_));
|
| +
|
| + new_app_ = CreateApp(kAppId, "2.0");
|
| + new_persistent_ = CreateExtension(kPersistentExtensionId, "2.0", true);
|
| + new_none_persistent_ =
|
| + CreateExtension(kNonPersistentExtensionId, "2.0", false);
|
| + }
|
| +
|
| + void TearDown() override { profile_manager_->DeleteAllTestingProfiles(); }
|
| +
|
| + void AddExistingExtensions() {
|
| + scoped_refptr<Extension> app = CreateApp(kAppId, "1.0");
|
| + registry_->AddEnabled(app);
|
| +
|
| + scoped_refptr<Extension> persistent =
|
| + CreateExtension(kPersistentExtensionId, "1.0", true);
|
| + registry_->AddEnabled(persistent);
|
| +
|
| + scoped_refptr<Extension> none_persistent =
|
| + CreateExtension(kNonPersistentExtensionId, "1.0", false);
|
| + registry_->AddEnabled(none_persistent);
|
| + }
|
| +
|
| + void MakeExtensionInUse(const std::string& extension_id) {
|
| + const Extension* const extension =
|
| + registry_->GetInstalledExtension(extension_id);
|
| + ASSERT_TRUE(!!extension);
|
| + ASSERT_TRUE(!!CreateHost(profile_, extension));
|
| + }
|
| +
|
| + void MakeExtensionListenForOnUpdateAvailable(
|
| + const std::string& extension_id) {
|
| + const char kOnUpdateAvailableEvent[] = "runtime.onUpdateAvailable";
|
| + event_router_->AddEventListener(kOnUpdateAvailableEvent, NULL,
|
| + extension_id);
|
| + }
|
| +
|
| + void Check(const Extension* extension,
|
| + bool is_in_use,
|
| + bool has_listener,
|
| + bool install_immediately,
|
| + InstallGate::Action expected_action) {
|
| + if (is_in_use)
|
| + MakeExtensionInUse(extension->id());
|
| + if (has_listener)
|
| + MakeExtensionListenForOnUpdateAvailable(extension->id());
|
| +
|
| + EXPECT_EQ(expected_action,
|
| + delayer()->ShouldDelay(extension, install_immediately));
|
| + }
|
| +
|
| + UpdateInstallGate* delayer() { return delayer_.get(); }
|
| + ExtensionService* service() { return service_; }
|
| +
|
| + const Extension* new_app() const { return new_app_.get(); }
|
| + const Extension* new_persistent() const { return new_persistent_.get(); }
|
| + const Extension* new_none_persistent() const {
|
| + return new_none_persistent_.get();
|
| + }
|
| +
|
| + private:
|
| + // Needed by extension system.
|
| + content::TestBrowserThreadBundle thread_bundle_;
|
| +
|
| + // Needed to ensure we don't end up creating actual RenderViewHosts
|
| + // and RenderProcessHosts.
|
| + content::RenderViewHostTestEnabler render_view_host_test_enabler_;
|
| +
|
| + TestingProfile* profile_ = nullptr;
|
| + std::unique_ptr<TestingProfileManager> profile_manager_;
|
| +
|
| + ExtensionService* service_ = nullptr;
|
| + ExtensionRegistry* registry_ = nullptr;
|
| + EventRouter* event_router_ = nullptr;
|
| +
|
| +#if defined(OS_CHROMEOS)
|
| + // Needed for creating ExtensionService.
|
| + chromeos::FakeChromeUserManager* fake_user_manager_ = nullptr;
|
| + std::unique_ptr<chromeos::ScopedUserManagerEnabler>
|
| + scoped_user_manager_enabler_;
|
| +#endif
|
| +
|
| + std::unique_ptr<UpdateInstallGate> delayer_;
|
| +
|
| + scoped_refptr<Extension> new_app_;
|
| + scoped_refptr<Extension> new_persistent_;
|
| + scoped_refptr<Extension> new_none_persistent_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(UpdateInstallGateTest);
|
| +};
|
| +
|
| +TEST_F(UpdateInstallGateTest, InstallOnServiceNotReady) {
|
| + ASSERT_FALSE(service()->is_ready());
|
| + Check(new_app(), false, false, false, InstallGate::INSTALL);
|
| + Check(new_persistent(), false, false, false, InstallGate::INSTALL);
|
| + Check(new_none_persistent(), false, false, false, InstallGate::INSTALL);
|
| +}
|
| +
|
| +TEST_F(UpdateInstallGateTest, InstallOnFirstInstall) {
|
| + service()->Init();
|
| + Check(new_app(), false, false, false, InstallGate::INSTALL);
|
| + Check(new_persistent(), false, false, false, InstallGate::INSTALL);
|
| + Check(new_none_persistent(), false, false, false, InstallGate::INSTALL);
|
| +}
|
| +
|
| +TEST_F(UpdateInstallGateTest, InstallOnInstallImmediately) {
|
| + service()->Init();
|
| + AddExistingExtensions();
|
| +
|
| + const bool kInstallImmediately = true;
|
| + for (bool in_use : {false, true}) {
|
| + for (bool has_listener : {false, true}) {
|
| + Check(new_app(), in_use, has_listener, kInstallImmediately,
|
| + InstallGate::INSTALL);
|
| + Check(new_persistent(), in_use, has_listener, kInstallImmediately,
|
| + InstallGate::INSTALL);
|
| + Check(new_none_persistent(), in_use, has_listener, kInstallImmediately,
|
| + InstallGate::INSTALL);
|
| + }
|
| + }
|
| +}
|
| +
|
| +TEST_F(UpdateInstallGateTest, DelayInstallWhenInUse) {
|
| + service()->Init();
|
| + AddExistingExtensions();
|
| +
|
| + const bool kInUse = true;
|
| + const bool kDontInstallImmediately = false;
|
| + for (bool has_listener : {false, true}) {
|
| + Check(new_app(), kInUse, has_listener, kDontInstallImmediately,
|
| + InstallGate::DELAY);
|
| + Check(new_persistent(), kInUse, has_listener, kDontInstallImmediately,
|
| + has_listener ? InstallGate::DELAY : InstallGate::INSTALL);
|
| + Check(new_none_persistent(), kInUse, has_listener, kDontInstallImmediately,
|
| + InstallGate::DELAY);
|
| + }
|
| +}
|
| +
|
| +} // namespace extensions
|
|
|