OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include "base/files/file_path.h" |
| 6 #include "base/path_service.h" |
| 7 #include "base/stringprintf.h" |
| 8 #include "base/strings/string_number_conversions.h" |
5 #include "base/values.h" | 9 #include "base/values.h" |
6 #include "chrome/browser/extensions/event_router.h" | 10 #include "chrome/browser/extensions/event_router.h" |
7 #include "chrome/browser/extensions/extension_apitest.h" | 11 #include "chrome/browser/extensions/extension_apitest.h" |
8 #include "chrome/browser/extensions/extension_system.h" | 12 #include "chrome/browser/extensions/extension_system.h" |
9 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
| 14 #include "chrome/browser/ui/browser.h" |
| 15 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
10 #include "chrome/common/chrome_notification_types.h" | 16 #include "chrome/common/chrome_notification_types.h" |
| 17 #include "chrome/common/chrome_paths.h" |
11 #include "chrome/common/chrome_switches.h" | 18 #include "chrome/common/chrome_switches.h" |
| 19 #include "chrome/test/base/ui_test_utils.h" |
12 #include "content/public/browser/notification_registrar.h" | 20 #include "content/public/browser/notification_registrar.h" |
13 #include "content/public/browser/notification_service.h" | 21 #include "content/public/browser/notification_service.h" |
| 22 #include "content/public/test/browser_test_utils.h" |
14 #include "googleurl/src/gurl.h" | 23 #include "googleurl/src/gurl.h" |
| 24 #include "net/dns/mock_host_resolver.h" |
| 25 #include "net/test/embedded_test_server/embedded_test_server.h" |
15 | 26 |
16 namespace { | 27 namespace { |
17 | 28 |
18 class MessageSender : public content::NotificationObserver { | 29 class MessageSender : public content::NotificationObserver { |
19 public: | 30 public: |
20 MessageSender() { | 31 MessageSender() { |
21 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, | 32 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, |
22 content::NotificationService::AllSources()); | 33 content::NotificationService::AllSources()); |
23 } | 34 } |
24 | 35 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 class PanelMessagingTest : public ExtensionApiTest { | 115 class PanelMessagingTest : public ExtensionApiTest { |
105 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { | 116 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { |
106 ExtensionApiTest::SetUpCommandLine(command_line); | 117 ExtensionApiTest::SetUpCommandLine(command_line); |
107 command_line->AppendSwitch(switches::kEnablePanels); | 118 command_line->AppendSwitch(switches::kEnablePanels); |
108 } | 119 } |
109 }; | 120 }; |
110 | 121 |
111 IN_PROC_BROWSER_TEST_F(PanelMessagingTest, MessagingPanel) { | 122 IN_PROC_BROWSER_TEST_F(PanelMessagingTest, MessagingPanel) { |
112 ASSERT_TRUE(RunExtensionTest("messaging/connect_panel")) << message_; | 123 ASSERT_TRUE(RunExtensionTest("messaging/connect_panel")) << message_; |
113 } | 124 } |
| 125 |
| 126 // Tests externally_connectable between a web page and an extension. |
| 127 // |
| 128 // TODO(kalman): Test between extensions. This is already tested in this file, |
| 129 // but not with externally_connectable set in the manifest. |
| 130 // |
| 131 // TODO(kalman): Test with host permissions. |
| 132 class ExternallyConnectableMessagingTest : public ExtensionApiTest { |
| 133 protected: |
| 134 // Result codes from the test. These must match up with |results| in |
| 135 // c/t/d/extensions/api_test/externally_connectable/sites/assertions.json. |
| 136 enum Result { |
| 137 OK = 0, |
| 138 NAMESPACE_NOT_DEFINED = 1, |
| 139 FUNCTION_NOT_DEFINED = 2, |
| 140 COULD_NOT_ESTABLISH_CONNECTION_ERROR = 3, |
| 141 OTHER_ERROR = 4, |
| 142 INCORRECT_RESPONSE_SENDER = 5, |
| 143 INCORRECT_RESPONSE_MESSAGE = 6, |
| 144 }; |
| 145 |
| 146 Result CanConnectAndSendMessages(const std::string& extension_id) { |
| 147 int result; |
| 148 CHECK(content::ExecuteScriptAndExtractInt( |
| 149 browser()->tab_strip_model()->GetActiveWebContents(), |
| 150 "assertions.canConnectAndSendMessages('" + extension_id + "')", |
| 151 &result)); |
| 152 return static_cast<Result>(result); |
| 153 } |
| 154 |
| 155 testing::AssertionResult AreAnyNonWebApisDefined() { |
| 156 // All runtime API methods are non-web except for sendRequest and connect. |
| 157 const std::string non_messaging_apis[] = { |
| 158 "getBackgroundPage", |
| 159 "getManifest", |
| 160 "getURL", |
| 161 "reload", |
| 162 "requestUpdateCheck", |
| 163 "connectNative", |
| 164 "sendNativeMessage", |
| 165 "onStartup", |
| 166 "onInstalled", |
| 167 "onSuspend", |
| 168 "onSuspendCanceled", |
| 169 "onUpdateAvailable", |
| 170 "onBrowserUpdateAvailable", |
| 171 "onConnect", |
| 172 "onConnectExternal", |
| 173 "onMessage", |
| 174 "onMessageExternal", |
| 175 "id", |
| 176 }; |
| 177 return AreAnyRuntimePropertiesDefined(std::vector<std::string>( |
| 178 non_messaging_apis, |
| 179 non_messaging_apis + arraysize(non_messaging_apis))); |
| 180 } |
| 181 |
| 182 GURL GetURLForPath(const std::string& host, const std::string& path) { |
| 183 std::string port = base::IntToString(embedded_test_server()->port()); |
| 184 GURL::Replacements replacements; |
| 185 replacements.SetHostStr(host); |
| 186 replacements.SetPortStr(port); |
| 187 return embedded_test_server()->GetURL(path).ReplaceComponents(replacements); |
| 188 } |
| 189 |
| 190 private: |
| 191 testing::AssertionResult AreAnyRuntimePropertiesDefined( |
| 192 const std::vector<std::string>& names) { |
| 193 for (size_t i = 0; i < names.size(); ++i) { |
| 194 if (IsRuntimePropertyDefined(names[i]) == OK) |
| 195 return testing::AssertionSuccess() << names[i] << " is defined"; |
| 196 } |
| 197 return testing::AssertionFailure() |
| 198 << "none of " << names.size() << " properties are defined"; |
| 199 } |
| 200 |
| 201 Result IsRuntimePropertyDefined(const std::string& name) { |
| 202 int result_int; |
| 203 CHECK(content::ExecuteScriptAndExtractInt( |
| 204 browser()->tab_strip_model()->GetActiveWebContents(), |
| 205 "assertions.isDefined('" + name + "')", |
| 206 &result_int)); |
| 207 return static_cast<Result>(result_int); |
| 208 } |
| 209 }; |
| 210 |
| 211 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, |
| 212 ExternallyConnectableMessaging) { |
| 213 const char kExtensionDir[] = "messaging/externally_connectable"; |
| 214 |
| 215 // The extension allows connections from chromium.org but not google.com. |
| 216 const char kChromiumOrg[] = "www.chromium.org"; |
| 217 const char kGoogleCom[] = "www.google.com"; |
| 218 |
| 219 base::FilePath test_data; |
| 220 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data)); |
| 221 embedded_test_server()->ServeFilesFromDirectory( |
| 222 test_data.AppendASCII("extensions/api_test").AppendASCII(kExtensionDir)); |
| 223 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); |
| 224 |
| 225 host_resolver()->AddRule("*", embedded_test_server()->base_url().host()); |
| 226 |
| 227 const GURL kChromiumOrgUrl = |
| 228 GetURLForPath(kChromiumOrg, "/sites/chromium.org.html"); |
| 229 const GURL kGoogleComUrl = |
| 230 GetURLForPath(kGoogleCom, "/sites/google.com.html"); |
| 231 |
| 232 // When an extension isn't installed all attempts to connect to it should |
| 233 // fail. |
| 234 const std::string kFakeId = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; |
| 235 ui_test_utils::NavigateToURL(browser(), kChromiumOrgUrl); |
| 236 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, |
| 237 CanConnectAndSendMessages(kFakeId)); |
| 238 EXPECT_FALSE(AreAnyNonWebApisDefined()); |
| 239 |
| 240 ui_test_utils::NavigateToURL(browser(), kGoogleComUrl); |
| 241 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, |
| 242 CanConnectAndSendMessages(kFakeId)); |
| 243 EXPECT_FALSE(AreAnyNonWebApisDefined()); |
| 244 |
| 245 // Install the web connectable extension. chromium.org can connect to it, |
| 246 // google.com can't. |
| 247 const extensions::Extension* web_connectable = LoadExtension( |
| 248 test_data_dir_.AppendASCII(kExtensionDir).AppendASCII("web_connectable")); |
| 249 |
| 250 ui_test_utils::NavigateToURL(browser(), kChromiumOrgUrl); |
| 251 EXPECT_EQ(OK, CanConnectAndSendMessages(web_connectable->id())); |
| 252 EXPECT_FALSE(AreAnyNonWebApisDefined()); |
| 253 |
| 254 ui_test_utils::NavigateToURL(browser(), kGoogleComUrl); |
| 255 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, |
| 256 CanConnectAndSendMessages(web_connectable->id())); |
| 257 EXPECT_FALSE(AreAnyNonWebApisDefined()); |
| 258 |
| 259 // Install the non-connectable extension. Nothing can connect to it. |
| 260 const extensions::Extension* not_connectable = LoadExtension( |
| 261 test_data_dir_.AppendASCII(kExtensionDir).AppendASCII("not_connectable")); |
| 262 |
| 263 ui_test_utils::NavigateToURL(browser(), kChromiumOrgUrl); |
| 264 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, |
| 265 CanConnectAndSendMessages(not_connectable->id())); |
| 266 EXPECT_FALSE(AreAnyNonWebApisDefined()); |
| 267 |
| 268 ui_test_utils::NavigateToURL(browser(), kGoogleComUrl); |
| 269 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, |
| 270 CanConnectAndSendMessages(not_connectable->id())); |
| 271 EXPECT_FALSE(AreAnyNonWebApisDefined()); |
| 272 } |
OLD | NEW |