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: 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 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 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