Home | History | Annotate | Download | only in ui
      1 // Copyright (c) 2011 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 "base/command_line.h"
      6 #include "base/file_path.h"
      7 #include "base/utf_string_conversions.h"
      8 #include "chrome/browser/extensions/extension_browsertest.h"
      9 #include "chrome/browser/extensions/extension_service.h"
     10 #include "chrome/browser/profiles/profile.h"
     11 #include "chrome/browser/ui/browser.h"
     12 #include "chrome/browser/ui/browser_init.h"
     13 #include "chrome/browser/ui/browser_list.h"
     14 #include "chrome/browser/ui/browser_window.h"
     15 #include "chrome/common/chrome_switches.h"
     16 #include "chrome/test/in_process_browser_test.h"
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 
     19 class BrowserInitTest : public ExtensionBrowserTest {
     20  protected:
     21   // Helper functions return void so that we can ASSERT*().
     22   // Use ASSERT_FALSE(HasFatalFailure()) after calling these functions
     23   // to stop the test if an assert fails.
     24   void LoadApp(const std::string& app_name,
     25                const Extension** out_app_extension) {
     26     ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(app_name.c_str())));
     27 
     28     ExtensionService* service = browser()->profile()->GetExtensionService();
     29     *out_app_extension = service->GetExtensionById(
     30         last_loaded_extension_id_, false);
     31     ASSERT_TRUE(*out_app_extension);
     32 
     33     // Code that opens a new browser assumes we start with exactly one.
     34     ASSERT_EQ(1u, BrowserList::GetBrowserCount(browser()->profile()));
     35   }
     36 
     37   void SetAppLaunchPref(const std::string& app_id,
     38                         ExtensionPrefs::LaunchType launch_type) {
     39     ExtensionService* service = browser()->profile()->GetExtensionService();
     40     service->extension_prefs()->SetLaunchType(app_id, launch_type);
     41   }
     42 
     43   // Check that there are two browsers.  Find the one that is not |browser()|.
     44   void FindOneOtherBrowser(Browser** out_other_browser) {
     45     // There should only be one other browser.
     46     ASSERT_EQ(2u, BrowserList::GetBrowserCount(browser()->profile()));
     47 
     48     // Find the new browser.
     49     Browser* other_browser = NULL;
     50     for (BrowserList::const_iterator i = BrowserList::begin();
     51          i != BrowserList::end() && !other_browser; ++i) {
     52       if (*i != browser())
     53         other_browser = *i;
     54     }
     55     ASSERT_TRUE(other_browser);
     56     ASSERT_TRUE(other_browser != browser());
     57     *out_other_browser = other_browser;
     58   }
     59 };
     60 
     61 class OpenURLsPopupObserver : public BrowserList::Observer {
     62  public:
     63   OpenURLsPopupObserver() : added_browser_(NULL) { }
     64 
     65   virtual void OnBrowserAdded(const Browser* browser) {
     66     added_browser_ = browser;
     67   }
     68 
     69   virtual void OnBrowserRemoved(const Browser* browser) { }
     70 
     71   const Browser* added_browser_;
     72 };
     73 
     74 // Test that when there is a popup as the active browser any requests to
     75 // BrowserInit::LaunchWithProfile::OpenURLsInBrowser don't crash because
     76 // there's no explicit profile given.
     77 IN_PROC_BROWSER_TEST_F(BrowserInitTest, OpenURLsPopup) {
     78   std::vector<GURL> urls;
     79   urls.push_back(GURL("http://localhost"));
     80 
     81   // Note that in our testing we do not ever query the BrowserList for the "last
     82   // active" browser. That's because the browsers are set as "active" by
     83   // platform UI toolkit messages, and those messages are not sent during unit
     84   // testing sessions.
     85 
     86   OpenURLsPopupObserver observer;
     87   BrowserList::AddObserver(&observer);
     88 
     89   Browser* popup = Browser::CreateForType(Browser::TYPE_POPUP,
     90                                           browser()->profile());
     91   ASSERT_EQ(popup->type(), Browser::TYPE_POPUP);
     92   ASSERT_EQ(popup, observer.added_browser_);
     93 
     94   CommandLine dummy(CommandLine::NO_PROGRAM);
     95   BrowserInit::LaunchWithProfile launch(FilePath(), dummy);
     96   // This should create a new window, but re-use the profile from |popup|. If
     97   // it used a NULL or invalid profile, it would crash.
     98   launch.OpenURLsInBrowser(popup, false, urls);
     99   ASSERT_NE(popup, observer.added_browser_);
    100   BrowserList::RemoveObserver(&observer);
    101 }
    102 
    103 // App shortcuts are not implemented on mac os.
    104 #if !defined(OS_MACOSX)
    105 IN_PROC_BROWSER_TEST_F(BrowserInitTest, OpenAppShortcutNoPref) {
    106   // Load an app with launch.container = 'tab'.
    107   const Extension* extension_app = NULL;
    108   LoadApp("app_with_tab_container", &extension_app);
    109   ASSERT_FALSE(HasFatalFailure());  // Check for ASSERT failures in LoadApp().
    110 
    111   // Add --app-id=<extension->id()> to the command line.
    112   CommandLine command_line(CommandLine::NO_PROGRAM);
    113   command_line.AppendSwitchASCII(switches::kAppId, extension_app->id());
    114 
    115   BrowserInit::LaunchWithProfile launch(FilePath(), command_line);
    116   ASSERT_TRUE(launch.Launch(browser()->profile(), std::vector<GURL>(), false));
    117 
    118   // No pref was set, so the app should have opened in a window.
    119   // The launch should have created a new browser.
    120   Browser* new_browser = NULL;
    121   FindOneOtherBrowser(&new_browser);
    122   ASSERT_FALSE(HasFatalFailure());
    123 
    124   // Expect an app window.
    125   EXPECT_EQ(Browser::TYPE_APP, new_browser->type());
    126 
    127   // The browser's app_name should include the app's ID.
    128   EXPECT_NE(
    129       new_browser->app_name_.find(extension_app->id()),
    130       std::string::npos) << new_browser->app_name_;
    131 }
    132 
    133 IN_PROC_BROWSER_TEST_F(BrowserInitTest, OpenAppShortcutWindowPref) {
    134   const Extension* extension_app = NULL;
    135   LoadApp("app_with_tab_container", &extension_app);
    136   ASSERT_FALSE(HasFatalFailure());  // Check for ASSERT failures in LoadApp().
    137 
    138   // Set a pref indicating that the user wants to open this app in a window.
    139   SetAppLaunchPref(extension_app->id(), ExtensionPrefs::LAUNCH_WINDOW);
    140 
    141   CommandLine command_line(CommandLine::NO_PROGRAM);
    142   command_line.AppendSwitchASCII(switches::kAppId, extension_app->id());
    143   BrowserInit::LaunchWithProfile launch(FilePath(), command_line);
    144   ASSERT_TRUE(launch.Launch(browser()->profile(), std::vector<GURL>(), false));
    145 
    146   // Pref was set to open in a window, so the app should have opened in a
    147   // window.  The launch should have created a new browser. Find the new
    148   // browser.
    149   Browser* new_browser = NULL;
    150   FindOneOtherBrowser(&new_browser);
    151   ASSERT_FALSE(HasFatalFailure());
    152 
    153   // Expect an app window.
    154   EXPECT_EQ(Browser::TYPE_APP, new_browser->type());
    155 
    156   // The browser's app_name should include the app's ID.
    157   EXPECT_NE(
    158       new_browser->app_name_.find(extension_app->id()),
    159       std::string::npos) << new_browser->app_name_;
    160 }
    161 
    162 IN_PROC_BROWSER_TEST_F(BrowserInitTest, OpenAppShortcutTabPref) {
    163   // Load an app with launch.container = 'tab'.
    164   const Extension* extension_app = NULL;
    165   LoadApp("app_with_tab_container", &extension_app);
    166   ASSERT_FALSE(HasFatalFailure());  // Check for ASSERT failures in LoadApp().
    167 
    168   // Set a pref indicating that the user wants to open this app in a window.
    169   SetAppLaunchPref(extension_app->id(), ExtensionPrefs::LAUNCH_REGULAR);
    170 
    171   CommandLine command_line(CommandLine::NO_PROGRAM);
    172   command_line.AppendSwitchASCII(switches::kAppId, extension_app->id());
    173   BrowserInit::LaunchWithProfile launch(FilePath(), command_line);
    174   ASSERT_TRUE(launch.Launch(browser()->profile(), std::vector<GURL>(), false));
    175 
    176   // When an app shortcut is open and the pref indicates a tab should
    177   // open, the tab is open in a new browser window.  Expect a new window.
    178   ASSERT_EQ(2u, BrowserList::GetBrowserCount(browser()->profile()));
    179 
    180   Browser* new_browser = NULL;
    181   FindOneOtherBrowser(&new_browser);
    182   ASSERT_FALSE(HasFatalFailure());
    183 
    184   // The tab should be in a normal window.
    185   EXPECT_EQ(Browser::TYPE_NORMAL, new_browser->type());
    186 
    187   // The browser's app_name should not include the app's ID: It is in a
    188   // normal browser.
    189   EXPECT_EQ(
    190       new_browser->app_name_.find(extension_app->id()),
    191       std::string::npos) << new_browser->app_name_;
    192 }
    193 
    194 IN_PROC_BROWSER_TEST_F(BrowserInitTest, OpenAppShortcutPanel) {
    195   // Load an app with launch.container = 'panel'.
    196   const Extension* extension_app = NULL;
    197   LoadApp("app_with_panel_container", &extension_app);
    198   ASSERT_FALSE(HasFatalFailure());  // Check for ASSERT failures in LoadApp().
    199 
    200   CommandLine command_line(CommandLine::NO_PROGRAM);
    201   command_line.AppendSwitchASCII(switches::kAppId, extension_app->id());
    202   BrowserInit::LaunchWithProfile launch(FilePath(), command_line);
    203   ASSERT_TRUE(launch.Launch(browser()->profile(), std::vector<GURL>(), false));
    204 
    205   // The launch should have created a new browser, with a panel type.
    206   Browser* new_browser = NULL;
    207   FindOneOtherBrowser(&new_browser);
    208   ASSERT_FALSE(HasFatalFailure());
    209 
    210   // Expect an app panel.
    211   EXPECT_EQ(Browser::TYPE_APP_POPUP, new_browser->type());
    212 
    213   // The new browser's app_name should include the app's ID.
    214   EXPECT_NE(
    215       new_browser->app_name_.find(extension_app->id()),
    216       std::string::npos) << new_browser->app_name_;
    217 }
    218 
    219 #endif  // !defined(OS_MACOSX)
    220