app_list: Re-enable people search.
[chromium-blink-merge.git] / chrome / browser / extensions / extension_messages_apitest.cc
bloba8bd92a4c37732c2058a174b03c77ef1d9e69cee
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.
5 #include "base/base64.h"
6 #include "base/files/file_path.h"
7 #include "base/json/json_reader.h"
8 #include "base/json/json_writer.h"
9 #include "base/path_service.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_piece.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/synchronization/waitable_event.h"
15 #include "base/values.h"
16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h"
18 #include "chrome/browser/extensions/extension_apitest.h"
19 #include "chrome/browser/extensions/test_extension_dir.h"
20 #include "chrome/browser/infobars/infobar_service.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/ui/browser.h"
23 #include "chrome/browser/ui/tabs/tab_strip_model.h"
24 #include "chrome/common/chrome_paths.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/test/base/ui_test_utils.h"
27 #include "content/public/browser/notification_registrar.h"
28 #include "content/public/browser/notification_service.h"
29 #include "content/public/test/browser_test_utils.h"
30 #include "extensions/browser/event_router.h"
31 #include "extensions/browser/extension_prefs.h"
32 #include "extensions/browser/extension_system.h"
33 #include "extensions/common/api/runtime.h"
34 #include "extensions/common/extension_builder.h"
35 #include "extensions/common/value_builder.h"
36 #include "net/cert/asn1_util.h"
37 #include "net/cert/jwk_serializer.h"
38 #include "net/dns/mock_host_resolver.h"
39 #include "net/ssl/channel_id_service.h"
40 #include "net/test/embedded_test_server/embedded_test_server.h"
41 #include "net/url_request/url_request_context.h"
42 #include "net/url_request/url_request_context_getter.h"
43 #include "url/gurl.h"
45 namespace extensions {
46 namespace {
48 class MessageSender : public content::NotificationObserver {
49 public:
50 MessageSender() {
51 registrar_.Add(this,
52 extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
53 content::NotificationService::AllSources());
56 private:
57 static scoped_ptr<base::ListValue> BuildEventArguments(
58 const bool last_message,
59 const std::string& data) {
60 base::DictionaryValue* event = new base::DictionaryValue();
61 event->SetBoolean("lastMessage", last_message);
62 event->SetString("data", data);
63 scoped_ptr<base::ListValue> arguments(new base::ListValue());
64 arguments->Append(event);
65 return arguments.Pass();
68 static scoped_ptr<Event> BuildEvent(scoped_ptr<base::ListValue> event_args,
69 Profile* profile,
70 GURL event_url) {
71 scoped_ptr<Event> event(new Event("test.onMessage", event_args.Pass()));
72 event->restrict_to_browser_context = profile;
73 event->event_url = event_url;
74 return event.Pass();
77 void Observe(int type,
78 const content::NotificationSource& source,
79 const content::NotificationDetails& details) override {
80 EventRouter* event_router =
81 EventRouter::Get(content::Source<Profile>(source).ptr());
83 // Sends four messages to the extension. All but the third message sent
84 // from the origin http://b.com/ are supposed to arrive.
85 event_router->BroadcastEvent(BuildEvent(
86 BuildEventArguments(false, "no restriction"),
87 content::Source<Profile>(source).ptr(),
88 GURL()));
89 event_router->BroadcastEvent(BuildEvent(
90 BuildEventArguments(false, "http://a.com/"),
91 content::Source<Profile>(source).ptr(),
92 GURL("http://a.com/")));
93 event_router->BroadcastEvent(BuildEvent(
94 BuildEventArguments(false, "http://b.com/"),
95 content::Source<Profile>(source).ptr(),
96 GURL("http://b.com/")));
97 event_router->BroadcastEvent(BuildEvent(
98 BuildEventArguments(true, "last message"),
99 content::Source<Profile>(source).ptr(),
100 GURL()));
103 content::NotificationRegistrar registrar_;
106 // Tests that message passing between extensions and content scripts works.
107 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Messaging) {
108 ASSERT_TRUE(StartEmbeddedTestServer());
109 ASSERT_TRUE(RunExtensionTest("messaging/connect")) << message_;
112 // Tests that message passing from one extension to another works.
113 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MessagingExternal) {
114 ASSERT_TRUE(LoadExtension(
115 test_data_dir_.AppendASCII("..").AppendASCII("good")
116 .AppendASCII("Extensions")
117 .AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa")
118 .AppendASCII("1.0")));
120 ASSERT_TRUE(RunExtensionTest("messaging/connect_external")) << message_;
123 // Tests that messages with event_urls are only passed to extensions with
124 // appropriate permissions.
125 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MessagingEventURL) {
126 MessageSender sender;
127 ASSERT_TRUE(RunExtensionTest("messaging/event_url")) << message_;
130 // Tests connecting from a panel to its extension.
131 class PanelMessagingTest : public ExtensionApiTest {
132 void SetUpCommandLine(base::CommandLine* command_line) override {
133 ExtensionApiTest::SetUpCommandLine(command_line);
134 command_line->AppendSwitch(switches::kEnablePanels);
138 IN_PROC_BROWSER_TEST_F(PanelMessagingTest, MessagingPanel) {
139 ASSERT_TRUE(RunExtensionTest("messaging/connect_panel")) << message_;
142 // XXX(kalman): All web messaging tests disabled on windows due to extreme
143 // flakiness. See http://crbug.com/350517.
144 #if !defined(OS_WIN)
146 // Tests externally_connectable between a web page and an extension.
148 // TODO(kalman): Test between extensions. This is already tested in this file,
149 // but not with externally_connectable set in the manifest.
151 // TODO(kalman): Test with host permissions.
152 class ExternallyConnectableMessagingTest : public ExtensionApiTest {
153 protected:
154 // Result codes from the test. These must match up with |results| in
155 // c/t/d/extensions/api_test/externally_connectable/assertions.json.
156 enum Result {
157 OK = 0,
158 NAMESPACE_NOT_DEFINED = 1,
159 FUNCTION_NOT_DEFINED = 2,
160 COULD_NOT_ESTABLISH_CONNECTION_ERROR = 3,
161 OTHER_ERROR = 4,
162 INCORRECT_RESPONSE_SENDER = 5,
163 INCORRECT_RESPONSE_MESSAGE = 6,
166 bool AppendIframe(const GURL& src) {
167 bool result;
168 CHECK(content::ExecuteScriptAndExtractBool(
169 browser()->tab_strip_model()->GetActiveWebContents(),
170 "actions.appendIframe('" + src.spec() + "');", &result));
171 return result;
174 Result CanConnectAndSendMessagesToMainFrame(const Extension* extension,
175 const char* message = NULL) {
176 return CanConnectAndSendMessagesToFrame(
177 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
178 extension,
179 message);
182 Result CanConnectAndSendMessagesToIFrame(const Extension* extension,
183 const char* message = NULL) {
184 content::RenderFrameHost* frame = content::FrameMatchingPredicate(
185 browser()->tab_strip_model()->GetActiveWebContents(),
186 base::Bind(&content::FrameIsChildOfMainFrame));
187 return CanConnectAndSendMessagesToFrame(frame, extension, message);
190 Result CanConnectAndSendMessagesToFrame(content::RenderFrameHost* frame,
191 const Extension* extension,
192 const char* message) {
193 int result;
194 std::string command = base::StringPrintf(
195 "assertions.canConnectAndSendMessages('%s', %s, %s)",
196 extension->id().c_str(),
197 extension->is_platform_app() ? "true" : "false",
198 message ? base::StringPrintf("'%s'", message).c_str() : "undefined");
199 CHECK(content::ExecuteScriptAndExtractInt(frame, command, &result));
200 return static_cast<Result>(result);
203 testing::AssertionResult AreAnyNonWebApisDefinedForMainFrame() {
204 return AreAnyNonWebApisDefinedForFrame(
205 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
208 testing::AssertionResult AreAnyNonWebApisDefinedForIFrame() {
209 content::RenderFrameHost* frame = content::FrameMatchingPredicate(
210 browser()->tab_strip_model()->GetActiveWebContents(),
211 base::Bind(&content::FrameIsChildOfMainFrame));
212 return AreAnyNonWebApisDefinedForFrame(frame);
215 testing::AssertionResult AreAnyNonWebApisDefinedForFrame(
216 content::RenderFrameHost* frame) {
217 // All runtime API methods are non-web except for sendRequest and connect.
218 const char* const non_messaging_apis[] = {
219 "getBackgroundPage",
220 "getManifest",
221 "getURL",
222 "reload",
223 "requestUpdateCheck",
224 "restart",
225 "connectNative",
226 "sendNativeMessage",
227 "onStartup",
228 "onInstalled",
229 "onSuspend",
230 "onSuspendCanceled",
231 "onUpdateAvailable",
232 "onBrowserUpdateAvailable",
233 "onConnect",
234 "onConnectExternal",
235 "onMessage",
236 "onMessageExternal",
237 "onRestartRequired",
238 // Note: no "id" here because this test method is used for hosted apps,
239 // which do have access to runtime.id.
242 // Turn the array into a JS array, which effectively gets eval()ed.
243 std::string as_js_array;
244 for (size_t i = 0; i < arraysize(non_messaging_apis); ++i) {
245 as_js_array += as_js_array.empty() ? "[" : ",";
246 as_js_array += base::StringPrintf("'%s'", non_messaging_apis[i]);
248 as_js_array += "]";
250 bool any_defined;
251 CHECK(content::ExecuteScriptAndExtractBool(
252 frame,
253 "assertions.areAnyRuntimePropertiesDefined(" + as_js_array + ")",
254 &any_defined));
255 return any_defined ?
256 testing::AssertionSuccess() : testing::AssertionFailure();
259 std::string GetTlsChannelIdFromPortConnect(const Extension* extension,
260 bool include_tls_channel_id,
261 const char* message = NULL) {
262 return GetTlsChannelIdFromAssertion("getTlsChannelIdFromPortConnect",
263 extension,
264 include_tls_channel_id,
265 message);
268 std::string GetTlsChannelIdFromSendMessage(const Extension* extension,
269 bool include_tls_channel_id,
270 const char* message = NULL) {
271 return GetTlsChannelIdFromAssertion("getTlsChannelIdFromSendMessage",
272 extension,
273 include_tls_channel_id,
274 message);
277 GURL GetURLForPath(const std::string& host, const std::string& path) {
278 std::string port = base::IntToString(embedded_test_server()->port());
279 GURL::Replacements replacements;
280 replacements.SetHostStr(host);
281 replacements.SetPortStr(port);
282 return embedded_test_server()->GetURL(path).ReplaceComponents(replacements);
285 GURL chromium_org_url() {
286 return GetURLForPath("www.chromium.org", "/chromium.org.html");
289 GURL google_com_url() {
290 return GetURLForPath("www.google.com", "/google.com.html");
293 scoped_refptr<const Extension> LoadChromiumConnectableExtension() {
294 scoped_refptr<const Extension> extension =
295 LoadExtensionIntoDir(&web_connectable_dir_,
296 base::StringPrintf(
298 " \"name\": \"chromium_connectable\","
299 " %s,"
300 " \"externally_connectable\": {"
301 " \"matches\": [\"*://*.chromium.org:*/*\"]"
302 " }"
303 "}",
304 common_manifest()));
305 CHECK(extension.get());
306 return extension;
309 scoped_refptr<const Extension> LoadChromiumConnectableApp(
310 bool with_event_handlers = true) {
311 scoped_refptr<const Extension> extension =
312 LoadExtensionIntoDir(&web_connectable_dir_,
314 " \"app\": {"
315 " \"background\": {"
316 " \"scripts\": [\"background.js\"]"
317 " }"
318 " },"
319 " \"externally_connectable\": {"
320 " \"matches\": [\"*://*.chromium.org:*/*\"]"
321 " },"
322 " \"manifest_version\": 2,"
323 " \"name\": \"app_connectable\","
324 " \"version\": \"1.0\""
325 "}",
326 with_event_handlers);
327 CHECK(extension.get());
328 return extension;
331 scoped_refptr<const Extension> LoadNotConnectableExtension() {
332 scoped_refptr<const Extension> extension =
333 LoadExtensionIntoDir(&not_connectable_dir_,
334 base::StringPrintf(
336 " \"name\": \"not_connectable\","
337 " %s"
338 "}",
339 common_manifest()));
340 CHECK(extension.get());
341 return extension;
344 scoped_refptr<const Extension>
345 LoadChromiumConnectableExtensionWithTlsChannelId() {
346 return LoadExtensionIntoDir(&tls_channel_id_connectable_dir_,
347 connectable_with_tls_channel_id_manifest());
350 scoped_refptr<const Extension> LoadChromiumHostedApp() {
351 scoped_refptr<const Extension> hosted_app =
352 LoadExtensionIntoDir(&hosted_app_dir_,
353 base::StringPrintf(
355 " \"name\": \"chromium_hosted_app\","
356 " \"version\": \"1.0\","
357 " \"manifest_version\": 2,"
358 " \"app\": {"
359 " \"urls\": [\"%s\"],"
360 " \"launch\": {"
361 " \"web_url\": \"%s\""
362 " }\n"
363 " }\n"
364 "}",
365 chromium_org_url().spec().c_str(),
366 chromium_org_url().spec().c_str()));
367 CHECK(hosted_app.get());
368 return hosted_app;
371 void InitializeTestServer() {
372 base::FilePath test_data;
373 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data));
374 embedded_test_server()->ServeFilesFromDirectory(test_data.AppendASCII(
375 "extensions/api_test/messaging/externally_connectable/sites"));
376 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
377 host_resolver()->AddRule("*", embedded_test_server()->base_url().host());
380 const char* close_background_message() {
381 return "closeBackgroundPage";
384 private:
385 scoped_refptr<const Extension> LoadExtensionIntoDir(
386 TestExtensionDir* dir,
387 const std::string& manifest,
388 bool with_event_handlers = true) {
389 dir->WriteManifest(manifest);
390 if (with_event_handlers) {
391 dir->WriteFile(
392 FILE_PATH_LITERAL("background.js"),
393 base::StringPrintf(
394 "function maybeClose(message) {\n"
395 " if (message.indexOf('%s') >= 0)\n"
396 " window.setTimeout(function() { window.close() }, 0);\n"
397 "}\n"
398 "chrome.runtime.onMessageExternal.addListener(\n"
399 " function(message, sender, reply) {\n"
400 " reply({ message: message, sender: sender });\n"
401 " maybeClose(message);\n"
402 "});\n"
403 "chrome.runtime.onConnectExternal.addListener(function(port) {\n"
404 " port.onMessage.addListener(function(message) {\n"
405 " port.postMessage({ message: message, sender: port.sender "
406 "});\n"
407 " maybeClose(message);\n"
408 " });\n"
409 "});\n",
410 close_background_message()));
411 } else {
412 dir->WriteFile(FILE_PATH_LITERAL("background.js"), "");
414 return LoadExtension(dir->unpacked_path());
417 const char* common_manifest() {
418 return "\"version\": \"1.0\","
419 "\"background\": {"
420 " \"scripts\": [\"background.js\"],"
421 " \"persistent\": false"
422 "},"
423 "\"manifest_version\": 2";
426 std::string connectable_with_tls_channel_id_manifest() {
427 return base::StringPrintf(
429 " \"name\": \"chromium_connectable_with_tls_channel_id\","
430 " %s,"
431 " \"externally_connectable\": {"
432 " \"matches\": [\"*://*.chromium.org:*/*\"],"
433 " \"accepts_tls_channel_id\": true"
434 " }"
435 "}",
436 common_manifest());
439 std::string GetTlsChannelIdFromAssertion(const char* method,
440 const Extension* extension,
441 bool include_tls_channel_id,
442 const char* message) {
443 std::string result;
444 std::string args = "'" + extension->id() + "', ";
445 args += include_tls_channel_id ? "true" : "false";
446 if (message)
447 args += std::string(", '") + message + "'";
448 CHECK(content::ExecuteScriptAndExtractString(
449 browser()->tab_strip_model()->GetActiveWebContents(),
450 base::StringPrintf("assertions.%s(%s)", method, args.c_str()),
451 &result));
452 return result;
455 TestExtensionDir web_connectable_dir_;
456 TestExtensionDir not_connectable_dir_;
457 TestExtensionDir tls_channel_id_connectable_dir_;
458 TestExtensionDir hosted_app_dir_;
461 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, NotInstalled) {
462 InitializeTestServer();
464 scoped_refptr<const Extension> extension =
465 ExtensionBuilder()
466 .SetID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
467 .SetManifest(DictionaryBuilder()
468 .Set("name", "Fake extension")
469 .Set("version", "1")
470 .Set("manifest_version", 2))
471 .Build();
473 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
474 EXPECT_EQ(NAMESPACE_NOT_DEFINED,
475 CanConnectAndSendMessagesToMainFrame(extension.get()));
476 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
478 ui_test_utils::NavigateToURL(browser(), google_com_url());
479 EXPECT_EQ(NAMESPACE_NOT_DEFINED,
480 CanConnectAndSendMessagesToMainFrame(extension.get()));
481 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
484 // Tests two extensions on the same sites: one web connectable, one not.
485 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
486 WebConnectableAndNotConnectable) {
487 InitializeTestServer();
489 // Install the web connectable extension. chromium.org can connect to it,
490 // google.com can't.
491 scoped_refptr<const Extension> chromium_connectable =
492 LoadChromiumConnectableExtension();
494 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
495 EXPECT_EQ(OK,
496 CanConnectAndSendMessagesToMainFrame(chromium_connectable.get()));
497 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
499 ui_test_utils::NavigateToURL(browser(), google_com_url());
500 EXPECT_EQ(NAMESPACE_NOT_DEFINED,
501 CanConnectAndSendMessagesToMainFrame(chromium_connectable.get()));
502 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
504 // Install the non-connectable extension. Nothing can connect to it.
505 scoped_refptr<const Extension> not_connectable =
506 LoadNotConnectableExtension();
508 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
509 // Namespace will be defined here because |chromium_connectable| can connect
510 // to it - so this will be the "cannot establish connection" error.
511 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
512 CanConnectAndSendMessagesToMainFrame(not_connectable.get()));
513 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
515 ui_test_utils::NavigateToURL(browser(), google_com_url());
516 EXPECT_EQ(NAMESPACE_NOT_DEFINED,
517 CanConnectAndSendMessagesToMainFrame(not_connectable.get()));
518 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
521 // See http://crbug.com/297866
522 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
523 DISABLED_BackgroundPageClosesOnMessageReceipt) {
524 InitializeTestServer();
526 // Install the web connectable extension.
527 scoped_refptr<const Extension> chromium_connectable =
528 LoadChromiumConnectableExtension();
530 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
531 // If the background page closes after receipt of the message, it will still
532 // reply to this message...
533 EXPECT_EQ(OK,
534 CanConnectAndSendMessagesToMainFrame(chromium_connectable.get(),
535 close_background_message()));
536 // and be re-opened by receipt of a subsequent message.
537 EXPECT_EQ(OK,
538 CanConnectAndSendMessagesToMainFrame(chromium_connectable.get()));
541 // Tests a web connectable extension that doesn't receive TLS channel id.
542 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
543 WebConnectableWithoutTlsChannelId) {
544 InitializeTestServer();
546 // Install the web connectable extension. chromium.org can connect to it,
547 // google.com can't.
548 scoped_refptr<const Extension> chromium_connectable =
549 LoadChromiumConnectableExtension();
550 ASSERT_TRUE(chromium_connectable.get());
552 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
553 // The web connectable extension doesn't request the TLS channel ID, so it
554 // doesn't get it, whether or not the page asks for it.
555 EXPECT_EQ(std::string(),
556 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), false));
557 EXPECT_EQ(std::string(),
558 GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true));
559 EXPECT_EQ(std::string(),
560 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), false));
561 EXPECT_EQ(std::string(),
562 GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true));
565 // Tests a web connectable extension that receives TLS channel id with a site
566 // that can't connect to it.
567 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
568 WebConnectableWithTlsChannelIdWithNonMatchingSite) {
569 InitializeTestServer();
571 scoped_refptr<const Extension> chromium_connectable =
572 LoadChromiumConnectableExtensionWithTlsChannelId();
573 ASSERT_TRUE(chromium_connectable.get());
575 ui_test_utils::NavigateToURL(browser(), google_com_url());
576 // The extension requests the TLS channel ID, but it doesn't get it for a
577 // site that can't connect to it, regardless of whether the page asks for it.
578 EXPECT_EQ(base::StringPrintf("%d", NAMESPACE_NOT_DEFINED),
579 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), false));
580 EXPECT_EQ(base::StringPrintf("%d", NAMESPACE_NOT_DEFINED),
581 GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true));
582 EXPECT_EQ(base::StringPrintf("%d", NAMESPACE_NOT_DEFINED),
583 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), false));
584 EXPECT_EQ(base::StringPrintf("%d", NAMESPACE_NOT_DEFINED),
585 GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true));
588 // Tests a web connectable extension that receives TLS channel id on a site
589 // that can connect to it, but with no TLS channel ID having been generated.
590 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
591 WebConnectableWithTlsChannelIdWithEmptyTlsChannelId) {
592 InitializeTestServer();
594 scoped_refptr<const Extension> chromium_connectable =
595 LoadChromiumConnectableExtensionWithTlsChannelId();
596 ASSERT_TRUE(chromium_connectable.get());
598 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
600 // Since the extension requests the TLS channel ID, it gets it for a site that
601 // can connect to it, but only if the page also asks to include it.
602 EXPECT_EQ(std::string(),
603 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), false));
604 EXPECT_EQ(std::string(),
605 GetTlsChannelIdFromSendMessage(chromium_connectable.get(), false));
606 // If the page does ask for it, it isn't empty.
607 std::string tls_channel_id =
608 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), true);
609 // Because the TLS channel ID has never been generated for this domain,
610 // no TLS channel ID is reported.
611 EXPECT_EQ(std::string(), tls_channel_id);
614 // Flaky on Linux and Windows. http://crbug.com/315264
615 // Tests a web connectable extension that receives TLS channel id, but
616 // immediately closes its background page upon receipt of a message.
617 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
618 DISABLED_WebConnectableWithEmptyTlsChannelIdAndClosedBackgroundPage) {
619 InitializeTestServer();
621 scoped_refptr<const Extension> chromium_connectable =
622 LoadChromiumConnectableExtensionWithTlsChannelId();
624 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
625 // If the page does ask for it, it isn't empty, even if the background page
626 // closes upon receipt of the connect.
627 std::string tls_channel_id = GetTlsChannelIdFromPortConnect(
628 chromium_connectable.get(), true, close_background_message());
629 // Because the TLS channel ID has never been generated for this domain,
630 // no TLS channel ID is reported.
631 EXPECT_EQ(std::string(), tls_channel_id);
632 // A subsequent connect will still succeed, even if the background page was
633 // previously closed.
634 tls_channel_id =
635 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), true);
636 // And the empty value is still retrieved.
637 EXPECT_EQ(std::string(), tls_channel_id);
640 // Tests that enabling and disabling an extension makes the runtime bindings
641 // appear and disappear.
643 // TODO(kalman): Test with multiple extensions that can be accessed by the same
644 // host.
645 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
646 EnablingAndDisabling) {
647 InitializeTestServer();
649 scoped_refptr<const Extension> chromium_connectable =
650 LoadChromiumConnectableExtension();
651 scoped_refptr<const Extension> not_connectable =
652 LoadNotConnectableExtension();
654 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
655 EXPECT_EQ(OK,
656 CanConnectAndSendMessagesToMainFrame(chromium_connectable.get()));
657 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
658 CanConnectAndSendMessagesToMainFrame(not_connectable.get()));
660 DisableExtension(chromium_connectable->id());
661 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
662 CanConnectAndSendMessagesToMainFrame(chromium_connectable.get()));
664 EnableExtension(chromium_connectable->id());
665 EXPECT_EQ(OK,
666 CanConnectAndSendMessagesToMainFrame(chromium_connectable.get()));
667 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
668 CanConnectAndSendMessagesToMainFrame(not_connectable.get()));
671 // Tests connection from incognito tabs when the user denies the connection
672 // request. Spanning mode only. A separate test for apps and extensions.
674 // TODO(kalman): ensure that we exercise split vs spanning incognito logic
675 // somewhere. This is a test that should be shared with the content script logic
676 // so it's not really our specific concern for web connectable.
678 // TODO(kalman): test messages from incognito extensions too.
679 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
680 FromIncognitoDenyApp) {
681 InitializeTestServer();
683 scoped_refptr<const Extension> app = LoadChromiumConnectableApp();
684 ASSERT_TRUE(app->is_platform_app());
686 Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord(
687 profile()->GetOffTheRecordProfile(),
688 chromium_org_url());
689 content::RenderFrameHost* incognito_frame = incognito_browser->
690 tab_strip_model()->GetActiveWebContents()->GetMainFrame();
693 IncognitoConnectability::ScopedAlertTracker alert_tracker(
694 IncognitoConnectability::ScopedAlertTracker::ALWAYS_DENY);
696 // No connection because incognito-enabled hasn't been set for the app, and
697 // the user denied our interactive request.
698 EXPECT_EQ(
699 COULD_NOT_ESTABLISH_CONNECTION_ERROR,
700 CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
701 EXPECT_EQ(1, alert_tracker.GetAndResetAlertCount());
703 // Try again. User has already denied so alert not shown.
704 EXPECT_EQ(
705 COULD_NOT_ESTABLISH_CONNECTION_ERROR,
706 CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
707 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount());
710 // It's not possible to allow an app in incognito.
711 ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(app->id(), true);
712 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
713 CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
716 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
717 FromIncognitoDenyExtension) {
718 InitializeTestServer();
720 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension();
722 Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord(
723 profile()->GetOffTheRecordProfile(), chromium_org_url());
724 content::RenderFrameHost* incognito_frame =
725 incognito_browser->tab_strip_model()
726 ->GetActiveWebContents()
727 ->GetMainFrame();
730 IncognitoConnectability::ScopedAlertTracker alert_tracker(
731 IncognitoConnectability::ScopedAlertTracker::ALWAYS_DENY);
733 // The alert doesn't show for extensions.
734 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
735 CanConnectAndSendMessagesToFrame(
736 incognito_frame, extension.get(), NULL));
737 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount());
740 // Allowing the extension in incognito mode will bypass the deny.
741 ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(extension->id(), true);
742 EXPECT_EQ(
744 CanConnectAndSendMessagesToFrame(incognito_frame, extension.get(), NULL));
747 // Tests connection from incognito tabs when the extension doesn't have an event
748 // handler for the connection event.
749 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
750 FromIncognitoNoEventHandlerInApp) {
751 InitializeTestServer();
753 scoped_refptr<const Extension> app = LoadChromiumConnectableApp(false);
754 ASSERT_TRUE(app->is_platform_app());
756 Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord(
757 profile()->GetOffTheRecordProfile(), chromium_org_url());
758 content::RenderFrameHost* incognito_frame =
759 incognito_browser->tab_strip_model()
760 ->GetActiveWebContents()
761 ->GetMainFrame();
764 IncognitoConnectability::ScopedAlertTracker alert_tracker(
765 IncognitoConnectability::ScopedAlertTracker::ALWAYS_ALLOW);
767 // No connection because incognito-enabled hasn't been set for the app, and
768 // the app hasn't installed event handlers.
769 EXPECT_EQ(
770 COULD_NOT_ESTABLISH_CONNECTION_ERROR,
771 CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
772 // No dialog should have been shown.
773 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount());
777 // Tests connection from incognito tabs when the user accepts the connection
778 // request. Spanning mode only. Separate tests for apps and extensions.
780 // TODO(kalman): see comment above about split mode.
781 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
782 FromIncognitoAllowApp) {
783 InitializeTestServer();
785 scoped_refptr<const Extension> app = LoadChromiumConnectableApp();
786 ASSERT_TRUE(app->is_platform_app());
788 Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord(
789 profile()->GetOffTheRecordProfile(),
790 chromium_org_url());
791 content::RenderFrameHost* incognito_frame = incognito_browser->
792 tab_strip_model()->GetActiveWebContents()->GetMainFrame();
795 IncognitoConnectability::ScopedAlertTracker alert_tracker(
796 IncognitoConnectability::ScopedAlertTracker::ALWAYS_ALLOW);
798 // Connection allowed even with incognito disabled, because the user
799 // accepted the interactive request.
800 EXPECT_EQ(
801 OK, CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
802 EXPECT_EQ(1, alert_tracker.GetAndResetAlertCount());
804 // Try again. User has already allowed.
805 EXPECT_EQ(
806 OK, CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
807 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount());
810 // Apps can't be allowed in incognito mode, but it's moot because it's
811 // already allowed.
812 ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(app->id(), true);
813 EXPECT_EQ(OK,
814 CanConnectAndSendMessagesToFrame(incognito_frame, app.get(), NULL));
817 // Tests connection from incognito tabs when there are multiple tabs open to the
818 // same origin. The user should only need to accept the connection request once.
819 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
820 FromIncognitoPromptApp) {
821 InitializeTestServer();
823 scoped_refptr<const Extension> app = LoadChromiumConnectableApp();
824 ASSERT_TRUE(app->is_platform_app());
826 // Open an incognito browser with two tabs displaying "chromium.org".
827 Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord(
828 profile()->GetOffTheRecordProfile(), chromium_org_url());
829 content::RenderFrameHost* incognito_frame1 =
830 incognito_browser->tab_strip_model()
831 ->GetActiveWebContents()
832 ->GetMainFrame();
833 InfoBarService* infobar_service1 = InfoBarService::FromWebContents(
834 incognito_browser->tab_strip_model()->GetActiveWebContents());
836 CHECK(ui_test_utils::OpenURLOffTheRecord(profile()->GetOffTheRecordProfile(),
837 chromium_org_url()) ==
838 incognito_browser);
839 content::RenderFrameHost* incognito_frame2 =
840 incognito_browser->tab_strip_model()
841 ->GetActiveWebContents()
842 ->GetMainFrame();
843 InfoBarService* infobar_service2 = InfoBarService::FromWebContents(
844 incognito_browser->tab_strip_model()->GetActiveWebContents());
845 EXPECT_EQ(2, incognito_browser->tab_strip_model()->count());
846 EXPECT_NE(incognito_frame1, incognito_frame2);
848 // Trigger a infobars in both tabs by trying to send messages.
849 std::string script =
850 base::StringPrintf("assertions.trySendMessage('%s')", app->id().c_str());
851 CHECK(content::ExecuteScript(incognito_frame1, script));
852 CHECK(content::ExecuteScript(incognito_frame2, script));
853 EXPECT_EQ(1U, infobar_service1->infobar_count());
854 EXPECT_EQ(1U, infobar_service2->infobar_count());
856 // Navigating away will dismiss the infobar on the active tab only.
857 ui_test_utils::NavigateToURL(incognito_browser, google_com_url());
858 EXPECT_EQ(1U, infobar_service1->infobar_count());
859 EXPECT_EQ(0U, infobar_service2->infobar_count());
861 // Navigate back and accept the infobar this time. Both should be dismissed.
863 IncognitoConnectability::ScopedAlertTracker alert_tracker(
864 IncognitoConnectability::ScopedAlertTracker::ALWAYS_ALLOW);
866 ui_test_utils::NavigateToURL(incognito_browser, chromium_org_url());
867 incognito_frame2 = incognito_browser->tab_strip_model()
868 ->GetActiveWebContents()
869 ->GetMainFrame();
870 EXPECT_NE(incognito_frame1, incognito_frame2);
872 EXPECT_EQ(1U, infobar_service1->infobar_count());
873 EXPECT_EQ(OK, CanConnectAndSendMessagesToFrame(incognito_frame2, app.get(),
874 NULL));
875 EXPECT_EQ(1, alert_tracker.GetAndResetAlertCount());
876 EXPECT_EQ(0U, infobar_service1->infobar_count());
880 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
881 FromIncognitoAllowExtension) {
882 InitializeTestServer();
884 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension();
886 Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord(
887 profile()->GetOffTheRecordProfile(), chromium_org_url());
888 content::RenderFrameHost* incognito_frame =
889 incognito_browser->tab_strip_model()
890 ->GetActiveWebContents()
891 ->GetMainFrame();
894 IncognitoConnectability::ScopedAlertTracker alert_tracker(
895 IncognitoConnectability::ScopedAlertTracker::ALWAYS_ALLOW);
897 // No alert is shown.
898 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
899 CanConnectAndSendMessagesToFrame(
900 incognito_frame, extension.get(), NULL));
901 EXPECT_EQ(0, alert_tracker.GetAndResetAlertCount());
904 // Allowing the extension in incognito mode is what allows connections.
905 ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(extension->id(), true);
906 EXPECT_EQ(
908 CanConnectAndSendMessagesToFrame(incognito_frame, extension.get(), NULL));
911 // Tests a connection from an iframe within a tab which doesn't have
912 // permission. Iframe should work.
913 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
914 FromIframeWithPermission) {
915 InitializeTestServer();
917 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension();
919 ui_test_utils::NavigateToURL(browser(), google_com_url());
920 EXPECT_EQ(NAMESPACE_NOT_DEFINED,
921 CanConnectAndSendMessagesToMainFrame(extension.get()));
922 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
924 ASSERT_TRUE(AppendIframe(chromium_org_url()));
926 EXPECT_EQ(OK, CanConnectAndSendMessagesToIFrame(extension.get()));
927 EXPECT_FALSE(AreAnyNonWebApisDefinedForIFrame());
930 // Tests connection from an iframe without permission within a tab that does.
931 // Iframe shouldn't work.
932 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
933 FromIframeWithoutPermission) {
934 InitializeTestServer();
936 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension();
938 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
939 EXPECT_EQ(OK, CanConnectAndSendMessagesToMainFrame(extension.get()));
940 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
942 ASSERT_TRUE(AppendIframe(google_com_url()));
944 EXPECT_EQ(NAMESPACE_NOT_DEFINED,
945 CanConnectAndSendMessagesToIFrame(extension.get()));
946 EXPECT_FALSE(AreAnyNonWebApisDefinedForIFrame());
949 // Tests externally_connectable between a web page and an extension with a
950 // TLS channel ID created for the origin.
951 class ExternallyConnectableMessagingWithTlsChannelIdTest :
952 public ExternallyConnectableMessagingTest {
953 public:
954 ExternallyConnectableMessagingWithTlsChannelIdTest()
955 : tls_channel_id_created_(false, false) {
958 std::string CreateTlsChannelId() {
959 scoped_refptr<net::URLRequestContextGetter> request_context_getter(
960 profile()->GetRequestContext());
961 std::string channel_id_private_key;
962 std::string channel_id_cert;
963 net::ChannelIDService::RequestHandle request_handle;
964 content::BrowserThread::PostTask(
965 content::BrowserThread::IO,
966 FROM_HERE,
967 base::Bind(
968 &ExternallyConnectableMessagingWithTlsChannelIdTest::
969 CreateDomainBoundCertOnIOThread,
970 base::Unretained(this),
971 base::Unretained(&channel_id_private_key),
972 base::Unretained(&channel_id_cert),
973 base::Unretained(&request_handle),
974 request_context_getter));
975 tls_channel_id_created_.Wait();
976 // Create the expected value.
977 base::StringPiece spki;
978 net::asn1::ExtractSPKIFromDERCert(channel_id_cert, &spki);
979 base::DictionaryValue jwk_value;
980 net::JwkSerializer::ConvertSpkiFromDerToJwk(spki, &jwk_value);
981 std::string tls_channel_id_value;
982 base::JSONWriter::Write(&jwk_value, &tls_channel_id_value);
983 return tls_channel_id_value;
986 private:
987 void CreateDomainBoundCertOnIOThread(
988 std::string* channel_id_private_key,
989 std::string* channel_id_cert,
990 net::ChannelIDService::RequestHandle* request_handle,
991 scoped_refptr<net::URLRequestContextGetter> request_context_getter) {
992 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
993 net::ChannelIDService* channel_id_service =
994 request_context_getter->GetURLRequestContext()->
995 channel_id_service();
996 int status = channel_id_service->GetOrCreateChannelID(
997 chromium_org_url().host(),
998 channel_id_private_key,
999 channel_id_cert,
1000 base::Bind(&ExternallyConnectableMessagingWithTlsChannelIdTest::
1001 GotDomainBoundCert,
1002 base::Unretained(this)),
1003 request_handle);
1004 if (status == net::ERR_IO_PENDING)
1005 return;
1006 GotDomainBoundCert(status);
1009 void GotDomainBoundCert(int status) {
1010 ASSERT_TRUE(status == net::OK);
1011 tls_channel_id_created_.Signal();
1014 base::WaitableEvent tls_channel_id_created_;
1017 // Tests a web connectable extension that receives TLS channel id on a site
1018 // that can connect to it, with a TLS channel ID having been generated.
1019 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingWithTlsChannelIdTest,
1020 WebConnectableWithNonEmptyTlsChannelId) {
1021 InitializeTestServer();
1022 std::string expected_tls_channel_id_value = CreateTlsChannelId();
1024 scoped_refptr<const Extension> chromium_connectable =
1025 LoadChromiumConnectableExtensionWithTlsChannelId();
1026 ASSERT_TRUE(chromium_connectable.get());
1028 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
1030 // Since the extension requests the TLS channel ID, it gets it for a site that
1031 // can connect to it, but only if the page also asks to send it.
1032 EXPECT_EQ(std::string(),
1033 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), false));
1034 EXPECT_EQ(std::string(),
1035 GetTlsChannelIdFromSendMessage(chromium_connectable.get(), false));
1037 // If the page does ask to send the TLS channel ID, it's sent and non-empty.
1038 std::string tls_channel_id_from_port_connect =
1039 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), true);
1040 EXPECT_NE(0u, tls_channel_id_from_port_connect.size());
1042 // The same value is received by both connect and sendMessage.
1043 std::string tls_channel_id_from_send_message =
1044 GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true);
1045 EXPECT_EQ(tls_channel_id_from_port_connect, tls_channel_id_from_send_message);
1047 // And since a TLS channel ID exists for the domain, the value received is
1048 // parseable as a JWK. (In particular, it has the same value we created by
1049 // converting the public key to JWK with net::ConvertSpkiFromDerToJwk.)
1050 std::string tls_channel_id(tls_channel_id_from_port_connect);
1051 EXPECT_EQ(expected_tls_channel_id_value, tls_channel_id);
1053 // The TLS channel ID shouldn't change from one connection to the next...
1054 std::string tls_channel_id2 =
1055 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), true);
1056 EXPECT_EQ(tls_channel_id, tls_channel_id2);
1057 tls_channel_id2 =
1058 GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true);
1059 EXPECT_EQ(tls_channel_id, tls_channel_id2);
1061 // nor should it change when navigating away, revisiting the page and
1062 // requesting it again.
1063 ui_test_utils::NavigateToURL(browser(), google_com_url());
1064 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
1065 tls_channel_id2 =
1066 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), true);
1067 EXPECT_EQ(tls_channel_id, tls_channel_id2);
1068 tls_channel_id2 =
1069 GetTlsChannelIdFromSendMessage(chromium_connectable.get(), true);
1070 EXPECT_EQ(tls_channel_id, tls_channel_id2);
1073 // Tests a web connectable extension that receives TLS channel id, but
1074 // immediately closes its background page upon receipt of a message.
1075 // Same flakiness seen in http://crbug.com/297866
1076 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingWithTlsChannelIdTest,
1077 DISABLED_WebConnectableWithNonEmptyTlsChannelIdAndClosedBackgroundPage) {
1078 InitializeTestServer();
1079 std::string expected_tls_channel_id_value = CreateTlsChannelId();
1081 scoped_refptr<const Extension> chromium_connectable =
1082 LoadChromiumConnectableExtensionWithTlsChannelId();
1084 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
1085 // If the page does ask for it, it isn't empty, even if the background page
1086 // closes upon receipt of the connect.
1087 std::string tls_channel_id = GetTlsChannelIdFromPortConnect(
1088 chromium_connectable.get(), true, close_background_message());
1089 EXPECT_EQ(expected_tls_channel_id_value, tls_channel_id);
1090 // A subsequent connect will still succeed, even if the background page was
1091 // previously closed.
1092 tls_channel_id =
1093 GetTlsChannelIdFromPortConnect(chromium_connectable.get(), true);
1094 // And the expected value is still retrieved.
1095 EXPECT_EQ(expected_tls_channel_id_value, tls_channel_id);
1098 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MessagingUserGesture) {
1099 const char kManifest[] = "{"
1100 " \"name\": \"user_gesture\","
1101 " \"version\": \"1.0\","
1102 " \"background\": {"
1103 " \"scripts\": [\"background.js\"]"
1104 " },"
1105 " \"manifest_version\": 2"
1106 "}";
1108 TestExtensionDir receiver_dir;
1109 receiver_dir.WriteManifest(kManifest);
1110 receiver_dir.WriteFile(FILE_PATH_LITERAL("background.js"),
1111 "chrome.runtime.onMessageExternal.addListener(\n"
1112 " function(msg, sender, reply) {\n"
1113 " reply({result:chrome.test.isProcessingUserGesture()});\n"
1114 " });");
1115 const Extension* receiver = LoadExtension(receiver_dir.unpacked_path());
1116 ASSERT_TRUE(receiver);
1118 TestExtensionDir sender_dir;
1119 sender_dir.WriteManifest(kManifest);
1120 sender_dir.WriteFile(FILE_PATH_LITERAL("background.js"), "");
1121 const Extension* sender = LoadExtension(sender_dir.unpacked_path());
1122 ASSERT_TRUE(sender);
1124 EXPECT_EQ("false",
1125 ExecuteScriptInBackgroundPage(sender->id(),
1126 base::StringPrintf(
1127 "chrome.test.runWithoutUserGesture(function() {\n"
1128 " chrome.runtime.sendMessage('%s', {}, function(response) {\n"
1129 " window.domAutomationController.send('' + response.result);\n"
1130 " });\n"
1131 "});", receiver->id().c_str())));
1133 EXPECT_EQ("true",
1134 ExecuteScriptInBackgroundPage(sender->id(),
1135 base::StringPrintf(
1136 "chrome.test.runWithUserGesture(function() {\n"
1137 " chrome.runtime.sendMessage('%s', {}, function(response) {\n"
1138 " window.domAutomationController.send('' + response.result);\n"
1139 " });\n"
1140 "});", receiver->id().c_str())));
1143 // Tests that a hosted app on a connectable site doesn't interfere with the
1144 // connectability of that site.
1145 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, HostedAppOnWebsite) {
1146 InitializeTestServer();
1148 scoped_refptr<const Extension> app = LoadChromiumHostedApp();
1150 // The presence of the hosted app shouldn't give the ability to send messages.
1151 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
1152 EXPECT_EQ(NAMESPACE_NOT_DEFINED,
1153 CanConnectAndSendMessagesToMainFrame(app.get()));
1154 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
1156 // Once a connectable extension is installed, it should.
1157 scoped_refptr<const Extension> extension = LoadChromiumConnectableExtension();
1158 EXPECT_EQ(OK, CanConnectAndSendMessagesToMainFrame(extension.get()));
1159 EXPECT_FALSE(AreAnyNonWebApisDefinedForMainFrame());
1162 // Tests that an invalid extension ID specified in a hosted app does not crash
1163 // the hosted app's renderer.
1165 // This is a regression test for http://crbug.com/326250#c12.
1166 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
1167 InvalidExtensionIDFromHostedApp) {
1168 InitializeTestServer();
1170 // The presence of the chromium hosted app triggers this bug. The chromium
1171 // connectable extension needs to be installed to set up the runtime bindings.
1172 LoadChromiumHostedApp();
1173 LoadChromiumConnectableExtension();
1175 scoped_refptr<const Extension> invalid =
1176 ExtensionBuilder()
1177 // A bit scary that this works...
1178 .SetID("invalid")
1179 .SetManifest(DictionaryBuilder()
1180 .Set("name", "Fake extension")
1181 .Set("version", "1")
1182 .Set("manifest_version", 2))
1183 .Build();
1185 ui_test_utils::NavigateToURL(browser(), chromium_org_url());
1186 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
1187 CanConnectAndSendMessagesToMainFrame(invalid.get()));
1190 #endif // !defined(OS_WIN) - http://crbug.com/350517.
1192 } // namespace
1194 }; // namespace extensions