| Index: chrome/browser/extensions/active_script_controller_browsertest.cc
|
| diff --git a/chrome/browser/extensions/active_script_controller_browsertest.cc b/chrome/browser/extensions/active_script_controller_browsertest.cc
|
| index 6234be632b03aae07a700e022288c18b34e73c83..0ae15caba38c6a73c7eefd4c77e17a14e6769cf3 100644
|
| --- a/chrome/browser/extensions/active_script_controller_browsertest.cc
|
| +++ b/chrome/browser/extensions/active_script_controller_browsertest.cc
|
| @@ -15,7 +15,9 @@
|
| #include "chrome/browser/ui/browser.h"
|
| #include "chrome/browser/ui/tabs/tab_strip_model.h"
|
| #include "chrome/test/base/ui_test_utils.h"
|
| +#include "content/public/test/browser_test_utils.h"
|
| #include "extensions/common/feature_switch.h"
|
| +#include "extensions/common/switches.h"
|
| #include "net/test/embedded_test_server/embedded_test_server.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| @@ -61,30 +63,37 @@ enum RequiresConsent {
|
|
|
| class ActiveScriptControllerBrowserTest : public ExtensionBrowserTest {
|
| public:
|
| - ActiveScriptControllerBrowserTest()
|
| - : feature_override_(FeatureSwitch::scripts_require_action(),
|
| - FeatureSwitch::OVERRIDE_ENABLED) {}
|
| + ActiveScriptControllerBrowserTest() {}
|
|
|
| + virtual void SetUpCommandLine(base::CommandLine* command_line) OVERRIDE;
|
| virtual void CleanUpOnMainThread() OVERRIDE;
|
|
|
| // Returns an extension with the given |host_type| and |injection_type|. If
|
| // one already exists, the existing extension will be returned. Othewrwise,
|
| // one will be created.
|
| // This could potentially return NULL if LoadExtension() fails.
|
| - const Extension* GetOrCreateExtension(HostType host_type,
|
| - InjectionType injection_type);
|
| + const Extension* CreateExtension(HostType host_type,
|
| + InjectionType injection_type);
|
|
|
| private:
|
| - FeatureSwitch::ScopedOverride feature_override_;
|
| ScopedVector<TestExtensionDir> test_extension_dirs_;
|
| std::vector<const Extension*> extensions_;
|
| };
|
|
|
| +void ActiveScriptControllerBrowserTest::SetUpCommandLine(
|
| + base::CommandLine* command_line) {
|
| + ExtensionBrowserTest::SetUpCommandLine(command_line);
|
| + // We append the actual switch to the commandline because it needs to be
|
| + // passed over to the renderer, which a FeatureSwitch::ScopedOverride will
|
| + // not do.
|
| + command_line->AppendSwitch(switches::kEnableScriptsRequireAction);
|
| +}
|
| +
|
| void ActiveScriptControllerBrowserTest::CleanUpOnMainThread() {
|
| test_extension_dirs_.clear();
|
| }
|
|
|
| -const Extension* ActiveScriptControllerBrowserTest::GetOrCreateExtension(
|
| +const Extension* ActiveScriptControllerBrowserTest::CreateExtension(
|
| HostType host_type, InjectionType injection_type) {
|
| std::string name =
|
| base::StringPrintf(
|
| @@ -93,13 +102,6 @@ const Extension* ActiveScriptControllerBrowserTest::GetOrCreateExtension(
|
| "content_script" : "execute_script",
|
| host_type == ALL_HOSTS ? "all_hosts" : "explicit_hosts");
|
|
|
| - for (std::vector<const Extension*>::const_iterator iter = extensions_.begin();
|
| - iter != extensions_.end();
|
| - ++iter) {
|
| - if ((*iter)->name() == name)
|
| - return *iter;
|
| - }
|
| -
|
| const char* permission_scheme =
|
| host_type == ALL_HOSTS ? kAllHostsScheme : kExplicitHostsScheme;
|
|
|
| @@ -266,10 +268,7 @@ testing::AssertionResult ActiveScriptTester::Verify() {
|
|
|
| // Otherwise, we don't have permission, and have to grant it. Ensure the
|
| // script has *not* already executed.
|
| - // Currently, it's okay for content scripts to execute, because we don't
|
| - // block them.
|
| - // TODO(rdevlin.cronin): Fix this.
|
| - if (inject_success_listener_->was_satisfied() && type_ != CONTENT_SCRIPT) {
|
| + if (inject_success_listener_->was_satisfied()) {
|
| return testing::AssertionFailure() <<
|
| name_ << "'s script ran without permission.";
|
| }
|
| @@ -316,7 +315,7 @@ ExtensionAction* ActiveScriptTester::GetAction() {
|
| }
|
|
|
| IN_PROC_BROWSER_TEST_F(ActiveScriptControllerBrowserTest,
|
| - ActiveScriptsAreDisplayed) {
|
| + ActiveScriptsAreDisplayedAndDelayExecution) {
|
| base::FilePath active_script_path =
|
| test_data_dir_.AppendASCII("active_script");
|
|
|
| @@ -337,32 +336,32 @@ IN_PROC_BROWSER_TEST_F(ActiveScriptControllerBrowserTest,
|
| ActiveScriptTester testers[] = {
|
| ActiveScriptTester(
|
| kExtensionNames[0],
|
| - GetOrCreateExtension(ALL_HOSTS, EXECUTE_SCRIPT),
|
| + CreateExtension(ALL_HOSTS, EXECUTE_SCRIPT),
|
| browser(),
|
| REQUIRES_CONSENT,
|
| EXECUTE_SCRIPT),
|
| ActiveScriptTester(
|
| kExtensionNames[1],
|
| - GetOrCreateExtension(EXPLICIT_HOSTS, EXECUTE_SCRIPT),
|
| + CreateExtension(EXPLICIT_HOSTS, EXECUTE_SCRIPT),
|
| browser(),
|
| DOES_NOT_REQUIRE_CONSENT,
|
| EXECUTE_SCRIPT),
|
| ActiveScriptTester(
|
| kExtensionNames[2],
|
| - GetOrCreateExtension(ALL_HOSTS, CONTENT_SCRIPT),
|
| + CreateExtension(ALL_HOSTS, CONTENT_SCRIPT),
|
| browser(),
|
| REQUIRES_CONSENT,
|
| CONTENT_SCRIPT),
|
| ActiveScriptTester(
|
| kExtensionNames[3],
|
| - GetOrCreateExtension(EXPLICIT_HOSTS, CONTENT_SCRIPT),
|
| + CreateExtension(EXPLICIT_HOSTS, CONTENT_SCRIPT),
|
| browser(),
|
| DOES_NOT_REQUIRE_CONSENT,
|
| CONTENT_SCRIPT),
|
| };
|
|
|
| // Navigate to an URL (which matches the explicit host specified in the
|
| - // extension content_scripts_explicit_hosts). All three extensions should
|
| + // extension content_scripts_explicit_hosts). All four extensions should
|
| // inject the script.
|
| ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
|
| ui_test_utils::NavigateToURL(
|
| @@ -372,4 +371,95 @@ IN_PROC_BROWSER_TEST_F(ActiveScriptControllerBrowserTest,
|
| EXPECT_TRUE(testers[i].Verify()) << kExtensionNames[i];
|
| }
|
|
|
| +// Test that removing an extension with pending injections a) removes the
|
| +// pending injections for that extension, and b) does not affect pending
|
| +// injections for other extensions.
|
| +IN_PROC_BROWSER_TEST_F(ActiveScriptControllerBrowserTest,
|
| + RemoveExtensionWithPendingInjections) {
|
| + // Load up two extensions, each with content scripts.
|
| + const Extension* extension1 = CreateExtension(ALL_HOSTS, CONTENT_SCRIPT);
|
| + ASSERT_TRUE(extension1);
|
| + const Extension* extension2 = CreateExtension(ALL_HOSTS, CONTENT_SCRIPT);
|
| + ASSERT_TRUE(extension2);
|
| +
|
| + ASSERT_NE(extension1->id(), extension2->id());
|
| +
|
| + content::WebContents* web_contents =
|
| + browser()->tab_strip_model()->GetActiveWebContents();
|
| + ASSERT_TRUE(web_contents);
|
| + ActiveScriptController* active_script_controller =
|
| + ActiveScriptController::GetForWebContents(web_contents);
|
| + ASSERT_TRUE(active_script_controller);
|
| +
|
| + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
|
| + ui_test_utils::NavigateToURL(
|
| + browser(), embedded_test_server()->GetURL("/extensions/test_file.html"));
|
| +
|
| + // Both extensions should have pending requests.
|
| + EXPECT_TRUE(active_script_controller->GetActionForExtension(extension1));
|
| + EXPECT_TRUE(active_script_controller->GetActionForExtension(extension2));
|
| +
|
| + // Unload one of the extensions.
|
| + UnloadExtension(extension2->id());
|
| +
|
| + // This is slight hack to achieve a RunPendingInRenderer() method. Since IPCs
|
| + // are sent synchronously, the renderer will be notified of the extension
|
| + // being unloaded before the script is executed, and, since ExecuteScript() is
|
| + // synchronous, the renderer is guaranteed to be done updating scripts.
|
| + EXPECT_TRUE(content::ExecuteScript(web_contents, "1 == 1;"));
|
| +
|
| + // We should have pending requests for extension1, but not the removed
|
| + // extension2.
|
| + EXPECT_TRUE(active_script_controller->GetActionForExtension(extension1));
|
| + EXPECT_FALSE(active_script_controller->GetActionForExtension(extension2));
|
| +
|
| + // We should still be able to run the request for extension1.
|
| + ExtensionTestMessageListener inject_success_listener(
|
| + new ExtensionTestMessageListener(kInjectSucceeded,
|
| + false /* won't reply */));
|
| + inject_success_listener.set_extension_id(extension1->id());
|
| + active_script_controller->OnClicked(extension1);
|
| + inject_success_listener.WaitUntilSatisfied();
|
| +}
|
| +
|
| +// A version of the test with the flag off, in order to test that everything
|
| +// still works as expected.
|
| +class FlagOffActiveScriptControllerBrowserTest
|
| + : public ActiveScriptControllerBrowserTest {
|
| + private:
|
| + // Simply don't append the flag.
|
| + virtual void SetUpCommandLine(base::CommandLine* command_line) OVERRIDE {
|
| + ExtensionBrowserTest::SetUpCommandLine(command_line);
|
| + }
|
| +};
|
| +
|
| +IN_PROC_BROWSER_TEST_F(FlagOffActiveScriptControllerBrowserTest,
|
| + ScriptsExecuteWhenFlagAbsent) {
|
| + const char* kExtensionNames[] = {
|
| + "content_scripts_all_hosts",
|
| + "inject_scripts_all_hosts",
|
| + };
|
| + ActiveScriptTester testers[] = {
|
| + ActiveScriptTester(
|
| + kExtensionNames[0],
|
| + CreateExtension(ALL_HOSTS, CONTENT_SCRIPT),
|
| + browser(),
|
| + DOES_NOT_REQUIRE_CONSENT,
|
| + CONTENT_SCRIPT),
|
| + ActiveScriptTester(
|
| + kExtensionNames[1],
|
| + CreateExtension(ALL_HOSTS, EXECUTE_SCRIPT),
|
| + browser(),
|
| + DOES_NOT_REQUIRE_CONSENT,
|
| + EXECUTE_SCRIPT),
|
| + };
|
| +
|
| + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
|
| + ui_test_utils::NavigateToURL(
|
| + browser(), embedded_test_server()->GetURL("/extensions/test_file.html"));
|
| +
|
| + for (size_t i = 0u; i < arraysize(testers); ++i)
|
| + EXPECT_TRUE(testers[i].Verify()) << kExtensionNames[i];
|
| +}
|
| +
|
| } // namespace extensions
|
|
|