Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / content / browser / message_port_provider_browsertest.cc
blob425e08fa954d0bff48739dbf57f4edf3e8fc816f
1 // Copyright 2015 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/bind.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "base/synchronization/waitable_event.h"
8 #include "content/browser/message_port_service.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "content/public/browser/message_port_delegate.h"
11 #include "content/public/browser/message_port_provider.h"
12 #include "content/public/browser/web_contents.h"
13 #include "content/public/test/browser_test_utils.h"
14 #include "content/public/test/content_browser_test.h"
15 #include "content/public/test/content_browser_test_utils.h"
16 #include "content/shell/browser/shell.h"
18 namespace content {
20 // This test verifies the functionality of the Message Port Provider API.
22 // A mock class for testing message port provider.
23 class MockMessagePortDelegate : public MessagePortDelegate {
24 public:
25 // A container to hold received messages
26 struct Message {
27 int route_id; // the routing id of the target port
28 MessagePortMessage data; // the message data
29 std::vector<TransferredMessagePort> sent_ports; // any transferred ports
32 typedef std::vector<Message> Messages;
34 MockMessagePortDelegate() { }
35 ~MockMessagePortDelegate() override { }
37 // MessagePortDelegate implementation
38 void SendMessage(
39 int route_id,
40 const MessagePortMessage& message,
41 const std::vector<TransferredMessagePort>& sent_message_ports) override {
42 Message m;
43 m.route_id = route_id;
44 m.data = message;
45 m.sent_ports = sent_message_ports;
46 messages_.push_back(m);
49 void SendMessagesAreQueued(int route_id) override { }
51 const Messages& getReceivedMessages() {
52 return messages_;
54 private:
55 Messages messages_;
57 DISALLOW_COPY_AND_ASSIGN(MockMessagePortDelegate);
61 class MessagePortProviderBrowserTest : public ContentBrowserTest {
64 // Verify that messages can be posted to main frame.
65 IN_PROC_BROWSER_TEST_F(MessagePortProviderBrowserTest, PostMessage) {
66 const std::string data =
67 "<!DOCTYPE html><html><body>"
68 " <script type=\"text/javascript\">"
69 " onmessage = function (e) { document.title = e.data; }"
70 " </script>"
71 "</body></html>";
72 const base::string16 target_origin(base::UTF8ToUTF16("http://baseurl"));
73 const GURL base_url(target_origin);
74 const GURL history_url;
75 // Load data. Blocks until it is done.
76 content::LoadDataWithBaseURL(shell(), history_url, data, base_url);
77 const base::string16 source_origin(base::UTF8ToUTF16("source"));
78 const base::string16 message(base::UTF8ToUTF16("success"));
79 const std::vector<TransferredMessagePort> ports;
80 content::TitleWatcher title_watcher(shell()->web_contents(), message);
81 MessagePortProvider::PostMessageToFrame(shell()->web_contents(),
82 source_origin,
83 target_origin,
84 message,
85 ports);
86 EXPECT_EQ(message, title_watcher.WaitAndGetTitle());
89 namespace {
91 void VerifyCreateChannelOnIOThread(base::WaitableEvent* event) {
93 const base::char16 MESSAGE1[] = { 0x1000, 0 };
94 const base::char16 MESSAGE2[] = { 0x1001, 0 };
96 MockMessagePortDelegate delegate;
97 int port1;
98 int port2;
100 MessagePortProvider::CreateMessageChannel(&delegate, &port1, &port2);
101 MessagePortService* service = MessagePortService::GetInstance();
102 // Send a message to port1 transferring no ports.
103 std::vector<TransferredMessagePort> sent_ports;
104 service->PostMessage(port1, MessagePortMessage(base::string16(MESSAGE1)),
105 sent_ports);
106 // Verify that message is received
107 const MockMessagePortDelegate::Messages& received =
108 delegate.getReceivedMessages();
109 EXPECT_EQ(received.size(), 1u);
110 // Verify that message sent to port1 is received by entangled port, which is
111 // port2.
112 EXPECT_EQ(received[0].route_id, port2);
113 EXPECT_EQ(received[0].data.message_as_string, MESSAGE1);
114 EXPECT_EQ(received[0].sent_ports.size(), 0u);
116 // Create a new channel, and transfer one of its ports to port2, making sure
117 // the transferred port is received.
118 TransferredMessagePort port3;
119 TransferredMessagePort port4;
120 MessagePortProvider::CreateMessageChannel(&delegate, &port3.id, &port4.id);
121 sent_ports.push_back(port3);
122 service->PostMessage(port1, MessagePortMessage(base::string16(MESSAGE2)),
123 sent_ports);
124 EXPECT_EQ(received.size(), 2u);
125 EXPECT_EQ(received[1].route_id, port2);
126 EXPECT_EQ(received[1].data.message_as_string, MESSAGE2);
127 EXPECT_EQ(received[1].sent_ports.size(), 1u);
128 EXPECT_EQ(received[1].sent_ports[0].id, port3.id);
130 event->Signal();
133 } // namespace
135 // Verify that a message channel can be created and used for exchanging
136 // messages.
137 IN_PROC_BROWSER_TEST_F(MessagePortProviderBrowserTest, CreateChannel) {
138 base::WaitableEvent event(true, false);
139 BrowserThread::PostTask(
140 BrowserThread::IO, FROM_HERE,
141 base::Bind(&VerifyCreateChannelOnIOThread, &event));
142 event.Wait();
145 } // namespace content