• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
LoadApp(const std::string & app_name,const Extension ** out_app_extension)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 
SetAppLaunchPref(const std::string & app_id,ExtensionPrefs::LaunchType launch_type)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()|.
FindOneOtherBrowser(Browser ** out_other_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:
OpenURLsPopupObserver()63   OpenURLsPopupObserver() : added_browser_(NULL) { }
64 
OnBrowserAdded(const Browser * browser)65   virtual void OnBrowserAdded(const Browser* browser) {
66     added_browser_ = browser;
67   }
68 
OnBrowserRemoved(const Browser * browser)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.
IN_PROC_BROWSER_TEST_F(BrowserInitTest,OpenURLsPopup)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)
IN_PROC_BROWSER_TEST_F(BrowserInitTest,OpenAppShortcutNoPref)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 
IN_PROC_BROWSER_TEST_F(BrowserInitTest,OpenAppShortcutWindowPref)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 
IN_PROC_BROWSER_TEST_F(BrowserInitTest,OpenAppShortcutTabPref)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 
IN_PROC_BROWSER_TEST_F(BrowserInitTest,OpenAppShortcutPanel)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