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/extension_system.h"
11 #include "chrome/browser/extensions/extension_test_message_listener.h"
12 #include "chrome/browser/extensions/test_management_policy.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/browser_commands.h"
16 #include "chrome/browser/ui/browser_finder.h"
17 #include "chrome/browser/ui/browser_iterator.h"
18 #include "chrome/browser/ui/tabs/tab_strip_model.h"
19 #include "chrome/common/chrome_switches.h"
20 #include "content/public/test/test_utils.h"
21 #include "extensions/common/manifest.h"
23 using extensions::Extension;
24 using extensions::Manifest;
28 // Find a browser other than |browser|.
29 Browser* FindOtherBrowser(Browser* browser) {
30 Browser* found = NULL;
31 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
41 class ExtensionManagementApiTest : public ExtensionApiTest {
43 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
44 ExtensionApiTest::SetUpCommandLine(command_line);
45 command_line->AppendSwitch(switches::kEnablePanels);
48 virtual void LoadExtensions() {
49 base::FilePath basedir = test_data_dir_.AppendASCII("management");
51 // Load 5 enabled items.
52 LoadNamedExtension(basedir, "enabled_extension");
53 LoadNamedExtension(basedir, "enabled_app");
54 LoadNamedExtension(basedir, "description");
55 LoadNamedExtension(basedir, "permissions");
56 LoadNamedExtension(basedir, "short_name");
58 // Load 2 disabled items.
59 LoadNamedExtension(basedir, "disabled_extension");
60 DisableExtension(extension_ids_["disabled_extension"]);
61 LoadNamedExtension(basedir, "disabled_app");
62 DisableExtension(extension_ids_["disabled_app"]);
65 // Load an app, and wait for a message from app "management/launch_on_install"
66 // indicating that the new app has been launched.
67 void LoadAndWaitForLaunch(const std::string& app_path,
68 std::string* out_app_id) {
69 ExtensionTestMessageListener launched_app("launched app", false);
70 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(app_path)));
73 *out_app_id = last_loaded_extension_id();
75 ASSERT_TRUE(launched_app.WaitUntilSatisfied());
79 void LoadNamedExtension(const base::FilePath& path,
80 const std::string& name) {
81 const Extension* extension = LoadExtension(path.AppendASCII(name));
82 ASSERT_TRUE(extension);
83 extension_ids_[name] = extension->id();
86 void InstallNamedExtension(const base::FilePath& path,
87 const std::string& name,
88 Manifest::Location install_source) {
89 const Extension* extension = InstallExtension(path.AppendASCII(name), 1,
91 ASSERT_TRUE(extension);
92 extension_ids_[name] = extension->id();
95 // Maps installed extension names to their IDs.
96 std::map<std::string, std::string> extension_ids_;
99 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, Basics) {
102 base::FilePath basedir = test_data_dir_.AppendASCII("management");
103 InstallNamedExtension(basedir, "internal_extension", Manifest::INTERNAL);
104 InstallNamedExtension(basedir, "external_extension",
105 Manifest::EXTERNAL_PREF);
106 InstallNamedExtension(basedir, "admin_extension",
107 Manifest::EXTERNAL_POLICY_DOWNLOAD);
109 ASSERT_TRUE(RunExtensionSubtest("management/test", "basics.html"));
112 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, NoPermission) {
114 ASSERT_TRUE(RunExtensionSubtest("management/no_permission", "test.html"));
117 // Disabled: http://crbug.com/174411
119 #define MAYBE_Uninstall DISABLED_Uninstall
121 #define MAYBE_Uninstall Uninstall
124 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, MAYBE_Uninstall) {
126 ASSERT_TRUE(RunExtensionSubtest("management/test", "uninstall.html"));
129 // Fails often on Windows dbg bots. http://crbug.com/177163
131 #define MAYBE_ManagementPolicyAllowed DISABLED_ManagementPolicyAllowed
133 #define MAYBE_ManagementPolicyAllowed ManagementPolicyAllowed
134 #endif // defined(OS_WIN)
135 // Tests actions on extensions when no management policy is in place.
136 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest,
137 MAYBE_ManagementPolicyAllowed) {
139 ExtensionService* service = extensions::ExtensionSystem::Get(
140 browser()->profile())->extension_service();
141 EXPECT_TRUE(service->GetExtensionById(extension_ids_["enabled_extension"],
144 // Ensure that all actions are allowed.
145 extensions::ExtensionSystem::Get(
146 browser()->profile())->management_policy()->UnregisterAllProviders();
148 ASSERT_TRUE(RunExtensionSubtest("management/management_policy",
150 // The last thing the test does is uninstall the "enabled_extension".
151 EXPECT_FALSE(service->GetExtensionById(extension_ids_["enabled_extension"],
155 // Fails often on Windows dbg bots. http://crbug.com/177163
157 #define MAYBE_ManagementPolicyProhibited DISABLED_ManagementPolicyProhibited
159 #define MAYBE_ManagementPolicyProhibited ManagementPolicyProhibited
160 #endif // defined(OS_WIN)
161 // Tests actions on extensions when management policy prohibits those actions.
162 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest,
163 MAYBE_ManagementPolicyProhibited) {
165 ExtensionService* service = extensions::ExtensionSystem::Get(
166 browser()->profile())->extension_service();
167 EXPECT_TRUE(service->GetExtensionById(extension_ids_["enabled_extension"],
170 // Prohibit status changes.
171 extensions::ManagementPolicy* policy = extensions::ExtensionSystem::Get(
172 browser()->profile())->management_policy();
173 policy->UnregisterAllProviders();
174 extensions::TestManagementPolicyProvider provider(
175 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
176 policy->RegisterProvider(&provider);
177 ASSERT_TRUE(RunExtensionSubtest("management/management_policy",
181 // Disabled. See http://crbug.com/176023
182 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, DISABLED_LaunchPanelApp) {
183 ExtensionService* service = extensions::ExtensionSystem::Get(
184 browser()->profile())->extension_service();
186 // Load an extension that calls launchApp() on any app that gets
188 ExtensionTestMessageListener launcher_loaded("launcher loaded", false);
189 ASSERT_TRUE(LoadExtension(
190 test_data_dir_.AppendASCII("management/launch_on_install")));
191 ASSERT_TRUE(launcher_loaded.WaitUntilSatisfied());
193 // Load an app with app.launch.container = "panel".
195 LoadAndWaitForLaunch("management/launch_app_panel", &app_id);
196 ASSERT_FALSE(HasFatalFailure()); // Stop the test if any ASSERT failed.
198 // Find the app's browser. Check that it is a popup.
199 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
200 browser()->host_desktop_type()));
201 Browser* app_browser = FindOtherBrowser(browser());
202 ASSERT_TRUE(app_browser->is_type_popup());
203 ASSERT_TRUE(app_browser->is_app());
205 // Close the app panel.
206 content::WindowedNotificationObserver signal(
207 chrome::NOTIFICATION_BROWSER_CLOSED,
208 content::Source<Browser>(app_browser));
210 chrome::CloseWindow(app_browser);
213 // Unload the extension.
214 UninstallExtension(app_id);
215 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
216 browser()->host_desktop_type()));
217 ASSERT_FALSE(service->GetExtensionById(app_id, true));
219 // Set a pref indicating that the user wants to launch in a regular tab.
220 // This should be ignored, because panel apps always load in a popup.
221 service->extension_prefs()->SetLaunchType(
222 app_id, extensions::ExtensionPrefs::LAUNCH_REGULAR);
224 // Load the extension again.
225 std::string app_id_new;
226 LoadAndWaitForLaunch("management/launch_app_panel", &app_id_new);
227 ASSERT_FALSE(HasFatalFailure());
229 // If the ID changed, then the pref will not apply to the app.
230 ASSERT_EQ(app_id, app_id_new);
232 // Find the app's browser. Apps that should load in a panel ignore
233 // prefs, so we should still see the launch in a popup.
234 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
235 browser()->host_desktop_type()));
236 app_browser = FindOtherBrowser(browser());
237 ASSERT_TRUE(app_browser->is_type_popup());
238 ASSERT_TRUE(app_browser->is_app());
241 // Disabled: http://crbug.com/230165
243 #define MAYBE_LaunchTabApp DISABLED_LaunchTabApp
245 #define MAYBE_LaunchTabApp LaunchTabApp
247 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, MAYBE_LaunchTabApp) {
248 ExtensionService* service = extensions::ExtensionSystem::Get(
249 browser()->profile())->extension_service();
251 // Load an extension that calls launchApp() on any app that gets
253 ExtensionTestMessageListener launcher_loaded("launcher loaded", false);
254 ASSERT_TRUE(LoadExtension(
255 test_data_dir_.AppendASCII("management/launch_on_install")));
256 ASSERT_TRUE(launcher_loaded.WaitUntilSatisfied());
258 // Code below assumes that the test starts with a single browser window
260 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
261 browser()->host_desktop_type()));
262 ASSERT_EQ(1, browser()->tab_strip_model()->count());
264 // Load an app with app.launch.container = "tab".
266 LoadAndWaitForLaunch("management/launch_app_tab", &app_id);
267 ASSERT_FALSE(HasFatalFailure());
269 // Check that the app opened in a new tab of the existing browser.
270 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
271 browser()->host_desktop_type()));
272 ASSERT_EQ(2, browser()->tab_strip_model()->count());
274 // Unload the extension.
275 UninstallExtension(app_id);
276 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
277 browser()->host_desktop_type()));
278 ASSERT_FALSE(service->GetExtensionById(app_id, true));
280 // Set a pref indicating that the user wants to launch in a window.
281 service->extension_prefs()->SetLaunchType(
282 app_id, extensions::ExtensionPrefs::LAUNCH_WINDOW);
284 std::string app_id_new;
285 LoadAndWaitForLaunch("management/launch_app_tab", &app_id_new);
286 ASSERT_FALSE(HasFatalFailure());
288 // If the ID changed, then the pref will not apply to the app.
289 ASSERT_EQ(app_id, app_id_new);
291 #if defined(OS_MACOSX)
292 // App windows are not yet implemented on mac os. We should fall back
294 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
295 browser()->host_desktop_type()));
296 ASSERT_EQ(2, browser()->tab_strip_model()->count());
298 // Find the app's browser. Opening in a new window will create
300 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
301 browser()->host_desktop_type()));
302 Browser* app_browser = FindOtherBrowser(browser());
303 ASSERT_TRUE(app_browser->is_app());