summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/extension_messages_unittest.cc
diff options
context:
space:
mode:
authormpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-27 19:18:41 +0000
committermpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-27 19:18:41 +0000
commitcc661e5f76c24a8640dbe818a1091e0fe60e1529 (patch)
tree09a8c5c6c76a4c5c990eb1a3fe862373d9536ebe /chrome/browser/extensions/extension_messages_unittest.cc
parent1a16364587d4fe3592b78d04ac13b5abfbd6360e (diff)
downloadchromium_src-cc661e5f76c24a8640dbe818a1091e0fe60e1529.zip
chromium_src-cc661e5f76c24a8640dbe818a1091e0fe60e1529.tar.gz
chromium_src-cc661e5f76c24a8640dbe818a1091e0fe60e1529.tar.bz2
Fix port disconnect so that it's refcounted. This fixes a bug where a channel
would close if any one listener on the channel called "disconnect()". BUG=16644 TEST=no Review URL: http://codereview.chromium.org/155476 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21678 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions/extension_messages_unittest.cc')
-rw-r--r--chrome/browser/extensions/extension_messages_unittest.cc69
1 files changed, 69 insertions, 0 deletions
diff --git a/chrome/browser/extensions/extension_messages_unittest.cc b/chrome/browser/extensions/extension_messages_unittest.cc
index 7da3f38..7bf402f 100644
--- a/chrome/browser/extensions/extension_messages_unittest.cc
+++ b/chrome/browser/extensions/extension_messages_unittest.cc
@@ -147,3 +147,72 @@ TEST_F(RenderViewTest, ExtensionMessagesOnConnect) {
ASSERT_TRUE(IPC::ReadParam(alert_msg, &iter, &alert_param));
EXPECT_EQ(L"disconnected: 24", alert_param.a);
}
+
+// Tests that we don't send the disconnect message until all ports have
+// disconnected.
+TEST_F(RenderViewTest, ExtensionMessagesDisconnect) {
+ LoadHTML("<body></body>");
+ ExecuteJavaScript(
+ "chrome.self.onConnect.addListener(function (port) {"
+ " port.onMessage.addListener(function(msg, p) {"
+ " if (msg.disconnect) port.disconnect();"
+ " });"
+ "});"
+ "var iframe1 = document.createElement('iframe');"
+ "var iframe2 = document.createElement('iframe');"
+ "var src = 'javascript:"
+ " chrome.self.onConnect.addListener(function(port) {"
+ " port.postMessage(\"onconnect\");"
+ " port.onMessage.addListener(function(p) { alert(\"NOTREACHED\"); });"
+ " port.disconnect();"
+ " });';"
+ "iframe1.src = src;"
+ "iframe2.src = src;"
+ "document.body.appendChild(iframe1);"
+ "document.body.appendChild(iframe2);");
+
+ render_thread_.sink().ClearMessages();
+
+ // Simulate a new connection being opened. The two child frames should
+ // disconnect immediately, but we shouldn't get a disconnect message until
+ // all 3 frames disconnect.
+ const int kPortId = 0;
+ const std::string kPortName = "testName";
+ DispatchOnConnect(kPortId, kPortName, "null");
+
+ // Verify that we handled the new connection by posting a message.
+ const IPC::Message* post_msg =
+ render_thread_.sink().GetFirstMessageMatching(
+ ViewHostMsg_ExtensionPostMessage::ID);
+ ASSERT_TRUE(post_msg);
+ ViewHostMsg_ExtensionPostMessage::Param post_params;
+ ViewHostMsg_ExtensionPostMessage::Read(post_msg, &post_params);
+ EXPECT_EQ("\"onconnect\"", post_params.b);
+
+ // Simulate sending a message.
+ render_thread_.sink().ClearMessages();
+ DispatchOnMessage("{\"val\": 42}", kPortId);
+
+ // If we get an alert box, then the iframes failed to disconnect properly.
+ const IPC::Message* alert_msg =
+ render_thread_.sink().GetFirstMessageMatching(
+ ViewHostMsg_RunJavaScriptMessage::ID);
+ ASSERT_FALSE(alert_msg);
+
+ // We should not get a disconnect message yet, since the toplevel frame didn't
+ // disconnect.
+ const IPC::Message* disconnect_msg =
+ render_thread_.sink().GetFirstMessageMatching(
+ ViewHostMsg_ExtensionCloseChannel::ID);
+ ASSERT_FALSE(disconnect_msg);
+
+ // Disconnect the port in the top frame.
+ render_thread_.sink().ClearMessages();
+ DispatchOnMessage("{\"disconnect\": true}", kPortId);
+
+ // Now we should have a disconnect message.
+ disconnect_msg =
+ render_thread_.sink().GetUniqueMessageMatching(
+ ViewHostMsg_ExtensionCloseChannel::ID);
+ ASSERT_TRUE(disconnect_msg);
+}