1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <string> 6 7 #include "base/command_line.h" 8 #include "base/files/file_path.h" 9 #include "base/memory/scoped_ptr.h" 10 #include "base/message_loop/message_loop.h" 11 #include "chrome/browser/extensions/component_loader.h" 12 #include "chrome/browser/extensions/extension_action.h" 13 #include "chrome/browser/extensions/extension_action_manager.h" 14 #include "chrome/browser/extensions/extension_service.h" 15 #include "chrome/browser/extensions/extension_tab_util.h" 16 #include "chrome/browser/extensions/script_bubble_controller.h" 17 #include "chrome/browser/extensions/test_extension_system.h" 18 #include "chrome/common/extensions/extension.h" 19 #include "chrome/common/extensions/extension_builder.h" 20 #include "chrome/common/extensions/feature_switch.h" 21 #include "chrome/common/extensions/value_builder.h" 22 #include "chrome/test/base/chrome_render_view_host_test_harness.h" 23 #include "chrome/test/base/testing_profile.h" 24 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/navigation_entry.h" 26 #include "content/public/test/test_browser_thread.h" 27 28 #if defined(OS_CHROMEOS) 29 #include "chrome/browser/chromeos/login/user_manager.h" 30 #include "chrome/browser/chromeos/settings/cros_settings.h" 31 #include "chrome/browser/chromeos/settings/device_settings_service.h" 32 #endif 33 34 namespace extensions { 35 namespace { 36 37 class ScriptBubbleControllerTest : public ChromeRenderViewHostTestHarness { 38 protected: 39 ScriptBubbleControllerTest() 40 : enable_script_bubble_(FeatureSwitch::script_bubble(), true) { 41 } 42 43 virtual void SetUp() OVERRIDE { 44 ChromeRenderViewHostTestHarness::SetUp(); 45 #if defined OS_CHROMEOS 46 test_user_manager_.reset(new chromeos::ScopedTestUserManager()); 47 #endif 48 CommandLine command_line(CommandLine::NO_PROGRAM); 49 Profile* profile = 50 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 51 extension_service_ = static_cast<TestExtensionSystem*>( 52 ExtensionSystem::Get(profile))->CreateExtensionService( 53 &command_line, base::FilePath(), false); 54 extension_service_->Init(); 55 56 TabHelper::CreateForWebContents(web_contents()); 57 58 script_bubble_controller_ = 59 TabHelper::FromWebContents(web_contents())->script_bubble_controller(); 60 } 61 62 virtual void TearDown() OVERRIDE { 63 #if defined OS_CHROMEOS 64 test_user_manager_.reset(); 65 #endif 66 ChromeRenderViewHostTestHarness::TearDown(); 67 } 68 69 int tab_id() { 70 return ExtensionTabUtil::GetTabId(web_contents()); 71 } 72 73 ExtensionService* extension_service_; 74 ScriptBubbleController* script_bubble_controller_; 75 76 private: 77 FeatureSwitch::ScopedOverride enable_script_bubble_; 78 79 #if defined OS_CHROMEOS 80 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_; 81 chromeos::ScopedTestCrosSettings test_cros_settings_; 82 scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_; 83 #endif 84 }; 85 86 TEST_F(ScriptBubbleControllerTest, Basics) { 87 #if defined(OS_WIN) 88 base::FilePath root(FILE_PATH_LITERAL("c:\\")); 89 #else 90 base::FilePath root(FILE_PATH_LITERAL("/root")); 91 #endif 92 scoped_refptr<const Extension> extension1 = 93 ExtensionBuilder() 94 .SetPath(root.AppendASCII("f1")) 95 .SetManifest(DictionaryBuilder() 96 .Set("name", "ex1") 97 .Set("version", "1") 98 .Set("manifest_version", 2) 99 .Set("permissions", ListBuilder() 100 .Append("activeTab"))) 101 .Build(); 102 103 scoped_refptr<const Extension> extension2 = 104 ExtensionBuilder() 105 .SetPath(root.AppendASCII("f2")) 106 .SetManifest(DictionaryBuilder() 107 .Set("name", "ex2") 108 .Set("version", "1") 109 .Set("manifest_version", 2) 110 .Set("permissions", ListBuilder() 111 .Append("activeTab"))) 112 .Build(); 113 114 scoped_refptr<const Extension> extension3 = 115 ExtensionBuilder() 116 .SetPath(root.AppendASCII("f3")) 117 .SetManifest(DictionaryBuilder() 118 .Set("name", "ex3") 119 .Set("version", "1") 120 .Set("manifest_version", 2) 121 .Set("permissions", ListBuilder() 122 .Append("activeTab"))) 123 .Build(); 124 125 extension_service_->AddExtension(extension1.get()); 126 extension_service_->AddExtension(extension2.get()); 127 extension_service_->AddExtension(extension3.get()); 128 129 EXPECT_EQ(0u, script_bubble_controller_->extensions_running_scripts().size()); 130 131 NavigateAndCommit(GURL("http://www.google.com")); 132 133 // Running a script on the tab causes the bubble to be visible. 134 TabHelper::ScriptExecutionObserver::ExecutingScriptsMap executing_scripts; 135 executing_scripts[extension1->id()].insert("script1"); 136 script_bubble_controller_->OnScriptsExecuted( 137 web_contents(), 138 executing_scripts, 139 web_contents()->GetController().GetActiveEntry()->GetPageID(), 140 web_contents()->GetController().GetActiveEntry()->GetURL()); 141 EXPECT_EQ(1u, script_bubble_controller_->extensions_running_scripts().size()); 142 std::set<std::string> extension_ids; 143 extension_ids.insert(extension1->id()); 144 EXPECT_EQ(1u, script_bubble_controller_->extensions_running_scripts().size()); 145 EXPECT_TRUE(extension_ids == 146 script_bubble_controller_->extensions_running_scripts()); 147 148 // Running a script from another extension increments the count. 149 executing_scripts.clear(); 150 executing_scripts[extension2->id()].insert("script2"); 151 script_bubble_controller_->OnScriptsExecuted( 152 web_contents(), 153 executing_scripts, 154 web_contents()->GetController().GetActiveEntry()->GetPageID(), 155 web_contents()->GetController().GetActiveEntry()->GetURL()); 156 EXPECT_EQ(2u, script_bubble_controller_->extensions_running_scripts().size()); 157 extension_ids.insert(extension2->id()); 158 EXPECT_TRUE(extension_ids == 159 script_bubble_controller_->extensions_running_scripts()); 160 161 // Running another script from an already-seen extension does not affect 162 // count. 163 executing_scripts.clear(); 164 executing_scripts[extension2->id()].insert("script3"); 165 script_bubble_controller_->OnScriptsExecuted( 166 web_contents(), 167 executing_scripts, 168 web_contents()->GetController().GetActiveEntry()->GetPageID(), 169 web_contents()->GetController().GetActiveEntry()->GetURL()); 170 EXPECT_EQ(2u, script_bubble_controller_->extensions_running_scripts().size()); 171 172 // Running tabs.executeScript from an already-seen extension does not affect 173 // count. 174 executing_scripts.clear(); 175 executing_scripts[extension1->id()] = std::set<std::string>(); 176 script_bubble_controller_->OnScriptsExecuted( 177 web_contents(), executing_scripts, 0, GURL()); 178 EXPECT_EQ(2u, script_bubble_controller_->extensions_running_scripts().size()); 179 180 // Running tabs.executeScript from a new extension increments the count. 181 executing_scripts.clear(); 182 executing_scripts[extension3->id()] = std::set<std::string>(); 183 script_bubble_controller_->OnScriptsExecuted( 184 web_contents(), executing_scripts, 0, GURL()); 185 EXPECT_EQ(3u, script_bubble_controller_->extensions_running_scripts().size()); 186 187 // Navigating away resets the badge. 188 NavigateAndCommit(GURL("http://www.google.com")); 189 EXPECT_EQ(0u, script_bubble_controller_->extensions_running_scripts().size()); 190 }; 191 192 } // namespace 193 } // namespace extensions 194