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 <string>
6
7 #include "base/command_line.h"
8 #include "base/json/json_reader.h"
9 #include "base/scoped_ptr.h"
10 #include "base/string_number_conversions.h"
11 #include "base/values.h"
12 #include "chrome/browser/extensions/extension_browsertest.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/extensions/extension.h"
16 #include "chrome/test/ui_test_utils.h"
17 #include "content/browser/tab_contents/tab_contents.h"
18 #include "googleurl/src/gurl.h"
19 #include "net/base/mock_host_resolver.h"
20
21 class ChromeAppAPITest : public ExtensionBrowserTest {
22 private:
SetUpCommandLine(CommandLine * command_line)23 virtual void SetUpCommandLine(CommandLine* command_line) {
24 ExtensionBrowserTest::SetUpCommandLine(command_line);
25 command_line->AppendSwitchASCII(switches::kAppsCheckoutURL,
26 "http://checkout.com:");
27 }
28 };
29
IN_PROC_BROWSER_TEST_F(ChromeAppAPITest,IsInstalled)30 IN_PROC_BROWSER_TEST_F(ChromeAppAPITest, IsInstalled) {
31 std::string app_host("app.com");
32 std::string nonapp_host("nonapp.com");
33
34 host_resolver()->AddRule(app_host, "127.0.0.1");
35 host_resolver()->AddRule(nonapp_host, "127.0.0.1");
36 ASSERT_TRUE(test_server()->Start());
37
38 GURL test_file_url(test_server()->GetURL("extensions/test_file.html"));
39 GURL::Replacements replace_host;
40
41 replace_host.SetHostStr(app_host);
42 GURL app_url(test_file_url.ReplaceComponents(replace_host));
43
44 replace_host.SetHostStr(nonapp_host);
45 GURL non_app_url(test_file_url.ReplaceComponents(replace_host));
46
47
48 // Load an app which includes app.com in its extent.
49 const Extension* extension = LoadExtension(
50 test_data_dir_.AppendASCII("app_dot_com_app"));
51 ASSERT_TRUE(extension);
52
53
54 // Test that a non-app page has chrome.app.isInstalled = false.
55 ui_test_utils::NavigateToURL(browser(), non_app_url);
56 std::wstring get_app_is_installed =
57 L"window.domAutomationController.send("
58 L" JSON.stringify(window.chrome.app.isInstalled));";
59 std::string result;
60 ASSERT_TRUE(
61 ui_test_utils::ExecuteJavaScriptAndExtractString(
62 browser()->GetSelectedTabContents()->render_view_host(),
63 L"", get_app_is_installed, &result));
64 EXPECT_EQ("false", result);
65
66 // Test that a non-app page returns null for chrome.app.getDetails().
67 std::wstring get_app_details =
68 L"window.domAutomationController.send("
69 L" JSON.stringify(window.chrome.app.getDetails()));";
70 ASSERT_TRUE(
71 ui_test_utils::ExecuteJavaScriptAndExtractString(
72 browser()->GetSelectedTabContents()->render_view_host(),
73 L"", get_app_details, &result));
74 EXPECT_EQ("null", result);
75
76 // Check that an app page has chrome.app.isInstalled = true.
77 ui_test_utils::NavigateToURL(browser(), app_url);
78 ASSERT_TRUE(
79 ui_test_utils::ExecuteJavaScriptAndExtractString(
80 browser()->GetSelectedTabContents()->render_view_host(),
81 L"", get_app_is_installed, &result));
82 EXPECT_EQ("true", result);
83
84 // Check that an app page returns the correct result for
85 // chrome.app.getDetails().
86 ui_test_utils::NavigateToURL(browser(), app_url);
87 ASSERT_TRUE(
88 ui_test_utils::ExecuteJavaScriptAndExtractString(
89 browser()->GetSelectedTabContents()->render_view_host(),
90 L"", get_app_details, &result));
91 scoped_ptr<DictionaryValue> app_details(
92 static_cast<DictionaryValue*>(
93 base::JSONReader::Read(result, false /* allow trailing comma */)));
94 // extension->manifest_value() does not contain the id.
95 app_details->Remove("id", NULL);
96 EXPECT_TRUE(app_details.get());
97 EXPECT_TRUE(app_details->Equals(extension->manifest_value()));
98
99
100 // Test that trying to set window.chrome.app.isInstalled throws
101 // an exception.
102 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
103 browser()->GetSelectedTabContents()->render_view_host(),
104 L"",
105 L"window.domAutomationController.send("
106 L" function() {"
107 L" try {"
108 L" window.chrome.app.isInstalled = false;"
109 L" return 'BAD: Should have thrown by now...';"
110 L" } catch (e) {"
111 L" return 'GOOD: Saw expected error.';"
112 L" }"
113 L" }()"
114 L");",
115 &result));
116 EXPECT_EQ("GOOD: Saw expected error.", result);
117 }
118
IN_PROC_BROWSER_TEST_F(ChromeAppAPITest,GetDetailsForFrame)119 IN_PROC_BROWSER_TEST_F(ChromeAppAPITest, GetDetailsForFrame) {
120 std::string app_host("app.com");
121 std::string nonapp_host("nonapp.com");
122 std::string checkout_host("checkout.com");
123
124 host_resolver()->AddRule(app_host, "127.0.0.1");
125 host_resolver()->AddRule(nonapp_host, "127.0.0.1");
126 host_resolver()->AddRule(checkout_host, "127.0.0.1");
127 ASSERT_TRUE(test_server()->Start());
128
129 GURL test_file_url(test_server()->GetURL(
130 "files/extensions/get_app_details_for_frame.html"));
131 GURL::Replacements replace_host;
132
133 replace_host.SetHostStr(checkout_host);
134 GURL checkout_url(test_file_url.ReplaceComponents(replace_host));
135
136 replace_host.SetHostStr(app_host);
137 GURL app_url(test_file_url.ReplaceComponents(replace_host));
138
139 // Load an app which includes app.com in its extent.
140 const Extension* extension = LoadExtension(
141 test_data_dir_.AppendASCII("app_dot_com_app"));
142 ASSERT_TRUE(extension);
143
144 // Test that normal pages (even apps) cannot use getDetailsForFrame().
145 ui_test_utils::NavigateToURL(browser(), app_url);
146 std::wstring test_unsuccessful_access =
147 L"window.domAutomationController.send(window.testUnsuccessfulAccess())";
148 bool result = false;
149 ASSERT_TRUE(
150 ui_test_utils::ExecuteJavaScriptAndExtractBool(
151 browser()->GetSelectedTabContents()->render_view_host(),
152 L"", test_unsuccessful_access, &result));
153 EXPECT_TRUE(result);
154
155 // Test that checkout can use getDetailsForFrame() and that it works
156 // correctly.
157 ui_test_utils::NavigateToURL(browser(), checkout_url);
158 std::wstring get_details_for_frame =
159 L"window.domAutomationController.send("
160 L" JSON.stringify(chrome.app.getDetailsForFrame(frames[0])))";
161 std::string json;
162 ASSERT_TRUE(
163 ui_test_utils::ExecuteJavaScriptAndExtractString(
164 browser()->GetSelectedTabContents()->render_view_host(),
165 L"", get_details_for_frame, &json));
166
167 scoped_ptr<DictionaryValue> app_details(
168 static_cast<DictionaryValue*>(
169 base::JSONReader::Read(json, false /* allow trailing comma */)));
170 // extension->manifest_value() does not contain the id.
171 app_details->Remove("id", NULL);
172 EXPECT_TRUE(app_details.get());
173 EXPECT_TRUE(app_details->Equals(extension->manifest_value()));
174 }
175