| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/command_line.h" |
| #include "base/file_path.h" |
| #include "base/utf_string_conversions.h" |
| #include "chrome/browser/extensions/extension_browsertest.h" |
| #include "chrome/browser/extensions/extension_service.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_init.h" |
| #include "chrome/browser/ui/browser_list.h" |
| #include "chrome/browser/ui/browser_window.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/test/in_process_browser_test.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| class BrowserInitTest : public ExtensionBrowserTest { |
| protected: |
| // Helper functions return void so that we can ASSERT*(). |
| // Use ASSERT_FALSE(HasFatalFailure()) after calling these functions |
| // to stop the test if an assert fails. |
| void LoadApp(const std::string& app_name, |
| const Extension** out_app_extension) { |
| ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(app_name.c_str()))); |
| |
| ExtensionService* service = browser()->profile()->GetExtensionService(); |
| *out_app_extension = service->GetExtensionById( |
| last_loaded_extension_id_, false); |
| ASSERT_TRUE(*out_app_extension); |
| |
| // Code that opens a new browser assumes we start with exactly one. |
| ASSERT_EQ(1u, BrowserList::GetBrowserCount(browser()->profile())); |
| } |
| |
| void SetAppLaunchPref(const std::string& app_id, |
| ExtensionPrefs::LaunchType launch_type) { |
| ExtensionService* service = browser()->profile()->GetExtensionService(); |
| service->extension_prefs()->SetLaunchType(app_id, launch_type); |
| } |
| |
| // Check that there are two browsers. Find the one that is not |browser()|. |
| void FindOneOtherBrowser(Browser** out_other_browser) { |
| // There should only be one other browser. |
| ASSERT_EQ(2u, BrowserList::GetBrowserCount(browser()->profile())); |
| |
| // Find the new browser. |
| Browser* other_browser = NULL; |
| for (BrowserList::const_iterator i = BrowserList::begin(); |
| i != BrowserList::end() && !other_browser; ++i) { |
| if (*i != browser()) |
| other_browser = *i; |
| } |
| ASSERT_TRUE(other_browser); |
| ASSERT_TRUE(other_browser != browser()); |
| *out_other_browser = other_browser; |
| } |
| }; |
| |
| class OpenURLsPopupObserver : public BrowserList::Observer { |
| public: |
| OpenURLsPopupObserver() : added_browser_(NULL) { } |
| |
| virtual void OnBrowserAdded(const Browser* browser) { |
| added_browser_ = browser; |
| } |
| |
| virtual void OnBrowserRemoved(const Browser* browser) { } |
| |
| const Browser* added_browser_; |
| }; |
| |
| // Test that when there is a popup as the active browser any requests to |
| // BrowserInit::LaunchWithProfile::OpenURLsInBrowser don't crash because |
| // there's no explicit profile given. |
| IN_PROC_BROWSER_TEST_F(BrowserInitTest, OpenURLsPopup) { |
| std::vector<GURL> urls; |
| urls.push_back(GURL("http://localhost")); |
| |
| // Note that in our testing we do not ever query the BrowserList for the "last |
| // active" browser. That's because the browsers are set as "active" by |
| // platform UI toolkit messages, and those messages are not sent during unit |
| // testing sessions. |
| |
| OpenURLsPopupObserver observer; |
| BrowserList::AddObserver(&observer); |
| |
| Browser* popup = Browser::CreateForType(Browser::TYPE_POPUP, |
| browser()->profile()); |
| ASSERT_EQ(popup->type(), Browser::TYPE_POPUP); |
| ASSERT_EQ(popup, observer.added_browser_); |
| |
| CommandLine dummy(CommandLine::NO_PROGRAM); |
| BrowserInit::LaunchWithProfile launch(FilePath(), dummy); |
| // This should create a new window, but re-use the profile from |popup|. If |
| // it used a NULL or invalid profile, it would crash. |
| launch.OpenURLsInBrowser(popup, false, urls); |
| ASSERT_NE(popup, observer.added_browser_); |
| BrowserList::RemoveObserver(&observer); |
| } |
| |
| // App shortcuts are not implemented on mac os. |
| #if !defined(OS_MACOSX) |
| IN_PROC_BROWSER_TEST_F(BrowserInitTest, OpenAppShortcutNoPref) { |
| // Load an app with launch.container = 'tab'. |
| const Extension* extension_app = NULL; |
| LoadApp("app_with_tab_container", &extension_app); |
| ASSERT_FALSE(HasFatalFailure()); // Check for ASSERT failures in LoadApp(). |
| |
| // Add --app-id=<extension->id()> to the command line. |
| CommandLine command_line(CommandLine::NO_PROGRAM); |
| command_line.AppendSwitchASCII(switches::kAppId, extension_app->id()); |
| |
| BrowserInit::LaunchWithProfile launch(FilePath(), command_line); |
| ASSERT_TRUE(launch.Launch(browser()->profile(), std::vector<GURL>(), false)); |
| |
| // No pref was set, so the app should have opened in a window. |
| // The launch should have created a new browser. |
| Browser* new_browser = NULL; |
| FindOneOtherBrowser(&new_browser); |
| ASSERT_FALSE(HasFatalFailure()); |
| |
| // Expect an app window. |
| EXPECT_EQ(Browser::TYPE_APP, new_browser->type()); |
| |
| // The browser's app_name should include the app's ID. |
| EXPECT_NE( |
| new_browser->app_name_.find(extension_app->id()), |
| std::string::npos) << new_browser->app_name_; |
| } |
| |
| IN_PROC_BROWSER_TEST_F(BrowserInitTest, OpenAppShortcutWindowPref) { |
| const Extension* extension_app = NULL; |
| LoadApp("app_with_tab_container", &extension_app); |
| ASSERT_FALSE(HasFatalFailure()); // Check for ASSERT failures in LoadApp(). |
| |
| // Set a pref indicating that the user wants to open this app in a window. |
| SetAppLaunchPref(extension_app->id(), ExtensionPrefs::LAUNCH_WINDOW); |
| |
| CommandLine command_line(CommandLine::NO_PROGRAM); |
| command_line.AppendSwitchASCII(switches::kAppId, extension_app->id()); |
| BrowserInit::LaunchWithProfile launch(FilePath(), command_line); |
| ASSERT_TRUE(launch.Launch(browser()->profile(), std::vector<GURL>(), false)); |
| |
| // Pref was set to open in a window, so the app should have opened in a |
| // window. The launch should have created a new browser. Find the new |
| // browser. |
| Browser* new_browser = NULL; |
| FindOneOtherBrowser(&new_browser); |
| ASSERT_FALSE(HasFatalFailure()); |
| |
| // Expect an app window. |
| EXPECT_EQ(Browser::TYPE_APP, new_browser->type()); |
| |
| // The browser's app_name should include the app's ID. |
| EXPECT_NE( |
| new_browser->app_name_.find(extension_app->id()), |
| std::string::npos) << new_browser->app_name_; |
| } |
| |
| IN_PROC_BROWSER_TEST_F(BrowserInitTest, OpenAppShortcutTabPref) { |
| // Load an app with launch.container = 'tab'. |
| const Extension* extension_app = NULL; |
| LoadApp("app_with_tab_container", &extension_app); |
| ASSERT_FALSE(HasFatalFailure()); // Check for ASSERT failures in LoadApp(). |
| |
| // Set a pref indicating that the user wants to open this app in a window. |
| SetAppLaunchPref(extension_app->id(), ExtensionPrefs::LAUNCH_REGULAR); |
| |
| CommandLine command_line(CommandLine::NO_PROGRAM); |
| command_line.AppendSwitchASCII(switches::kAppId, extension_app->id()); |
| BrowserInit::LaunchWithProfile launch(FilePath(), command_line); |
| ASSERT_TRUE(launch.Launch(browser()->profile(), std::vector<GURL>(), false)); |
| |
| // When an app shortcut is open and the pref indicates a tab should |
| // open, the tab is open in a new browser window. Expect a new window. |
| ASSERT_EQ(2u, BrowserList::GetBrowserCount(browser()->profile())); |
| |
| Browser* new_browser = NULL; |
| FindOneOtherBrowser(&new_browser); |
| ASSERT_FALSE(HasFatalFailure()); |
| |
| // The tab should be in a normal window. |
| EXPECT_EQ(Browser::TYPE_NORMAL, new_browser->type()); |
| |
| // The browser's app_name should not include the app's ID: It is in a |
| // normal browser. |
| EXPECT_EQ( |
| new_browser->app_name_.find(extension_app->id()), |
| std::string::npos) << new_browser->app_name_; |
| } |
| |
| IN_PROC_BROWSER_TEST_F(BrowserInitTest, OpenAppShortcutPanel) { |
| // Load an app with launch.container = 'panel'. |
| const Extension* extension_app = NULL; |
| LoadApp("app_with_panel_container", &extension_app); |
| ASSERT_FALSE(HasFatalFailure()); // Check for ASSERT failures in LoadApp(). |
| |
| CommandLine command_line(CommandLine::NO_PROGRAM); |
| command_line.AppendSwitchASCII(switches::kAppId, extension_app->id()); |
| BrowserInit::LaunchWithProfile launch(FilePath(), command_line); |
| ASSERT_TRUE(launch.Launch(browser()->profile(), std::vector<GURL>(), false)); |
| |
| // The launch should have created a new browser, with a panel type. |
| Browser* new_browser = NULL; |
| FindOneOtherBrowser(&new_browser); |
| ASSERT_FALSE(HasFatalFailure()); |
| |
| // Expect an app panel. |
| EXPECT_EQ(Browser::TYPE_APP_POPUP, new_browser->type()); |
| |
| // The new browser's app_name should include the app's ID. |
| EXPECT_NE( |
| new_browser->app_name_.find(extension_app->id()), |
| std::string::npos) << new_browser->app_name_; |
| } |
| |
| #endif // !defined(OS_MACOSX) |