blob: 4b0ebb85a52a56be9f8a8a19c662ec90d38c3ca0 [file] [log] [blame]
// 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 <string>
#include <vector>
#include "base/memory/ref_counted.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/values.h"
#include "chrome/browser/extensions/component_migration_helper.h"
#include "chrome/browser/extensions/extension_action_test_util.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_service_test_base.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/feature_switch.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::Return;
using ::testing::StrictMock;
namespace extensions {
namespace {
const char kTestActionId[] = "toolbar-action";
class MockComponentActionDelegate
: public ComponentMigrationHelper::ComponentActionDelegate {
public:
MOCK_METHOD1(AddComponentAction, void(const std::string&));
MOCK_METHOD1(RemoveComponentAction, void(const std::string&));
MOCK_CONST_METHOD1(HasComponentAction, bool(const std::string&));
};
class MockComponentMigrationHelper : public ComponentMigrationHelper {
public:
MockComponentMigrationHelper(Profile* profile,
ComponentActionDelegate* delegate)
: ComponentMigrationHelper(profile, delegate) {}
~MockComponentMigrationHelper() override{};
void SetTestComponentActionPref(bool enabled) {
SetComponentActionPref(kTestActionId, enabled);
}
void EnableTestFeature() { enabled_actions_.insert(kTestActionId); }
void DisableTestFeature() { enabled_actions_.erase(kTestActionId); }
};
} // namespace
class ComponentMigrationHelperTest : public ExtensionServiceTestBase {
protected:
ComponentMigrationHelperTest() {}
~ComponentMigrationHelperTest() override {}
void SetUp() override {
extension_action_redesign_.reset(new FeatureSwitch::ScopedOverride(
FeatureSwitch::extension_action_redesign(),
FeatureSwitch::OVERRIDE_ENABLED));
ExtensionServiceTestBase::SetUp();
InitializeEmptyExtensionService();
migrated_extension_a_ = extension_action_test_util::CreateActionExtension(
"migrated_browser_action_a",
extension_action_test_util::BROWSER_ACTION);
migrated_extension_b_ = extension_action_test_util::CreateActionExtension(
"migrated_browser_action_b",
extension_action_test_util::BROWSER_ACTION);
unregistered_extension_ = extension_action_test_util::CreateActionExtension(
"unregistered_extension", extension_action_test_util::BROWSER_ACTION);
mock_helper_.reset(new StrictMock<MockComponentMigrationHelper>(
profile(), &mock_delegate_));
mock_helper_->Register(kTestActionId, migrated_extension_a_->id());
mock_helper_->Register(kTestActionId, migrated_extension_b_->id());
}
bool IsTestComponentActionEnabled() {
const base::DictionaryValue* migration_pref =
profile()->GetPrefs()->GetDictionary(
::prefs::kToolbarMigratedComponentActionStatus);
if (!migration_pref->HasKey(kTestActionId))
return false;
bool enable_value = false;
CHECK(migration_pref->GetBoolean(kTestActionId, &enable_value));
return enable_value;
}
StrictMock<MockComponentActionDelegate> mock_delegate_;
scoped_ptr<StrictMock<MockComponentMigrationHelper>> mock_helper_;
scoped_ptr<FeatureSwitch::ScopedOverride> extension_action_redesign_;
// Migrated extensions with browser actions.
scoped_refptr<const Extension> migrated_extension_a_;
scoped_refptr<const Extension> migrated_extension_b_;
// An extension that is not migrated.
scoped_refptr<const Extension> unregistered_extension_;
private:
DISALLOW_COPY_AND_ASSIGN(ComponentMigrationHelperTest);
};
TEST_F(ComponentMigrationHelperTest, FeatureEnabledWhenExtensionInstalled) {
service()->AddExtension(migrated_extension_a_.get());
service()->AddExtension(migrated_extension_b_.get());
EXPECT_CALL(mock_delegate_, HasComponentAction(kTestActionId))
.WillOnce(Return(false));
EXPECT_CALL(mock_delegate_, AddComponentAction(kTestActionId));
mock_helper_->OnFeatureEnabled(kTestActionId);
EXPECT_TRUE(IsTestComponentActionEnabled());
EXPECT_FALSE(
registry()->enabled_extensions().Contains(migrated_extension_a_->id()));
EXPECT_FALSE(
registry()->enabled_extensions().Contains(migrated_extension_b_->id()));
}
TEST_F(ComponentMigrationHelperTest, FeatureEnabledWithNoPref) {
mock_helper_->OnFeatureEnabled(kTestActionId);
EXPECT_FALSE(IsTestComponentActionEnabled());
}
TEST_F(ComponentMigrationHelperTest, FeatureEnabledWithPrefFalse) {
mock_helper_->SetTestComponentActionPref(false);
mock_helper_->OnFeatureEnabled(kTestActionId);
EXPECT_FALSE(IsTestComponentActionEnabled());
}
TEST_F(ComponentMigrationHelperTest, FeatureEnabledWithPrefTrue) {
mock_helper_->SetTestComponentActionPref(true);
EXPECT_CALL(mock_delegate_, HasComponentAction(kTestActionId))
.WillOnce(Return(false));
EXPECT_CALL(mock_delegate_, AddComponentAction(kTestActionId));
mock_helper_->OnFeatureEnabled(kTestActionId);
EXPECT_TRUE(IsTestComponentActionEnabled());
}
TEST_F(ComponentMigrationHelperTest, FeatureDisabledWithAction) {
mock_helper_->EnableTestFeature();
EXPECT_CALL(mock_delegate_, HasComponentAction(kTestActionId))
.WillOnce(Return(true));
EXPECT_CALL(mock_delegate_, RemoveComponentAction(kTestActionId));
mock_helper_->OnFeatureDisabled(kTestActionId);
EXPECT_FALSE(IsTestComponentActionEnabled());
}
TEST_F(ComponentMigrationHelperTest, InstallWithFeatureEnabled) {
mock_helper_->EnableTestFeature();
EXPECT_CALL(mock_delegate_, HasComponentAction(kTestActionId))
.WillOnce(Return(false));
EXPECT_CALL(mock_delegate_, AddComponentAction(kTestActionId));
service()->AddExtension(migrated_extension_a_.get());
// The test framework does not call OnExtensionReady :-/
mock_helper_->OnExtensionReady(browser_context(),
migrated_extension_a_.get());
EXPECT_TRUE(IsTestComponentActionEnabled());
EXPECT_FALSE(
registry()->enabled_extensions().Contains(migrated_extension_a_->id()));
}
TEST_F(ComponentMigrationHelperTest, InstallWithFeatureDisabled) {
mock_helper_->DisableTestFeature();
service()->AddExtension(migrated_extension_a_.get());
EXPECT_FALSE(IsTestComponentActionEnabled());
EXPECT_TRUE(
registry()->enabled_extensions().Contains(migrated_extension_a_->id()));
}
TEST_F(ComponentMigrationHelperTest, InstallUnregisteredExtension) {
service()->AddExtension(unregistered_extension_.get());
EXPECT_FALSE(IsTestComponentActionEnabled());
EXPECT_TRUE(
registry()->enabled_extensions().Contains(unregistered_extension_->id()));
}
TEST_F(ComponentMigrationHelperTest, RemoveComponentAction) {
mock_helper_->SetTestComponentActionPref(true);
EXPECT_CALL(mock_delegate_, HasComponentAction(kTestActionId))
.WillOnce(Return(false));
EXPECT_CALL(mock_delegate_, AddComponentAction(kTestActionId));
mock_helper_->OnFeatureEnabled(kTestActionId);
EXPECT_TRUE(IsTestComponentActionEnabled());
EXPECT_CALL(mock_delegate_, HasComponentAction(kTestActionId))
.WillOnce(Return(true));
EXPECT_CALL(mock_delegate_, RemoveComponentAction(kTestActionId));
mock_helper_->OnActionRemoved(kTestActionId);
EXPECT_FALSE(IsTestComponentActionEnabled());
}
} // namespace extensions