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.
7 #include "chrome/browser/chrome_notification_types.h"
8 #include "chrome/browser/extensions/extension_apitest.h"
9 #include "chrome/browser/extensions/extension_service.h"
10 #include "chrome/browser/extensions/launch_util.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/browser_commands.h"
14 #include "chrome/browser/ui/browser_finder.h"
15 #include "chrome/browser/ui/browser_iterator.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/extensions/extension_constants.h"
19 #include "content/public/test/test_utils.h"
20 #include "extensions/browser/api/management/management_api.h"
21 #include "extensions/browser/extension_system.h"
22 #include "extensions/browser/test_management_policy.h"
23 #include "extensions/common/manifest.h"
24 #include "extensions/test/extension_test_message_listener.h"
26 using extensions::Extension;
27 using extensions::Manifest;
31 // Find a browser other than |browser|.
32 Browser* FindOtherBrowser(Browser* browser) {
33 Browser* found = NULL;
34 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
44 class ExtensionManagementApiTest : public ExtensionApiTest {
46 void SetUpCommandLine(CommandLine* command_line) override {
47 ExtensionApiTest::SetUpCommandLine(command_line);
48 command_line->AppendSwitch(switches::kEnablePanels);
51 virtual void LoadExtensions() {
52 base::FilePath basedir = test_data_dir_.AppendASCII("management");
54 // Load 5 enabled items.
55 LoadNamedExtension(basedir, "enabled_extension");
56 LoadNamedExtension(basedir, "enabled_app");
57 LoadNamedExtension(basedir, "description");
58 LoadNamedExtension(basedir, "permissions");
59 LoadNamedExtension(basedir, "short_name");
61 // Load 2 disabled items.
62 LoadNamedExtension(basedir, "disabled_extension");
63 DisableExtension(extension_ids_["disabled_extension"]);
64 LoadNamedExtension(basedir, "disabled_app");
65 DisableExtension(extension_ids_["disabled_app"]);
68 // Load an app, and wait for a message from app "management/launch_on_install"
69 // indicating that the new app has been launched.
70 void LoadAndWaitForLaunch(const std::string& app_path,
71 std::string* out_app_id) {
72 ExtensionTestMessageListener launched_app("launched app", false);
73 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(app_path)));
76 *out_app_id = last_loaded_extension_id();
78 ASSERT_TRUE(launched_app.WaitUntilSatisfied());
82 void LoadNamedExtension(const base::FilePath& path,
83 const std::string& name) {
84 const Extension* extension = LoadExtension(path.AppendASCII(name));
85 ASSERT_TRUE(extension);
86 extension_ids_[name] = extension->id();
89 void InstallNamedExtension(const base::FilePath& path,
90 const std::string& name,
91 Manifest::Location install_source) {
92 const Extension* extension = InstallExtension(path.AppendASCII(name), 1,
94 ASSERT_TRUE(extension);
95 extension_ids_[name] = extension->id();
98 // Maps installed extension names to their IDs.
99 std::map<std::string, std::string> extension_ids_;
102 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, Basics) {
105 base::FilePath basedir = test_data_dir_.AppendASCII("management");
106 InstallNamedExtension(basedir, "internal_extension", Manifest::INTERNAL);
107 InstallNamedExtension(basedir, "external_extension",
108 Manifest::EXTERNAL_PREF);
109 InstallNamedExtension(basedir, "admin_extension",
110 Manifest::EXTERNAL_POLICY_DOWNLOAD);
112 ASSERT_TRUE(RunExtensionSubtest("management/test", "basics.html"));
115 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, NoPermission) {
117 ASSERT_TRUE(RunExtensionSubtest("management/no_permission", "test.html"));
120 // Disabled: http://crbug.com/174411
122 #define MAYBE_Uninstall DISABLED_Uninstall
124 #define MAYBE_Uninstall Uninstall
127 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, MAYBE_Uninstall) {
129 // Confirmation dialog will be shown for uninstallations except for self.
130 extensions::ManagementUninstallFunction::SetAutoConfirmForTest(true);
131 ASSERT_TRUE(RunExtensionSubtest("management/test", "uninstall.html"));
134 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, CreateAppShortcut) {
136 base::FilePath basedir = test_data_dir_.AppendASCII("management");
137 LoadNamedExtension(basedir, "packaged_app");
139 extensions::ManagementCreateAppShortcutFunction::SetAutoConfirmForTest(true);
140 ASSERT_TRUE(RunExtensionSubtest("management/test",
141 "createAppShortcut.html"));
144 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, GenerateAppForLink) {
146 ASSERT_TRUE(RunExtensionSubtest("management/test",
147 "generateAppForLink.html"));
150 // Fails often on Windows dbg bots. http://crbug.com/177163
152 #define MAYBE_ManagementPolicyAllowed DISABLED_ManagementPolicyAllowed
154 #define MAYBE_ManagementPolicyAllowed ManagementPolicyAllowed
155 #endif // defined(OS_WIN)
156 // Tests actions on extensions when no management policy is in place.
157 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest,
158 MAYBE_ManagementPolicyAllowed) {
160 extensions::ManagementUninstallFunction::SetAutoConfirmForTest(true);
161 ExtensionService* service = extensions::ExtensionSystem::Get(
162 browser()->profile())->extension_service();
163 EXPECT_TRUE(service->GetExtensionById(extension_ids_["enabled_extension"],
166 // Ensure that all actions are allowed.
167 extensions::ExtensionSystem::Get(
168 browser()->profile())->management_policy()->UnregisterAllProviders();
170 ASSERT_TRUE(RunExtensionSubtest("management/management_policy",
172 // The last thing the test does is uninstall the "enabled_extension".
173 EXPECT_FALSE(service->GetExtensionById(extension_ids_["enabled_extension"],
177 // Fails often on Windows dbg bots. http://crbug.com/177163
179 #define MAYBE_ManagementPolicyProhibited DISABLED_ManagementPolicyProhibited
181 #define MAYBE_ManagementPolicyProhibited ManagementPolicyProhibited
182 #endif // defined(OS_WIN)
183 // Tests actions on extensions when management policy prohibits those actions.
184 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest,
185 MAYBE_ManagementPolicyProhibited) {
187 ExtensionService* service = extensions::ExtensionSystem::Get(
188 browser()->profile())->extension_service();
189 EXPECT_TRUE(service->GetExtensionById(extension_ids_["enabled_extension"],
192 // Prohibit status changes.
193 extensions::ManagementPolicy* policy = extensions::ExtensionSystem::Get(
194 browser()->profile())->management_policy();
195 policy->UnregisterAllProviders();
196 extensions::TestManagementPolicyProvider provider(
197 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
198 policy->RegisterProvider(&provider);
199 ASSERT_TRUE(RunExtensionSubtest("management/management_policy",
203 // Disabled. See http://crbug.com/176023
204 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, DISABLED_LaunchPanelApp) {
205 ExtensionService* service = extensions::ExtensionSystem::Get(
206 browser()->profile())->extension_service();
208 // Load an extension that calls launchApp() on any app that gets
210 ExtensionTestMessageListener launcher_loaded("launcher loaded", false);
211 ASSERT_TRUE(LoadExtension(
212 test_data_dir_.AppendASCII("management/launch_on_install")));
213 ASSERT_TRUE(launcher_loaded.WaitUntilSatisfied());
215 // Load an app with app.launch.container = "panel".
217 LoadAndWaitForLaunch("management/launch_app_panel", &app_id);
218 ASSERT_FALSE(HasFatalFailure()); // Stop the test if any ASSERT failed.
220 // Find the app's browser. Check that it is a popup.
221 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
222 browser()->host_desktop_type()));
223 Browser* app_browser = FindOtherBrowser(browser());
224 ASSERT_TRUE(app_browser->is_type_popup());
225 ASSERT_TRUE(app_browser->is_app());
227 // Close the app panel.
228 content::WindowedNotificationObserver signal(
229 chrome::NOTIFICATION_BROWSER_CLOSED,
230 content::Source<Browser>(app_browser));
232 chrome::CloseWindow(app_browser);
235 // Unload the extension.
236 UninstallExtension(app_id);
237 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
238 browser()->host_desktop_type()));
239 ASSERT_FALSE(service->GetExtensionById(app_id, true));
241 // Set a pref indicating that the user wants to launch in a regular tab.
242 // This should be ignored, because panel apps always load in a popup.
243 extensions::SetLaunchType(service, app_id, extensions::LAUNCH_TYPE_REGULAR);
245 // Load the extension again.
246 std::string app_id_new;
247 LoadAndWaitForLaunch("management/launch_app_panel", &app_id_new);
248 ASSERT_FALSE(HasFatalFailure());
250 // If the ID changed, then the pref will not apply to the app.
251 ASSERT_EQ(app_id, app_id_new);
253 // Find the app's browser. Apps that should load in a panel ignore
254 // prefs, so we should still see the launch in a popup.
255 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
256 browser()->host_desktop_type()));
257 app_browser = FindOtherBrowser(browser());
258 ASSERT_TRUE(app_browser->is_type_popup());
259 ASSERT_TRUE(app_browser->is_app());
262 // Disabled: http://crbug.com/230165
264 #define MAYBE_LaunchTabApp DISABLED_LaunchTabApp
266 #define MAYBE_LaunchTabApp LaunchTabApp
268 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, MAYBE_LaunchTabApp) {
269 ExtensionService* service = extensions::ExtensionSystem::Get(
270 browser()->profile())->extension_service();
272 // Load an extension that calls launchApp() on any app that gets
274 ExtensionTestMessageListener launcher_loaded("launcher loaded", false);
275 ASSERT_TRUE(LoadExtension(
276 test_data_dir_.AppendASCII("management/launch_on_install")));
277 ASSERT_TRUE(launcher_loaded.WaitUntilSatisfied());
279 // Code below assumes that the test starts with a single browser window
281 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
282 browser()->host_desktop_type()));
283 ASSERT_EQ(1, browser()->tab_strip_model()->count());
285 // Load an app with app.launch.container = "tab".
287 LoadAndWaitForLaunch("management/launch_app_tab", &app_id);
288 ASSERT_FALSE(HasFatalFailure());
290 // Check that the app opened in a new tab of the existing browser.
291 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
292 browser()->host_desktop_type()));
293 ASSERT_EQ(2, browser()->tab_strip_model()->count());
295 // Unload the extension.
296 UninstallExtension(app_id);
297 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
298 browser()->host_desktop_type()));
299 ASSERT_FALSE(service->GetExtensionById(app_id, true));
301 // Set a pref indicating that the user wants to launch in a window.
302 extensions::SetLaunchType(service, app_id, extensions::LAUNCH_TYPE_WINDOW);
304 std::string app_id_new;
305 LoadAndWaitForLaunch("management/launch_app_tab", &app_id_new);
306 ASSERT_FALSE(HasFatalFailure());
308 // If the ID changed, then the pref will not apply to the app.
309 ASSERT_EQ(app_id, app_id_new);
311 #if defined(OS_MACOSX)
312 // App windows are not yet implemented on mac os. We should fall back
314 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
315 browser()->host_desktop_type()));
316 ASSERT_EQ(2, browser()->tab_strip_model()->count());
318 // Find the app's browser. Opening in a new window will create
320 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
321 browser()->host_desktop_type()));
322 Browser* app_browser = FindOtherBrowser(browser());
323 ASSERT_TRUE(app_browser->is_app());
327 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, LaunchType) {
329 base::FilePath basedir = test_data_dir_.AppendASCII("management");
330 LoadNamedExtension(basedir, "packaged_app");
332 ASSERT_TRUE(RunExtensionSubtest("management/test", "launchType.html"));
335 class ExtensionManagementApiStreamlinedAppsTest
336 : public ExtensionManagementApiTest {
338 void SetUpCommandLine(CommandLine* command_line) override {
339 ExtensionManagementApiTest::SetUpCommandLine(command_line);
340 command_line->AppendSwitch(switches::kEnableStreamlinedHostedApps);
344 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiStreamlinedAppsTest, LaunchType) {
346 base::FilePath basedir = test_data_dir_.AppendASCII("management");
347 LoadNamedExtension(basedir, "packaged_app");
349 ASSERT_TRUE(RunExtensionSubtest("management/test",
350 "launchType.html?streamlined-hosted-apps"));