Home | History | Annotate | Download | only in management
      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/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 "chrome/common/extensions/manifest.h"
     21 #include "content/public/test/test_utils.h"
     22 
     23 using extensions::Extension;
     24 using extensions::Manifest;
     25 
     26 namespace {
     27 
     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()) {
     32     if (*it == browser)
     33       continue;
     34     found = *it;
     35   }
     36   return found;
     37 }
     38 
     39 }  // namespace
     40 
     41 class 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 
     98 IN_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 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, NoPermission) {
    112   LoadExtensions();
    113   ASSERT_TRUE(RunExtensionSubtest("management/no_permission", "test.html"));
    114 }
    115 
    116 // Disabled: http://crbug.com/174411
    117 #if defined(OS_WIN)
    118 #define MAYBE_Uninstall DISABLED_Uninstall
    119 #else
    120 #define MAYBE_Uninstall Uninstall
    121 #endif
    122 
    123 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, MAYBE_Uninstall) {
    124   LoadExtensions();
    125   ASSERT_TRUE(RunExtensionSubtest("management/test", "uninstall.html"));
    126 }
    127 
    128 // Fails often on Windows dbg bots. http://crbug.com/177163
    129 #if defined(OS_WIN)
    130 #define MAYBE_ManagementPolicyAllowed DISABLED_ManagementPolicyAllowed
    131 #else
    132 #define MAYBE_ManagementPolicyAllowed ManagementPolicyAllowed
    133 #endif  // defined(OS_WIN)
    134 // Tests actions on extensions when no management policy is in place.
    135 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest,
    136                        MAYBE_ManagementPolicyAllowed) {
    137   LoadExtensions();
    138   ExtensionService* service = extensions::ExtensionSystem::Get(
    139       browser()->profile())->extension_service();
    140   EXPECT_TRUE(service->GetExtensionById(extension_ids_["enabled_extension"],
    141                                         false));
    142 
    143   // Ensure that all actions are allowed.
    144   extensions::ExtensionSystem::Get(
    145       browser()->profile())->management_policy()->UnregisterAllProviders();
    146 
    147   ASSERT_TRUE(RunExtensionSubtest("management/management_policy",
    148                                   "allowed.html"));
    149   // The last thing the test does is uninstall the "enabled_extension".
    150   EXPECT_FALSE(service->GetExtensionById(extension_ids_["enabled_extension"],
    151                                          true));
    152 }
    153 
    154 // Fails often on Windows dbg bots. http://crbug.com/177163
    155 #if defined(OS_WIN)
    156 #define MAYBE_ManagementPolicyProhibited DISABLED_ManagementPolicyProhibited
    157 #else
    158 #define MAYBE_ManagementPolicyProhibited ManagementPolicyProhibited
    159 #endif  // defined(OS_WIN)
    160 // Tests actions on extensions when management policy prohibits those actions.
    161 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest,
    162                        MAYBE_ManagementPolicyProhibited) {
    163   LoadExtensions();
    164   ExtensionService* service = extensions::ExtensionSystem::Get(
    165       browser()->profile())->extension_service();
    166   EXPECT_TRUE(service->GetExtensionById(extension_ids_["enabled_extension"],
    167                                         false));
    168 
    169   // Prohibit status changes.
    170   extensions::ManagementPolicy* policy = extensions::ExtensionSystem::Get(
    171       browser()->profile())->management_policy();
    172   policy->UnregisterAllProviders();
    173   extensions::TestManagementPolicyProvider provider(
    174     extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
    175   policy->RegisterProvider(&provider);
    176   ASSERT_TRUE(RunExtensionSubtest("management/management_policy",
    177                                   "prohibited.html"));
    178 }
    179 
    180 // Disabled. See http://crbug.com/176023
    181 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, DISABLED_LaunchPanelApp) {
    182   ExtensionService* service = extensions::ExtensionSystem::Get(
    183       browser()->profile())->extension_service();
    184 
    185   // Load an extension that calls launchApp() on any app that gets
    186   // installed.
    187   ExtensionTestMessageListener launcher_loaded("launcher loaded", false);
    188   ASSERT_TRUE(LoadExtension(
    189       test_data_dir_.AppendASCII("management/launch_on_install")));
    190   ASSERT_TRUE(launcher_loaded.WaitUntilSatisfied());
    191 
    192   // Load an app with app.launch.container = "panel".
    193   std::string app_id;
    194   LoadAndWaitForLaunch("management/launch_app_panel", &app_id);
    195   ASSERT_FALSE(HasFatalFailure());  // Stop the test if any ASSERT failed.
    196 
    197   // Find the app's browser.  Check that it is a popup.
    198   ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
    199                                         browser()->host_desktop_type()));
    200   Browser* app_browser = FindOtherBrowser(browser());
    201   ASSERT_TRUE(app_browser->is_type_popup());
    202   ASSERT_TRUE(app_browser->is_app());
    203 
    204   // Close the app panel.
    205   content::WindowedNotificationObserver signal(
    206       chrome::NOTIFICATION_BROWSER_CLOSED,
    207       content::Source<Browser>(app_browser));
    208 
    209   chrome::CloseWindow(app_browser);
    210   signal.Wait();
    211 
    212   // Unload the extension.
    213   UninstallExtension(app_id);
    214   ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
    215                                         browser()->host_desktop_type()));
    216   ASSERT_FALSE(service->GetExtensionById(app_id, true));
    217 
    218   // Set a pref indicating that the user wants to launch in a regular tab.
    219   // This should be ignored, because panel apps always load in a popup.
    220   service->extension_prefs()->SetLaunchType(
    221       app_id, extensions::ExtensionPrefs::LAUNCH_REGULAR);
    222 
    223   // Load the extension again.
    224   std::string app_id_new;
    225   LoadAndWaitForLaunch("management/launch_app_panel", &app_id_new);
    226   ASSERT_FALSE(HasFatalFailure());
    227 
    228   // If the ID changed, then the pref will not apply to the app.
    229   ASSERT_EQ(app_id, app_id_new);
    230 
    231   // Find the app's browser.  Apps that should load in a panel ignore
    232   // prefs, so we should still see the launch in a popup.
    233   ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
    234                                         browser()->host_desktop_type()));
    235   app_browser = FindOtherBrowser(browser());
    236   ASSERT_TRUE(app_browser->is_type_popup());
    237   ASSERT_TRUE(app_browser->is_app());
    238 }
    239 
    240 // Disabled: http://crbug.com/230165
    241 #if defined(OS_WIN)
    242 #define MAYBE_LaunchTabApp DISABLED_LaunchTabApp
    243 #else
    244 #define MAYBE_LaunchTabApp LaunchTabApp
    245 #endif
    246 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, MAYBE_LaunchTabApp) {
    247   ExtensionService* service = extensions::ExtensionSystem::Get(
    248       browser()->profile())->extension_service();
    249 
    250   // Load an extension that calls launchApp() on any app that gets
    251   // installed.
    252   ExtensionTestMessageListener launcher_loaded("launcher loaded", false);
    253   ASSERT_TRUE(LoadExtension(
    254       test_data_dir_.AppendASCII("management/launch_on_install")));
    255   ASSERT_TRUE(launcher_loaded.WaitUntilSatisfied());
    256 
    257   // Code below assumes that the test starts with a single browser window
    258   // hosting one tab.
    259   ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
    260                                         browser()->host_desktop_type()));
    261   ASSERT_EQ(1, browser()->tab_strip_model()->count());
    262 
    263   // Load an app with app.launch.container = "tab".
    264   std::string app_id;
    265   LoadAndWaitForLaunch("management/launch_app_tab", &app_id);
    266   ASSERT_FALSE(HasFatalFailure());
    267 
    268   // Check that the app opened in a new tab of the existing browser.
    269   ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
    270                                         browser()->host_desktop_type()));
    271   ASSERT_EQ(2, browser()->tab_strip_model()->count());
    272 
    273   // Unload the extension.
    274   UninstallExtension(app_id);
    275   ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
    276                                         browser()->host_desktop_type()));
    277   ASSERT_FALSE(service->GetExtensionById(app_id, true));
    278 
    279   // Set a pref indicating that the user wants to launch in a window.
    280   service->extension_prefs()->SetLaunchType(
    281       app_id, extensions::ExtensionPrefs::LAUNCH_WINDOW);
    282 
    283   std::string app_id_new;
    284   LoadAndWaitForLaunch("management/launch_app_tab", &app_id_new);
    285   ASSERT_FALSE(HasFatalFailure());
    286 
    287   // If the ID changed, then the pref will not apply to the app.
    288   ASSERT_EQ(app_id, app_id_new);
    289 
    290 #if defined(OS_MACOSX)
    291   // App windows are not yet implemented on mac os.  We should fall back
    292   // to a normal tab.
    293   ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
    294                                         browser()->host_desktop_type()));
    295   ASSERT_EQ(2, browser()->tab_strip_model()->count());
    296 #else
    297   // Find the app's browser.  Opening in a new window will create
    298   // a new browser.
    299   ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
    300                                         browser()->host_desktop_type()));
    301   Browser* app_browser = FindOtherBrowser(browser());
    302   ASSERT_TRUE(app_browser->is_app());
    303 #endif
    304 }
    305