Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / chrome_app_api_browsertest.cc
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 <string>
6
7 #include "base/command_line.h"
8 #include "base/json/json_reader.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/values.h"
12 #include "chrome/browser/extensions/extension_browsertest.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/test/base/ui_test_utils.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/test/browser_test_utils.h"
21 #include "extensions/common/extension.h"
22 #include "extensions/common/manifest.h"
23 #include "net/dns/mock_host_resolver.h"
24 #include "url/gurl.h"
25
26 using extensions::Extension;
27
28 class ChromeAppAPITest : public ExtensionBrowserTest {
29  protected:
30   bool IsAppInstalledInMainFrame() {
31     return IsAppInstalledInFrame(
32         browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
33   }
34   bool IsAppInstalledInIFrame() {
35     return IsAppInstalledInFrame(GetIFrame());
36   }
37   bool IsAppInstalledInFrame(content::RenderFrameHost* frame) {
38     const char kGetAppIsInstalled[] =
39         "window.domAutomationController.send(window.chrome.app.isInstalled);";
40     bool result;
41     CHECK(content::ExecuteScriptAndExtractBool(frame,
42                                                kGetAppIsInstalled,
43                                                &result));
44     return result;
45   }
46
47   std::string InstallStateInMainFrame() {
48     return InstallStateInFrame(
49         browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
50   }
51   std::string InstallStateInIFrame() {
52     return InstallStateInFrame(GetIFrame());
53   }
54   std::string InstallStateInFrame(content::RenderFrameHost* frame) {
55     const char kGetAppInstallState[] =
56         "window.chrome.app.installState("
57         "    function(s) { window.domAutomationController.send(s); });";
58     std::string result;
59     CHECK(content::ExecuteScriptAndExtractString(frame,
60                                                  kGetAppInstallState,
61                                                  &result));
62     return result;
63   }
64
65   std::string RunningStateInMainFrame() {
66     return RunningStateInFrame(
67         browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
68   }
69   std::string RunningStateInIFrame() {
70     return RunningStateInFrame(GetIFrame());
71   }
72   std::string RunningStateInFrame(content::RenderFrameHost* frame) {
73     const char kGetAppRunningState[] =
74         "window.domAutomationController.send("
75         "    window.chrome.app.runningState());";
76     std::string result;
77     CHECK(content::ExecuteScriptAndExtractString(frame,
78                                                  kGetAppRunningState,
79                                                  &result));
80     return result;
81   }
82
83  private:
84   content::RenderFrameHost* GetIFrame() {
85     return content::FrameMatchingPredicate(
86         browser()->tab_strip_model()->GetActiveWebContents(),
87         base::Bind(&content::FrameIsChildOfMainFrame));
88   }
89
90   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
91     ExtensionBrowserTest::SetUpCommandLine(command_line);
92     command_line->AppendSwitchASCII(switches::kAppsCheckoutURL,
93                                     "http://checkout.com:");
94   }
95 };
96
97 // Flaky http://crbug.com/238674
98 #if defined(OS_WIN)
99 #define MAYBE_IsInstalled DISABLED_IsInstalled
100 #else
101 #define MAYBE_IsInstalled IsInstalled
102 #endif
103 IN_PROC_BROWSER_TEST_F(ChromeAppAPITest, MAYBE_IsInstalled) {
104   std::string app_host("app.com");
105   std::string nonapp_host("nonapp.com");
106
107   host_resolver()->AddRule(app_host, "127.0.0.1");
108   host_resolver()->AddRule(nonapp_host, "127.0.0.1");
109   ASSERT_TRUE(test_server()->Start());
110
111   GURL test_file_url(test_server()->GetURL("extensions/test_file.html"));
112   GURL::Replacements replace_host;
113
114   replace_host.SetHostStr(app_host);
115   GURL app_url(test_file_url.ReplaceComponents(replace_host));
116
117   replace_host.SetHostStr(nonapp_host);
118   GURL non_app_url(test_file_url.ReplaceComponents(replace_host));
119
120   // Before the app is installed, app.com does not think that it is installed
121   ui_test_utils::NavigateToURL(browser(), app_url);
122   EXPECT_FALSE(IsAppInstalledInMainFrame());
123
124   // Load an app which includes app.com in its extent.
125   const Extension* extension = LoadExtension(
126       test_data_dir_.AppendASCII("app_dot_com_app"));
127   ASSERT_TRUE(extension);
128
129   // Even after the app is installed, the existing app.com tab is not in an
130   // app process, so chrome.app.isInstalled should return false.
131   EXPECT_FALSE(IsAppInstalledInMainFrame());
132
133   // Test that a non-app page has chrome.app.isInstalled = false.
134   ui_test_utils::NavigateToURL(browser(), non_app_url);
135   EXPECT_FALSE(IsAppInstalledInMainFrame());
136
137   // Test that a non-app page returns null for chrome.app.getDetails().
138   const char kGetAppDetails[] =
139       "window.domAutomationController.send("
140       "    JSON.stringify(window.chrome.app.getDetails()));";
141   std::string result;
142   ASSERT_TRUE(
143       content::ExecuteScriptAndExtractString(
144           browser()->tab_strip_model()->GetActiveWebContents(),
145           kGetAppDetails,
146           &result));
147   EXPECT_EQ("null", result);
148
149   // Check that an app page has chrome.app.isInstalled = true.
150   ui_test_utils::NavigateToURL(browser(), app_url);
151   EXPECT_TRUE(IsAppInstalledInMainFrame());
152
153   // Check that an app page returns the correct result for
154   // chrome.app.getDetails().
155   ui_test_utils::NavigateToURL(browser(), app_url);
156   ASSERT_TRUE(
157       content::ExecuteScriptAndExtractString(
158           browser()->tab_strip_model()->GetActiveWebContents(),
159           kGetAppDetails,
160           &result));
161   scoped_ptr<base::DictionaryValue> app_details(
162       static_cast<base::DictionaryValue*>(base::JSONReader::Read(result)));
163   // extension->manifest() does not contain the id.
164   app_details->Remove("id", NULL);
165   EXPECT_TRUE(app_details.get());
166   EXPECT_TRUE(app_details->Equals(extension->manifest()->value()));
167
168   // Try to change app.isInstalled.  Should silently fail, so
169   // that isInstalled should have the initial value.
170   ASSERT_TRUE(
171       content::ExecuteScriptAndExtractString(
172           browser()->tab_strip_model()->GetActiveWebContents(),
173           "window.domAutomationController.send("
174           "    function() {"
175           "        var value = window.chrome.app.isInstalled;"
176           "        window.chrome.app.isInstalled = !value;"
177           "        if (window.chrome.app.isInstalled == value) {"
178           "            return 'true';"
179           "        } else {"
180           "            return 'false';"
181           "        }"
182           "    }()"
183           ");",
184           &result));
185
186   // Should not be able to alter window.chrome.app.isInstalled from javascript";
187   EXPECT_EQ("true", result);
188 }
189
190 IN_PROC_BROWSER_TEST_F(ChromeAppAPITest, GetDetailsForFrame) {
191   std::string app_host("app.com");
192   std::string nonapp_host("nonapp.com");
193   std::string checkout_host("checkout.com");
194
195   host_resolver()->AddRule(app_host, "127.0.0.1");
196   host_resolver()->AddRule(nonapp_host, "127.0.0.1");
197   host_resolver()->AddRule(checkout_host, "127.0.0.1");
198   ASSERT_TRUE(test_server()->Start());
199
200   GURL test_file_url(test_server()->GetURL(
201       "files/extensions/get_app_details_for_frame.html"));
202   GURL::Replacements replace_host;
203
204   replace_host.SetHostStr(checkout_host);
205   GURL checkout_url(test_file_url.ReplaceComponents(replace_host));
206
207   replace_host.SetHostStr(app_host);
208   GURL app_url(test_file_url.ReplaceComponents(replace_host));
209
210   // Load an app which includes app.com in its extent.
211   const Extension* extension = LoadExtension(
212       test_data_dir_.AppendASCII("app_dot_com_app"));
213   ASSERT_TRUE(extension);
214
215   // Test that normal pages (even apps) cannot use getDetailsForFrame().
216   ui_test_utils::NavigateToURL(browser(), app_url);
217   const char kTestUnsuccessfulAccess[] =
218       "window.domAutomationController.send(window.testUnsuccessfulAccess())";
219   bool result = false;
220   ASSERT_TRUE(
221       content::ExecuteScriptAndExtractBool(
222           browser()->tab_strip_model()->GetActiveWebContents(),
223           kTestUnsuccessfulAccess,
224           &result));
225   EXPECT_TRUE(result);
226
227   // Test that checkout can use getDetailsForFrame() and that it works
228   // correctly.
229   ui_test_utils::NavigateToURL(browser(), checkout_url);
230   const char kGetDetailsForFrame[] =
231       "window.domAutomationController.send("
232       "    JSON.stringify(chrome.app.getDetailsForFrame(frames[0])))";
233   std::string json;
234   ASSERT_TRUE(
235       content::ExecuteScriptAndExtractString(
236           browser()->tab_strip_model()->GetActiveWebContents(),
237           kGetDetailsForFrame,
238           &json));
239
240   scoped_ptr<base::DictionaryValue> app_details(
241       static_cast<base::DictionaryValue*>(base::JSONReader::Read(json)));
242   // extension->manifest() does not contain the id.
243   app_details->Remove("id", NULL);
244   EXPECT_TRUE(app_details.get());
245   EXPECT_TRUE(app_details->Equals(extension->manifest()->value()));
246 }
247
248
249 IN_PROC_BROWSER_TEST_F(ChromeAppAPITest, InstallAndRunningState) {
250   std::string app_host("app.com");
251   std::string non_app_host("nonapp.com");
252
253   host_resolver()->AddRule(app_host, "127.0.0.1");
254   host_resolver()->AddRule(non_app_host, "127.0.0.1");
255   ASSERT_TRUE(test_server()->Start());
256
257   GURL test_file_url(test_server()->GetURL(
258       "files/extensions/get_app_details_for_frame.html"));
259   GURL::Replacements replace_host;
260
261   replace_host.SetHostStr(app_host);
262   GURL app_url(test_file_url.ReplaceComponents(replace_host));
263
264   replace_host.SetHostStr(non_app_host);
265   GURL non_app_url(test_file_url.ReplaceComponents(replace_host));
266
267   // Before the app is installed, app.com does not think that it is installed
268   ui_test_utils::NavigateToURL(browser(), app_url);
269
270   EXPECT_EQ("not_installed", InstallStateInMainFrame());
271   EXPECT_EQ("cannot_run", RunningStateInMainFrame());
272   EXPECT_FALSE(IsAppInstalledInMainFrame());
273
274   const Extension* extension = LoadExtension(
275       test_data_dir_.AppendASCII("app_dot_com_app"));
276   ASSERT_TRUE(extension);
277
278   EXPECT_EQ("installed", InstallStateInMainFrame());
279   EXPECT_EQ("ready_to_run", RunningStateInMainFrame());
280   EXPECT_FALSE(IsAppInstalledInMainFrame());
281
282   // Reloading the page should put the tab in an app process.
283   ui_test_utils::NavigateToURL(browser(), app_url);
284   EXPECT_EQ("installed", InstallStateInMainFrame());
285   EXPECT_EQ("running", RunningStateInMainFrame());
286   EXPECT_TRUE(IsAppInstalledInMainFrame());
287
288   // Disable the extension and verify the state.
289   ExtensionService* service = extensions::ExtensionSystem::Get(
290       browser()->profile())->extension_service();
291   service->DisableExtension(extension->id(),
292                             Extension::DISABLE_PERMISSIONS_INCREASE);
293   ui_test_utils::NavigateToURL(browser(), app_url);
294
295   EXPECT_EQ("disabled", InstallStateInMainFrame());
296   EXPECT_EQ("cannot_run", RunningStateInMainFrame());
297   EXPECT_FALSE(IsAppInstalledInMainFrame());
298
299   service->EnableExtension(extension->id());
300   EXPECT_EQ("installed", InstallStateInMainFrame());
301   EXPECT_EQ("ready_to_run", RunningStateInMainFrame());
302   EXPECT_FALSE(IsAppInstalledInMainFrame());
303
304   // The non-app URL should still not be installed or running.
305   ui_test_utils::NavigateToURL(browser(), non_app_url);
306
307   EXPECT_EQ("not_installed", InstallStateInMainFrame());
308   EXPECT_EQ("cannot_run", RunningStateInMainFrame());
309   EXPECT_FALSE(IsAppInstalledInMainFrame());
310
311   EXPECT_EQ("installed", InstallStateInIFrame());
312   EXPECT_EQ("cannot_run", RunningStateInIFrame());
313   EXPECT_FALSE(IsAppInstalledInIFrame());
314 }
315
316 IN_PROC_BROWSER_TEST_F(ChromeAppAPITest, InstallAndRunningStateFrame) {
317   std::string app_host("app.com");
318   std::string non_app_host("nonapp.com");
319
320   host_resolver()->AddRule(app_host, "127.0.0.1");
321   host_resolver()->AddRule(non_app_host, "127.0.0.1");
322   ASSERT_TRUE(test_server()->Start());
323
324   GURL test_file_url(test_server()->GetURL(
325       "files/extensions/get_app_details_for_frame_reversed.html"));
326   GURL::Replacements replace_host;
327
328   replace_host.SetHostStr(app_host);
329   GURL app_url(test_file_url.ReplaceComponents(replace_host));
330
331   replace_host.SetHostStr(non_app_host);
332   GURL non_app_url(test_file_url.ReplaceComponents(replace_host));
333
334   // Check the install and running state of a non-app iframe running
335   // within an app.
336   ui_test_utils::NavigateToURL(browser(), app_url);
337
338   EXPECT_EQ("not_installed", InstallStateInIFrame());
339   EXPECT_EQ("cannot_run", RunningStateInIFrame());
340   EXPECT_FALSE(IsAppInstalledInIFrame());
341 }