management_apitest.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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 <map> 6 7#include "chrome/browser/extensions/extension_apitest.h" 8#include "chrome/browser/extensions/extension_service.h" 9#include "chrome/browser/extensions/extension_system.h" 10#include "chrome/browser/extensions/extension_test_message_listener.h" 11#include "chrome/browser/extensions/test_management_policy.h" 12#include "chrome/browser/profiles/profile.h" 13#include "chrome/browser/ui/browser.h" 14#include "chrome/browser/ui/browser_commands.h" 15#include "chrome/browser/ui/browser_finder.h" 16#include "chrome/browser/ui/browser_iterator.h" 17#include "chrome/browser/ui/tabs/tab_strip_model.h" 18#include "chrome/common/chrome_notification_types.h" 19#include "chrome/common/chrome_switches.h" 20#include "chrome/common/extensions/manifest.h" 21#include "content/public/test/test_utils.h" 22 23using extensions::Extension; 24using extensions::Manifest; 25 26namespace { 27 28// Find a browser other than |browser|. 29Browser* FindOtherBrowser(Browser* browser) { 30 Browser* found = NULL; 31 for (chrome::BrowserIterator it; !it.done(); it.Next()) { 32 if (*it == browser) 33 continue; 34 found = *it; 35 } 36 return found; 37} 38 39} // namespace 40 41class ExtensionManagementApiTest : public ExtensionApiTest { 42 public: 43 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 44 ExtensionApiTest::SetUpCommandLine(command_line); 45 command_line->AppendSwitch(switches::kEnablePanels); 46 } 47 48 virtual void LoadExtensions() { 49 base::FilePath basedir = test_data_dir_.AppendASCII("management"); 50 51 // Load 4 enabled items. 52 LoadNamedExtension(basedir, "enabled_extension"); 53 LoadNamedExtension(basedir, "enabled_app"); 54 LoadNamedExtension(basedir, "description"); 55 LoadNamedExtension(basedir, "permissions"); 56 57 // Load 2 disabled items. 58 LoadNamedExtension(basedir, "disabled_extension"); 59 DisableExtension(extension_ids_["disabled_extension"]); 60 LoadNamedExtension(basedir, "disabled_app"); 61 DisableExtension(extension_ids_["disabled_app"]); 62 } 63 64 // Load an app, and wait for a message from app "management/launch_on_install" 65 // indicating that the new app has been launched. 66 void LoadAndWaitForLaunch(const std::string& app_path, 67 std::string* out_app_id) { 68 ExtensionTestMessageListener launched_app("launched app", false); 69 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(app_path))); 70 71 if (out_app_id) 72 *out_app_id = last_loaded_extension_id_; 73 74 ASSERT_TRUE(launched_app.WaitUntilSatisfied()); 75 } 76 77 protected: 78 void LoadNamedExtension(const base::FilePath& path, 79 const std::string& name) { 80 const Extension* extension = LoadExtension(path.AppendASCII(name)); 81 ASSERT_TRUE(extension); 82 extension_ids_[name] = extension->id(); 83 } 84 85 void InstallNamedExtension(const base::FilePath& path, 86 const std::string& name, 87 Manifest::Location install_source) { 88 const Extension* extension = InstallExtension(path.AppendASCII(name), 1, 89 install_source); 90 ASSERT_TRUE(extension); 91 extension_ids_[name] = extension->id(); 92 } 93 94 // Maps installed extension names to their IDs. 95 std::map<std::string, std::string> extension_ids_; 96}; 97 98IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, Basics) { 99 LoadExtensions(); 100 101 base::FilePath basedir = test_data_dir_.AppendASCII("management"); 102 InstallNamedExtension(basedir, "internal_extension", Manifest::INTERNAL); 103 InstallNamedExtension(basedir, "external_extension", 104 Manifest::EXTERNAL_PREF); 105 InstallNamedExtension(basedir, "admin_extension", 106 Manifest::EXTERNAL_POLICY_DOWNLOAD); 107 108 ASSERT_TRUE(RunExtensionSubtest("management/test", "basics.html")); 109} 110 111// Disabled: http://crbug.com/174411 112#if defined(OS_WIN) 113#define MAYBE_Uninstall DISABLED_Uninstall 114#else 115#define MAYBE_Uninstall Uninstall 116#endif 117 118IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, MAYBE_Uninstall) { 119 LoadExtensions(); 120 ASSERT_TRUE(RunExtensionSubtest("management/test", "uninstall.html")); 121} 122 123// Fails often on Windows dbg bots. http://crbug.com/177163 124#if defined(OS_WIN) 125#define MAYBE_ManagementPolicyAllowed DISABLED_ManagementPolicyAllowed 126#else 127#define MAYBE_ManagementPolicyAllowed ManagementPolicyAllowed 128#endif // defined(OS_WIN) 129// Tests actions on extensions when no management policy is in place. 130IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, 131 MAYBE_ManagementPolicyAllowed) { 132 LoadExtensions(); 133 ExtensionService* service = extensions::ExtensionSystem::Get( 134 browser()->profile())->extension_service(); 135 EXPECT_TRUE(service->GetExtensionById(extension_ids_["enabled_extension"], 136 false)); 137 138 // Ensure that all actions are allowed. 139 extensions::ExtensionSystem::Get( 140 browser()->profile())->management_policy()->UnregisterAllProviders(); 141 142 ASSERT_TRUE(RunExtensionSubtest("management/management_policy", 143 "allowed.html")); 144 // The last thing the test does is uninstall the "enabled_extension". 145 EXPECT_FALSE(service->GetExtensionById(extension_ids_["enabled_extension"], 146 true)); 147} 148 149// Fails often on Windows dbg bots. http://crbug.com/177163 150#if defined(OS_WIN) 151#define MAYBE_ManagementPolicyProhibited DISABLED_ManagementPolicyProhibited 152#else 153#define MAYBE_ManagementPolicyProhibited ManagementPolicyProhibited 154#endif // defined(OS_WIN) 155// Tests actions on extensions when management policy prohibits those actions. 156IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, 157 MAYBE_ManagementPolicyProhibited) { 158 LoadExtensions(); 159 ExtensionService* service = extensions::ExtensionSystem::Get( 160 browser()->profile())->extension_service(); 161 EXPECT_TRUE(service->GetExtensionById(extension_ids_["enabled_extension"], 162 false)); 163 164 // Prohibit status changes. 165 extensions::ManagementPolicy* policy = extensions::ExtensionSystem::Get( 166 browser()->profile())->management_policy(); 167 policy->UnregisterAllProviders(); 168 extensions::TestManagementPolicyProvider provider( 169 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS); 170 policy->RegisterProvider(&provider); 171 ASSERT_TRUE(RunExtensionSubtest("management/management_policy", 172 "prohibited.html")); 173} 174 175// Disabled. See http://crbug.com/176023 176IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, DISABLED_LaunchPanelApp) { 177 ExtensionService* service = extensions::ExtensionSystem::Get( 178 browser()->profile())->extension_service(); 179 180 // Load an extension that calls launchApp() on any app that gets 181 // installed. 182 ExtensionTestMessageListener launcher_loaded("launcher loaded", false); 183 ASSERT_TRUE(LoadExtension( 184 test_data_dir_.AppendASCII("management/launch_on_install"))); 185 ASSERT_TRUE(launcher_loaded.WaitUntilSatisfied()); 186 187 // Load an app with app.launch.container = "panel". 188 std::string app_id; 189 LoadAndWaitForLaunch("management/launch_app_panel", &app_id); 190 ASSERT_FALSE(HasFatalFailure()); // Stop the test if any ASSERT failed. 191 192 // Find the app's browser. Check that it is a popup. 193 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(), 194 browser()->host_desktop_type())); 195 Browser* app_browser = FindOtherBrowser(browser()); 196 ASSERT_TRUE(app_browser->is_type_popup()); 197 ASSERT_TRUE(app_browser->is_app()); 198 199 // Close the app panel. 200 content::WindowedNotificationObserver signal( 201 chrome::NOTIFICATION_BROWSER_CLOSED, 202 content::Source<Browser>(app_browser)); 203 204 chrome::CloseWindow(app_browser); 205 signal.Wait(); 206 207 // Unload the extension. 208 UninstallExtension(app_id); 209 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(), 210 browser()->host_desktop_type())); 211 ASSERT_FALSE(service->GetExtensionById(app_id, true)); 212 213 // Set a pref indicating that the user wants to launch in a regular tab. 214 // This should be ignored, because panel apps always load in a popup. 215 service->extension_prefs()->SetLaunchType( 216 app_id, extensions::ExtensionPrefs::LAUNCH_REGULAR); 217 218 // Load the extension again. 219 std::string app_id_new; 220 LoadAndWaitForLaunch("management/launch_app_panel", &app_id_new); 221 ASSERT_FALSE(HasFatalFailure()); 222 223 // If the ID changed, then the pref will not apply to the app. 224 ASSERT_EQ(app_id, app_id_new); 225 226 // Find the app's browser. Apps that should load in a panel ignore 227 // prefs, so we should still see the launch in a popup. 228 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(), 229 browser()->host_desktop_type())); 230 app_browser = FindOtherBrowser(browser()); 231 ASSERT_TRUE(app_browser->is_type_popup()); 232 ASSERT_TRUE(app_browser->is_app()); 233} 234 235// Disabled: http://crbug.com/230165 236#if defined(OS_WIN) 237#define MAYBE_LaunchTabApp DISABLED_LaunchTabApp 238#else 239#define MAYBE_LaunchTabApp LaunchTabApp 240#endif 241IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, MAYBE_LaunchTabApp) { 242 ExtensionService* service = extensions::ExtensionSystem::Get( 243 browser()->profile())->extension_service(); 244 245 // Load an extension that calls launchApp() on any app that gets 246 // installed. 247 ExtensionTestMessageListener launcher_loaded("launcher loaded", false); 248 ASSERT_TRUE(LoadExtension( 249 test_data_dir_.AppendASCII("management/launch_on_install"))); 250 ASSERT_TRUE(launcher_loaded.WaitUntilSatisfied()); 251 252 // Code below assumes that the test starts with a single browser window 253 // hosting one tab. 254 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(), 255 browser()->host_desktop_type())); 256 ASSERT_EQ(1, browser()->tab_strip_model()->count()); 257 258 // Load an app with app.launch.container = "tab". 259 std::string app_id; 260 LoadAndWaitForLaunch("management/launch_app_tab", &app_id); 261 ASSERT_FALSE(HasFatalFailure()); 262 263 // Check that the app opened in a new tab of the existing browser. 264 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(), 265 browser()->host_desktop_type())); 266 ASSERT_EQ(2, browser()->tab_strip_model()->count()); 267 268 // Unload the extension. 269 UninstallExtension(app_id); 270 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(), 271 browser()->host_desktop_type())); 272 ASSERT_FALSE(service->GetExtensionById(app_id, true)); 273 274 // Set a pref indicating that the user wants to launch in a window. 275 service->extension_prefs()->SetLaunchType( 276 app_id, extensions::ExtensionPrefs::LAUNCH_WINDOW); 277 278 std::string app_id_new; 279 LoadAndWaitForLaunch("management/launch_app_tab", &app_id_new); 280 ASSERT_FALSE(HasFatalFailure()); 281 282 // If the ID changed, then the pref will not apply to the app. 283 ASSERT_EQ(app_id, app_id_new); 284 285#if defined(OS_MACOSX) 286 // App windows are not yet implemented on mac os. We should fall back 287 // to a normal tab. 288 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(), 289 browser()->host_desktop_type())); 290 ASSERT_EQ(2, browser()->tab_strip_model()->count()); 291#else 292 // Find the app's browser. Opening in a new window will create 293 // a new browser. 294 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(), 295 browser()->host_desktop_type())); 296 Browser* app_browser = FindOtherBrowser(browser()); 297 ASSERT_TRUE(app_browser->is_app()); 298#endif 299} 300