OLD | NEW |
| (Empty) |
1 // Copyright (c) 2009 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 "base/values.h" | |
6 #include "chrome/browser/extensions/extension_message_service.h" | |
7 #include "chrome/common/render_messages.h" | |
8 #include "chrome/renderer/extensions/event_bindings.h" | |
9 #include "chrome/renderer/extensions/renderer_extension_bindings.h" | |
10 #include "chrome/test/render_view_test.h" | |
11 #include "testing/gtest/include/gtest/gtest.h" | |
12 | |
13 static void DispatchOnConnect(int source_port_id, const std::string& name, | |
14 const std::string& tab_json) { | |
15 ListValue args; | |
16 args.Set(0, Value::CreateIntegerValue(source_port_id)); | |
17 args.Set(1, Value::CreateStringValue(name)); | |
18 args.Set(2, Value::CreateStringValue(tab_json)); | |
19 args.Set(3, Value::CreateStringValue("")); // extension ID is empty for tests | |
20 args.Set(4, Value::CreateStringValue("")); // extension ID is empty for tests | |
21 RendererExtensionBindings::Invoke( | |
22 ExtensionMessageService::kDispatchOnConnect, args, NULL, false, GURL()); | |
23 } | |
24 | |
25 static void DispatchOnDisconnect(int source_port_id) { | |
26 ListValue args; | |
27 args.Set(0, Value::CreateIntegerValue(source_port_id)); | |
28 RendererExtensionBindings::Invoke( | |
29 ExtensionMessageService::kDispatchOnDisconnect, args, NULL, false, | |
30 GURL()); | |
31 } | |
32 | |
33 static void DispatchOnMessage(const std::string& message, int source_port_id) { | |
34 ListValue args; | |
35 args.Set(0, Value::CreateStringValue(message)); | |
36 args.Set(1, Value::CreateIntegerValue(source_port_id)); | |
37 RendererExtensionBindings::Invoke( | |
38 ExtensionMessageService::kDispatchOnMessage, args, NULL, false, GURL()); | |
39 } | |
40 | |
41 // Tests that the bindings for opening a channel to an extension and sending | |
42 // and receiving messages through that channel all works. | |
43 TEST_F(RenderViewTest, ExtensionMessagesOpenChannel) { | |
44 render_thread_.sink().ClearMessages(); | |
45 LoadHTML("<body></body>"); | |
46 ExecuteJavaScript( | |
47 "var port = chrome.extension.connect({name:'testName'});" | |
48 "port.onMessage.addListener(doOnMessage);" | |
49 "port.postMessage({message: 'content ready'});" | |
50 "function doOnMessage(msg, port) {" | |
51 " alert('content got: ' + msg.val);" | |
52 "}"); | |
53 | |
54 // Verify that we opened a channel and sent a message through it. | |
55 const IPC::Message* open_channel_msg = | |
56 render_thread_.sink().GetUniqueMessageMatching( | |
57 ViewHostMsg_OpenChannelToExtension::ID); | |
58 ASSERT_TRUE(open_channel_msg); | |
59 void* iter = IPC::SyncMessage::GetDataIterator(open_channel_msg); | |
60 ViewHostMsg_OpenChannelToExtension::SendParam open_params; | |
61 ASSERT_TRUE(IPC::ReadParam(open_channel_msg, &iter, &open_params)); | |
62 EXPECT_EQ("testName", open_params.d); | |
63 | |
64 const IPC::Message* post_msg = | |
65 render_thread_.sink().GetUniqueMessageMatching( | |
66 ViewHostMsg_ExtensionPostMessage::ID); | |
67 ASSERT_TRUE(post_msg); | |
68 ViewHostMsg_ExtensionPostMessage::Param post_params; | |
69 ViewHostMsg_ExtensionPostMessage::Read(post_msg, &post_params); | |
70 EXPECT_EQ("{\"message\":\"content ready\"}", post_params.b); | |
71 | |
72 // Now simulate getting a message back from the other side. | |
73 render_thread_.sink().ClearMessages(); | |
74 const int kPortId = 0; | |
75 DispatchOnMessage("{\"val\": 42}", kPortId); | |
76 | |
77 // Verify that we got it. | |
78 const IPC::Message* alert_msg = | |
79 render_thread_.sink().GetUniqueMessageMatching( | |
80 ViewHostMsg_RunJavaScriptMessage::ID); | |
81 ASSERT_TRUE(alert_msg); | |
82 iter = IPC::SyncMessage::GetDataIterator(alert_msg); | |
83 ViewHostMsg_RunJavaScriptMessage::SendParam alert_param; | |
84 ASSERT_TRUE(IPC::ReadParam(alert_msg, &iter, &alert_param)); | |
85 EXPECT_EQ(L"content got: 42", alert_param.a); | |
86 } | |
87 | |
88 // Tests that the bindings for handling a new channel connection and channel | |
89 // closing all works. | |
90 TEST_F(RenderViewTest, ExtensionMessagesOnConnect) { | |
91 LoadHTML("<body></body>"); | |
92 ExecuteJavaScript( | |
93 "chrome.extension.onConnect.addListener(function (port) {" | |
94 " port.test = 24;" | |
95 " port.onMessage.addListener(doOnMessage);" | |
96 " port.onDisconnect.addListener(doOnDisconnect);" | |
97 " port.postMessage({message: 'onconnect from ' + port.tab.url + " | |
98 " ' name ' + port.name});" | |
99 "});" | |
100 "function doOnMessage(msg, port) {" | |
101 " alert('got: ' + msg.val);" | |
102 "}" | |
103 "function doOnDisconnect(port) {" | |
104 " alert('disconnected: ' + port.test);" | |
105 "}"); | |
106 | |
107 render_thread_.sink().ClearMessages(); | |
108 | |
109 // Simulate a new connection being opened. | |
110 const int kPortId = 0; | |
111 const std::string kPortName = "testName"; | |
112 DispatchOnConnect(kPortId, kPortName, "{\"url\":\"foo://bar\"}"); | |
113 | |
114 // Verify that we handled the new connection by posting a message. | |
115 const IPC::Message* post_msg = | |
116 render_thread_.sink().GetUniqueMessageMatching( | |
117 ViewHostMsg_ExtensionPostMessage::ID); | |
118 ASSERT_TRUE(post_msg); | |
119 ViewHostMsg_ExtensionPostMessage::Param post_params; | |
120 ViewHostMsg_ExtensionPostMessage::Read(post_msg, &post_params); | |
121 std::string expected_msg = | |
122 "{\"message\":\"onconnect from foo://bar name " + kPortName + "\"}"; | |
123 EXPECT_EQ(expected_msg, post_params.b); | |
124 | |
125 // Now simulate getting a message back from the channel opener. | |
126 render_thread_.sink().ClearMessages(); | |
127 DispatchOnMessage("{\"val\": 42}", kPortId); | |
128 | |
129 // Verify that we got it. | |
130 const IPC::Message* alert_msg = | |
131 render_thread_.sink().GetUniqueMessageMatching( | |
132 ViewHostMsg_RunJavaScriptMessage::ID); | |
133 ASSERT_TRUE(alert_msg); | |
134 void* iter = IPC::SyncMessage::GetDataIterator(alert_msg); | |
135 ViewHostMsg_RunJavaScriptMessage::SendParam alert_param; | |
136 ASSERT_TRUE(IPC::ReadParam(alert_msg, &iter, &alert_param)); | |
137 EXPECT_EQ(L"got: 42", alert_param.a); | |
138 | |
139 // Now simulate the channel closing. | |
140 render_thread_.sink().ClearMessages(); | |
141 DispatchOnDisconnect(kPortId); | |
142 | |
143 // Verify that we got it. | |
144 alert_msg = | |
145 render_thread_.sink().GetUniqueMessageMatching( | |
146 ViewHostMsg_RunJavaScriptMessage::ID); | |
147 ASSERT_TRUE(alert_msg); | |
148 iter = IPC::SyncMessage::GetDataIterator(alert_msg); | |
149 ASSERT_TRUE(IPC::ReadParam(alert_msg, &iter, &alert_param)); | |
150 EXPECT_EQ(L"disconnected: 24", alert_param.a); | |
151 } | |
OLD | NEW |